diff --git a/src/Squidex.Domain.Apps.Read/Contents/Edm/EdmModelBuilder.cs b/src/Squidex.Domain.Apps.Read/Contents/Edm/EdmModelBuilder.cs index f7d1da481..b45117b5c 100644 --- a/src/Squidex.Domain.Apps.Read/Contents/Edm/EdmModelBuilder.cs +++ b/src/Squidex.Domain.Apps.Read/Contents/Edm/EdmModelBuilder.cs @@ -18,14 +18,14 @@ using Squidex.Infrastructure; namespace Squidex.Domain.Apps.Read.Contents.Edm { - public sealed class EdmModelBuilder : CachingProviderBase + public class EdmModelBuilder : CachingProviderBase { public EdmModelBuilder(IMemoryCache cache) : base(cache) { } - public IEdmModel BuildEdmModel(ISchemaEntity schema, IAppEntity app) + public virtual IEdmModel BuildEdmModel(ISchemaEntity schema, IAppEntity app) { Guard.NotNull(schema, nameof(schema)); diff --git a/src/Squidex.Domain.Apps.Read/Contents/Edm/EdmModelExtensions.cs b/src/Squidex.Domain.Apps.Read/Contents/Edm/EdmModelExtensions.cs index 721265b9f..c3dfe029e 100644 --- a/src/Squidex.Domain.Apps.Read/Contents/Edm/EdmModelExtensions.cs +++ b/src/Squidex.Domain.Apps.Read/Contents/Edm/EdmModelExtensions.cs @@ -17,6 +17,11 @@ namespace Squidex.Domain.Apps.Read.Contents.Edm { public static ODataUriParser ParseQuery(this IEdmModel model, string query) { + if (!model.EntityContainer.EntitySets().Any()) + { + return null; + } + query = query ?? string.Empty; var path = model.EntityContainer.EntitySets().First().Path.Path.Split('.').Last(); diff --git a/tests/Squidex.Domain.Apps.Read.Tests/Contents/ContentQueryServiceTests.cs b/tests/Squidex.Domain.Apps.Read.Tests/Contents/ContentQueryServiceTests.cs new file mode 100644 index 000000000..4c261f297 --- /dev/null +++ b/tests/Squidex.Domain.Apps.Read.Tests/Contents/ContentQueryServiceTests.cs @@ -0,0 +1,129 @@ +// ========================================================================== +// ContentQueryServiceTests.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System; +using System.Security.Claims; +using System.Threading.Tasks; +using FakeItEasy; +using Squidex.Domain.Apps.Core.Contents; +using Squidex.Domain.Apps.Core.Scripting; +using Squidex.Domain.Apps.Read.Apps; +using Squidex.Domain.Apps.Read.Contents.Edm; +using Squidex.Domain.Apps.Read.Contents.Repositories; +using Squidex.Domain.Apps.Read.Schemas; +using Squidex.Domain.Apps.Read.Schemas.Services; +using Squidex.Infrastructure; +using Xunit; +using System.Collections.Generic; +using Microsoft.OData.UriParser; + +namespace Squidex.Domain.Apps.Read.Contents +{ + public class ContentQueryServiceTests + { + private readonly IContentRepository contentRepository = A.Fake(); + private readonly IScriptEngine scriptEngine = A.Fake(); + private readonly ISchemaProvider schemas = A.Fake(); + private readonly ISchemaEntity schema = A.Fake(); + private readonly IContentEntity content = A.Fake(); + private readonly IAppEntity app = A.Fake(); + private readonly Guid appId = Guid.NewGuid(); + private readonly Guid schemaId = Guid.NewGuid(); + private readonly Guid contentId = Guid.NewGuid(); + private readonly NamedContentData data = new NamedContentData(); + private readonly NamedContentData transformedData = new NamedContentData(); + private readonly ClaimsPrincipal user = new ClaimsPrincipal(); + private readonly EdmModelBuilder modelBuilder = A.Fake(); + private readonly ContentQueryService sut; + + public ContentQueryServiceTests() + { + A.CallTo(() => app.Id).Returns(appId); + + A.CallTo(() => content.Id).Returns(contentId); + A.CallTo(() => content.Data).Returns(data); + + sut = new ContentQueryService(contentRepository, schemas, scriptEngine, modelBuilder); + } + + [Fact] + public async Task Should_return_schema_from_id_if_string_is_guid() + { + A.CallTo(() => schemas.FindSchemaByIdAsync(schemaId, false)).Returns(schema); + + var result = await sut.FindSchemaAsync(app, schemaId.ToString()); + + Assert.Equal(schema, result); + } + + [Fact] + public async Task Should_return_schema_from_name_if_string_not_guid() + { + A.CallTo(() => schemas.FindSchemaByNameAsync(appId, "my-schema")).Returns(schema); + + var result = await sut.FindSchemaAsync(app, "my-schema"); + + Assert.Equal(schema, result); + } + + [Fact] + public async Task Should_throw_if_schema_not_found() + { + A.CallTo(() => schemas.FindSchemaByNameAsync(appId, "my-schema")).Returns(Task.FromResult(null)); + + await Assert.ThrowsAsync(() => sut.FindSchemaAsync(app, "my-schema")); + } + + [Fact] + public async Task Should_return_content_from_repository_and_transform() + { + A.CallTo(() => schemas.FindSchemaByIdAsync(schemaId, false)).Returns(Task.FromResult(schema)); + A.CallTo(() => contentRepository.FindContentAsync(app, schema, contentId)).Returns(content); + + A.CallTo(() => schema.ScriptQuery).Returns(""); + + A.CallTo(() => scriptEngine.Transform(A.That.Matches(x => x.User == user && x.ContentId == contentId && ReferenceEquals(x.Data, data)), "")).Returns(transformedData); + + var result = await sut.FindContentAsync(app, schemaId.ToString(), user, contentId); + + Assert.Equal(schema, result.Schema); + Assert.Equal(data, result.Content.Data); + Assert.Equal(content.Id, result.Content.Id); + } + + [Fact] + public async Task Should_throw_if_content_to_find_does_not_exist() + { + A.CallTo(() => schemas.FindSchemaByIdAsync(schemaId, false)).Returns(Task.FromResult(schema)); + A.CallTo(() => contentRepository.FindContentAsync(app, schema, contentId)).Returns(Task.FromResult(null)); + + await Assert.ThrowsAsync(async () => await sut.FindContentAsync(app, schemaId.ToString(), user, contentId)); + } + + [Fact] + public async Task Should_return_contents_from_repository_and_transform() + { + var ids = new HashSet(); + + A.CallTo(() => schemas.FindSchemaByIdAsync(schemaId, false)).Returns(Task.FromResult(schema)); + A.CallTo(() => contentRepository.QueryAsync(app, schema, false, ids, A.Ignored)).Returns(Task.FromResult>(new List { content })); + A.CallTo(() => contentRepository.CountAsync(app, schema, false, ids, A.Ignored)).Returns(123); + + A.CallTo(() => schema.ScriptQuery).Returns(""); + + A.CallTo(() => scriptEngine.Transform(A.That.Matches(x => x.User == user && x.ContentId == contentId && ReferenceEquals(x.Data, data)), "")).Returns(transformedData); + + var result = await sut.QueryWithCountAsync(app, schemaId.ToString(), user, ids, null); + + Assert.Equal(123, result.Total); + Assert.Equal(schema, result.Schema); + Assert.Equal(data, result.Items[0].Data); + Assert.Equal(content.Id, result.Items[0].Id); + } + } +} diff --git a/tests/Squidex.Domain.Apps.Read.Tests/Contents/GraphQLTests.cs b/tests/Squidex.Domain.Apps.Read.Tests/Contents/GraphQLTests.cs index 70b7622bb..e89599ea4 100644 --- a/tests/Squidex.Domain.Apps.Read.Tests/Contents/GraphQLTests.cs +++ b/tests/Squidex.Domain.Apps.Read.Tests/Contents/GraphQLTests.cs @@ -355,7 +355,7 @@ namespace Squidex.Domain.Apps.Read.Contents }} }}"; - A.CallTo(() => contentQuery.FindContentAsync(app, schema.ToString(), user, contentId)) + A.CallTo(() => contentQuery.FindContentAsync(app, schema.Id.ToString(), user, contentId)) .Returns(Task.FromResult((schema, content))); var result = await sut.QueryAsync(app, user, new GraphQLQuery { Query = query }); @@ -439,7 +439,7 @@ namespace Squidex.Domain.Apps.Read.Contents var refContents = new List { contentRef }; - A.CallTo(() => contentQuery.FindContentAsync(app, schema.ToString(), user, contentId)) + A.CallTo(() => contentQuery.FindContentAsync(app, schema.Id.ToString(), user, contentId)) .Returns(Task.FromResult((schema, content))); A.CallTo(() => contentQuery.QueryWithCountAsync(app, schema.Id.ToString(), user, A>.That.Matches(x => x.Contains(contentRefId)), null)) @@ -499,7 +499,7 @@ namespace Squidex.Domain.Apps.Read.Contents var refAssets = new List { assetRef }; - A.CallTo(() => contentQuery.FindContentAsync(app, schema.ToString(), user, contentId)) + A.CallTo(() => contentQuery.FindContentAsync(app, schema.Id.ToString(), user, contentId)) .Returns(Task.FromResult((schema, content))); A.CallTo(() => assetRepository.QueryAsync(app.Id, null, A>.That.Matches(x => x.Contains(assetRefId)), null, int.MaxValue, 0)) @@ -558,7 +558,7 @@ namespace Squidex.Domain.Apps.Read.Contents }} }}"; - A.CallTo(() => contentQuery.FindContentAsync(app, schema.ToString(), user, contentId)) + A.CallTo(() => contentQuery.FindContentAsync(app, schema.Id.ToString(), user, contentId)) .Returns(Task.FromResult((schema, content))); var result = await sut.QueryAsync(app, user, new GraphQLQuery { Query = query });