Browse Source

Correct usage of publish state for schemas.

pull/107/head
Sebastian Stehle 9 years ago
parent
commit
ac10257a83
  1. 4
      src/Squidex.Domain.Apps.Read.MongoDb/Contents/MongoContentEntity.cs
  2. 2
      src/Squidex.Domain.Apps.Read.MongoDb/Contents/MongoContentRepository.cs
  3. 4
      src/Squidex.Domain.Apps.Read.MongoDb/Schemas/MongoSchemaRepository.cs
  4. 31
      src/Squidex.Domain.Apps.Read/Contents/GraphQL/CachingGraphQLService.cs
  5. 3
      src/Squidex.Domain.Apps.Read/Contents/GraphQL/IGraphQLService.cs
  6. 65
      src/Squidex.Domain.Apps.Read/Contents/GraphQL/QueryContext.cs
  7. 2
      src/Squidex.Domain.Apps.Read/Contents/IContentEntity.cs
  8. 2
      src/Squidex.Domain.Apps.Read/Schemas/Repositories/ISchemaRepository.cs
  9. 2
      src/Squidex.Domain.Apps.Read/Schemas/Services/Implementations/CachingSchemaProvider.cs
  10. 39
      src/Squidex/Controllers/ContentApi/ContentsController.cs
  11. 88
      tests/Squidex.Domain.Apps.Read.Tests/Contents/GraphQLTests.cs
  12. 12
      tests/Squidex.Domain.Apps.Read.Tests/Schemas/CachingSchemaProviderTests.cs
  13. 6
      tests/Squidex.Domain.Apps.Write.Tests/Contents/ContentCommandHandlerTests.cs
  14. 12
      tests/Squidex.Domain.Apps.Write.Tests/Schemas/SchemaCommandHandlerTests.cs
  15. 28
      tests/Squidex.Domain.Apps.Write.Tests/Webhooks/WebhookCommandMiddlewareTests.cs

4
src/Squidex.Domain.Apps.Read.MongoDb/Contents/MongoContentEntity.cs

@ -94,6 +94,10 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Contents
{
return contentData;
}
set
{
contentData = value;
}
}
public void ParseData(Schema schema)

2
src/Squidex.Domain.Apps.Read.MongoDb/Contents/MongoContentRepository.cs

@ -189,7 +189,7 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Contents
{
var collection = GetCollection(appId);
var schemaEntity = await schemas.FindSchemaByIdAsync(schemaId, true);
var schemaEntity = await schemas.FindSchemaByIdAsync(schemaId);
if (schemaEntity == null)
{

4
src/Squidex.Domain.Apps.Read.MongoDb/Schemas/MongoSchemaRepository.cs

@ -69,7 +69,7 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Schemas
return schemaEntity;
}
public async Task<ISchemaEntity> FindSchemaAsync(Guid schemaId)
public async Task<ISchemaEntity> FindSchemaAsync(Guid schemaId, bool provideDeleted = false)
{
var schemaEntity =
await Collection.Find(s => s.Id == schemaId)
@ -77,7 +77,7 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Schemas
schemaEntity?.DeserializeSchema(serializer);
return schemaEntity;
return schemaEntity != null && (provideDeleted || !schemaEntity.IsDeleted) ? schemaEntity : null;
}
}
}

31
src/Squidex.Domain.Apps.Read/Contents/GraphQL/CachingGraphQLService.cs

@ -8,13 +8,16 @@
using System;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Memory;
using Squidex.Domain.Apps.Core.Scripting;
using Squidex.Domain.Apps.Events;
using Squidex.Domain.Apps.Read.Apps;
using Squidex.Domain.Apps.Read.Assets.Repositories;
using Squidex.Domain.Apps.Read.Contents.Repositories;
using Squidex.Domain.Apps.Read.Schemas.Repositories;
using Squidex.Domain.Apps.Read.Schemas.Services;
using Squidex.Domain.Apps.Read.Utils;
using Squidex.Infrastructure;
using Squidex.Infrastructure.CQRS.Events;
@ -30,6 +33,8 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL
private readonly IGraphQLUrlGenerator urlGenerator;
private readonly IAssetRepository assetRepository;
private readonly ISchemaRepository schemaRepository;
private readonly ISchemaProvider schemas;
private readonly IScriptEngine scriptEngine;
public string Name
{
@ -41,18 +46,28 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL
get { return "^(schema-)|(apps-)"; }
}
public CachingGraphQLService(IMemoryCache cache, ISchemaRepository schemaRepository, IAssetRepository assetRepository, IContentRepository contentRepository, IGraphQLUrlGenerator urlGenerator)
public CachingGraphQLService(IMemoryCache cache,
IAssetRepository assetRepository,
IContentRepository contentRepository,
IGraphQLUrlGenerator urlGenerator,
ISchemaRepository schemaRepository,
ISchemaProvider schemas,
IScriptEngine scriptEngine)
: base(cache)
{
Guard.NotNull(contentRepository, nameof(contentRepository));
Guard.NotNull(schemaRepository, nameof(schemaRepository));
Guard.NotNull(assetRepository, nameof(assetRepository));
Guard.NotNull(contentRepository, nameof(contentRepository));
Guard.NotNull(urlGenerator, nameof(urlGenerator));
Guard.NotNull(scriptEngine, nameof(scriptEngine));
Guard.NotNull(schemas, nameof(schemas));
this.contentRepository = contentRepository;
this.schemaRepository = schemaRepository;
this.assetRepository = assetRepository;
this.contentRepository = contentRepository;
this.urlGenerator = urlGenerator;
this.schemaRepository = schemaRepository;
this.schemas = schemas;
this.scriptEngine = scriptEngine;
}
public Task ClearAsync()
@ -70,13 +85,13 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL
return TaskHelper.Done;
}
public async Task<(object Data, object[] Errors)> QueryAsync(IAppEntity app, GraphQLQuery query)
public async Task<(object Data, object[] Errors)> QueryAsync(IAppEntity app, ClaimsPrincipal user, GraphQLQuery query)
{
Guard.NotNull(app, nameof(app));
Guard.NotNull(query, nameof(query));
var modelContext = await GetModelAsync(app);
var queryContext = new QueryContext(app, contentRepository, assetRepository, urlGenerator);
var queryContext = new QueryContext(app, assetRepository, contentRepository, urlGenerator, schemas, scriptEngine, user);
return await modelContext.ExecuteAsync(queryContext, query);
}
@ -89,9 +104,9 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL
if (modelContext == null)
{
var schemas = await schemaRepository.QueryAllAsync(app.Id);
var allSchemas = await schemaRepository.QueryAllAsync(app.Id);
modelContext = new GraphQLModel(app, schemas.Where(x => x.IsPublished), urlGenerator);
modelContext = new GraphQLModel(app, allSchemas.Where(x => x.IsPublished), urlGenerator);
Cache.Set(cacheKey, modelContext);
}

3
src/Squidex.Domain.Apps.Read/Contents/GraphQL/IGraphQLService.cs

@ -6,6 +6,7 @@
// All rights reserved.
// ==========================================================================
using System.Security.Claims;
using System.Threading.Tasks;
using Squidex.Domain.Apps.Read.Apps;
@ -13,6 +14,6 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL
{
public interface IGraphQLService
{
Task<(object Data, object[] Errors)> QueryAsync(IAppEntity app, GraphQLQuery query);
Task<(object Data, object[] Errors)> QueryAsync(IAppEntity app, ClaimsPrincipal user, GraphQLQuery query);
}
}

65
src/Squidex.Domain.Apps.Read/Contents/GraphQL/QueryContext.cs

@ -13,10 +13,13 @@ using Squidex.Domain.Apps.Read.Contents.Repositories;
using Squidex.Infrastructure;
using System.Collections.Concurrent;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Squidex.Domain.Apps.Core.Scripting;
using Squidex.Domain.Apps.Read.Apps;
using Squidex.Domain.Apps.Read.Assets;
using Squidex.Domain.Apps.Read.Assets.Repositories;
using Squidex.Domain.Apps.Read.Schemas.Services;
// ReSharper disable InvertIf
@ -29,24 +32,41 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL
private readonly IContentRepository contentRepository;
private readonly IAssetRepository assetRepository;
private readonly IGraphQLUrlGenerator urlGenerator;
private readonly IScriptEngine scriptEngine;
private readonly ISchemaProvider schemas;
private readonly IAppEntity app;
private readonly ClaimsPrincipal user;
public IGraphQLUrlGenerator UrlGenerator
{
get { return urlGenerator; }
}
public QueryContext(IAppEntity app, IContentRepository contentRepository, IAssetRepository assetRepository, IGraphQLUrlGenerator urlGenerator)
public QueryContext(
IAppEntity app,
IAssetRepository assetRepository,
IContentRepository contentRepository,
IGraphQLUrlGenerator urlGenerator,
ISchemaProvider schemas,
IScriptEngine scriptEngine,
ClaimsPrincipal user)
{
Guard.NotNull(contentRepository, nameof(contentRepository));
Guard.NotNull(assetRepository, nameof(assetRepository));
Guard.NotNull(schemas, nameof(schemas));
Guard.NotNull(scriptEngine, nameof(scriptEngine));
Guard.NotNull(urlGenerator, nameof(urlGenerator));
Guard.NotNull(user, nameof(user));
Guard.NotNull(app, nameof(app));
this.contentRepository = contentRepository;
this.assetRepository = assetRepository;
this.schemas = schemas;
this.scriptEngine = scriptEngine;
this.urlGenerator = urlGenerator;
this.user = user;
this.app = app;
}
@ -73,11 +93,18 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL
if (content == null)
{
content = await contentRepository.FindContentAsync(app, schemaId, id).ConfigureAwait(false);
var schema = await schemas.FindSchemaByIdAsync(schemaId).ConfigureAwait(false);
if (content != null)
if (schema != null)
{
cachedContents[content.Id] = content;
content = await contentRepository.FindContentAsync(app, schemaId, id).ConfigureAwait(false);
if (content != null)
{
content.Data = scriptEngine.Transform(new ScriptContext { Data = content.Data, ContentId = content.Id, User = user }, schema.ScriptQuery);
cachedContents[content.Id] = content;
}
}
}
@ -98,14 +125,23 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL
public async Task<IReadOnlyList<IContentEntity>> QueryContentsAsync(Guid schemaId, string query)
{
var contents = await contentRepository.QueryAsync(app, schemaId, false, null, query).ConfigureAwait(false);
var result = new List<IContentEntity>();
var schema = await schemas.FindSchemaByIdAsync(schemaId).ConfigureAwait(false);
foreach (var content in contents)
if (schema != null)
{
cachedContents[content.Id] = content;
result.AddRange(await contentRepository.QueryAsync(app, schemaId, false, null, query).ConfigureAwait(false));
foreach (var content in result)
{
content.Data = scriptEngine.Transform(new ScriptContext { Data = content.Data, ContentId = content.Id, User = user }, schema.ScriptQuery);
cachedContents[content.Id] = content;
}
}
return contents;
return result;
}
public Task<IReadOnlyList<IAssetEntity>> GetReferencedAssetsAsync(JToken value)
@ -149,11 +185,18 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL
if (notLoadedContents.Count > 0)
{
var contents = await contentRepository.QueryAsync(app, schemaId, false, notLoadedContents, null).ConfigureAwait(false);
var schema = await schemas.FindSchemaByIdAsync(schemaId).ConfigureAwait(false);
foreach (var content in contents)
if (schema != null)
{
cachedContents[content.Id] = content;
var contents = await contentRepository.QueryAsync(app, schemaId, false, notLoadedContents, null).ConfigureAwait(false);
foreach (var content in contents)
{
content.Data = scriptEngine.Transform(new ScriptContext { Data = content.Data, ContentId = content.Id, User = user }, schema.ScriptQuery);
cachedContents[content.Id] = content;
}
}
}

2
src/Squidex.Domain.Apps.Read/Contents/IContentEntity.cs

@ -14,6 +14,6 @@ namespace Squidex.Domain.Apps.Read.Contents
{
bool IsPublished { get; }
NamedContentData Data { get; }
NamedContentData Data { get; set; }
}
}

2
src/Squidex.Domain.Apps.Read/Schemas/Repositories/ISchemaRepository.cs

@ -18,6 +18,6 @@ namespace Squidex.Domain.Apps.Read.Schemas.Repositories
Task<ISchemaEntity> FindSchemaAsync(Guid appId, string name);
Task<ISchemaEntity> FindSchemaAsync(Guid schemaId);
Task<ISchemaEntity> FindSchemaAsync(Guid schemaId, bool provideDeleted = false);
}
}

2
src/Squidex.Domain.Apps.Read/Schemas/Services/Implementations/CachingSchemaProvider.cs

@ -52,7 +52,7 @@ namespace Squidex.Domain.Apps.Read.Schemas.Services.Implementations
if (!Cache.TryGetValue(cacheKey, out ISchemaEntity result))
{
result = await repository.FindSchemaAsync(id);
result = await repository.FindSchemaAsync(id, provideDeleted);
Cache.Set(cacheKey, result, CacheDuration);

39
src/Squidex/Controllers/ContentApi/ContentsController.cs

@ -22,6 +22,7 @@ using Squidex.Domain.Apps.Read.Schemas;
using Squidex.Domain.Apps.Read.Schemas.Services;
using Squidex.Domain.Apps.Write.Contents;
using Squidex.Domain.Apps.Write.Contents.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.CQRS.Commands;
using Squidex.Infrastructure.Reflection;
using Squidex.Pipeline;
@ -51,8 +52,8 @@ namespace Squidex.Controllers.ContentApi
: base(commandBus)
{
this.graphQL = graphQL;
this.scriptEngine = scriptEngine;
this.schemas = schemas;
this.scriptEngine = scriptEngine;
this.contentRepository = contentRepository;
}
@ -63,7 +64,7 @@ namespace Squidex.Controllers.ContentApi
[ApiCosts(2)]
public async Task<IActionResult> PostGraphQL([FromBody] GraphQLQuery query)
{
var result = await graphQL.QueryAsync(App, query);
var result = await graphQL.QueryAsync(App, User, query);
if (result.Errors?.Length > 0)
{
@ -143,11 +144,6 @@ namespace Squidex.Controllers.ContentApi
{
var schemaEntity = await FindSchemaAsync(name);
if (schemaEntity == null)
{
return NotFound();
}
var entity = await contentRepository.FindContentAsync(App, schemaEntity.Id, id);
if (entity == null)
@ -187,8 +183,10 @@ namespace Squidex.Controllers.ContentApi
[HttpPost]
[Route("content/{app}/{name}/")]
[ApiCosts(1)]
public async Task<IActionResult> PostContent([FromBody] NamedContentData request, [FromQuery] bool publish = false)
public async Task<IActionResult> PostContent(string name, [FromBody] NamedContentData request, [FromQuery] bool publish = false)
{
await FindSchemaAsync(name);
var command = new CreateContent { ContentId = Guid.NewGuid(), User = User, Data = request.ToCleaned(), Publish = publish };
var context = await CommandBus.PublishAsync(command);
@ -203,8 +201,10 @@ namespace Squidex.Controllers.ContentApi
[HttpPut]
[Route("content/{app}/{name}/{id}")]
[ApiCosts(1)]
public async Task<IActionResult> PutContent(Guid id, [FromBody] NamedContentData request)
public async Task<IActionResult> PutContent(string name, Guid id, [FromBody] NamedContentData request)
{
await FindSchemaAsync(name);
var command = new UpdateContent { ContentId = id, User = User, Data = request.ToCleaned() };
var context = await CommandBus.PublishAsync(command);
@ -219,8 +219,10 @@ namespace Squidex.Controllers.ContentApi
[HttpPatch]
[Route("content/{app}/{name}/{id}")]
[ApiCosts(1)]
public async Task<IActionResult> PatchContent(Guid id, [FromBody] NamedContentData request)
public async Task<IActionResult> PatchContent(string name, Guid id, [FromBody] NamedContentData request)
{
await FindSchemaAsync(name);
var command = new PatchContent { ContentId = id, User = User, Data = request.ToCleaned() };
var context = await CommandBus.PublishAsync(command);
@ -235,8 +237,10 @@ namespace Squidex.Controllers.ContentApi
[HttpPut]
[Route("content/{app}/{name}/{id}/publish")]
[ApiCosts(1)]
public async Task<IActionResult> PublishContent(Guid id)
public async Task<IActionResult> PublishContent(string name, Guid id)
{
await FindSchemaAsync(name);
var command = new PublishContent { ContentId = id, User = User };
await CommandBus.PublishAsync(command);
@ -248,8 +252,10 @@ namespace Squidex.Controllers.ContentApi
[HttpPut]
[Route("content/{app}/{name}/{id}/unpublish")]
[ApiCosts(1)]
public async Task<IActionResult> UnpublishContent(Guid id)
public async Task<IActionResult> UnpublishContent(string name, Guid id)
{
await FindSchemaAsync(name);
var command = new UnpublishContent { ContentId = id, User = User };
await CommandBus.PublishAsync(command);
@ -261,8 +267,10 @@ namespace Squidex.Controllers.ContentApi
[HttpDelete]
[Route("content/{app}/{name}/{id}")]
[ApiCosts(1)]
public async Task<IActionResult> PutContent(Guid id)
public async Task<IActionResult> DeleteContent(string name, Guid id)
{
await FindSchemaAsync(name);
var command = new DeleteContent { ContentId = id, User = User };
await CommandBus.PublishAsync(command);
@ -283,6 +291,11 @@ namespace Squidex.Controllers.ContentApi
schemaEntity = await schemas.FindSchemaByNameAsync(AppId, name);
}
if (schemaEntity == null || !schemaEntity.IsPublished)
{
throw new DomainObjectNotFoundException(name, typeof(ISchemaEntity));
}
return schemaEntity;
}
}

88
tests/Squidex.Domain.Apps.Read.Tests/Contents/GraphQLTests.cs

@ -8,6 +8,7 @@
using System;
using System.Collections.Generic;
using System.Security.Claims;
using System.Threading.Tasks;
using FakeItEasy;
using Microsoft.Extensions.Caching.Memory;
@ -26,7 +27,9 @@ using Squidex.Domain.Apps.Read.Schemas.Repositories;
using Xunit;
using NodaTime.Extensions;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Scripting;
using Squidex.Domain.Apps.Read.Assets;
using Squidex.Domain.Apps.Read.Schemas.Services;
using Squidex.Infrastructure;
// ReSharper disable SimilarAnonymousTypeNearby
@ -60,11 +63,14 @@ namespace Squidex.Domain.Apps.Read.Contents
new GeolocationFieldProperties()));
private readonly ISchemaRepository schemaRepository = A.Fake<ISchemaRepository>();
private readonly ISchemaProvider schemas = A.Fake<ISchemaProvider>();
private readonly ISchemaEntity schemaEntity = A.Fake<ISchemaEntity>();
private readonly IScriptEngine scriptEngine = A.Fake<IScriptEngine>();
private readonly IContentRepository contentRepository = A.Fake<IContentRepository>();
private readonly IAssetRepository assetRepository = A.Fake<IAssetRepository>();
private readonly IAppEntity appEntity = A.Dummy<IAppEntity>();
private readonly IMemoryCache cache = new MemoryCache(Options.Create(new MemoryCacheOptions()));
private readonly ClaimsPrincipal user = new ClaimsPrincipal();
private readonly IGraphQLService sut;
public GraphQLTests()
@ -76,12 +82,19 @@ namespace Squidex.Domain.Apps.Read.Contents
A.CallTo(() => schemaEntity.Name).Returns(schema.Name);
A.CallTo(() => schemaEntity.Schema).Returns(schema);
A.CallTo(() => schemaEntity.IsPublished).Returns(true);
A.CallTo(() => schemaEntity.ScriptQuery).Returns("<script-query>");
var schemas = new List<ISchemaEntity> { schemaEntity };
A.CallTo(() => scriptEngine.Transform(A<ScriptContext>.That.Matches(x => x.User == user), "<script-query>"))
.ReturnsLazily((ScriptContext c, string s) => c.Data);
A.CallTo(() => schemaRepository.QueryAllAsync(appId)).Returns(Task.FromResult<IReadOnlyList<ISchemaEntity>>(schemas));
A.CallTo(() => schemas.FindSchemaByIdAsync(A<Guid>.Ignored, false))
.Returns(Task.FromResult(schemaEntity));
sut = new CachingGraphQLService(cache, schemaRepository, assetRepository, contentRepository, new FakeUrlGenerator());
var allSchemas = new List<ISchemaEntity> { schemaEntity };
A.CallTo(() => schemaRepository.QueryAllAsync(appId)).Returns(Task.FromResult<IReadOnlyList<ISchemaEntity>>(allSchemas));
sut = new CachingGraphQLService(cache, assetRepository, contentRepository, new FakeUrlGenerator(), schemaRepository, schemas, scriptEngine);
}
[Fact]
@ -116,7 +129,7 @@ namespace Squidex.Domain.Apps.Read.Contents
A.CallTo(() => assetRepository.QueryAsync(appEntity.Id, null, null, "my-query", 30, 5))
.Returns(Task.FromResult<IReadOnlyList<IAssetEntity>>(assets));
var result = await sut.QueryAsync(appEntity, new GraphQLQuery { Query = query });
var result = await sut.QueryAsync(appEntity, user, new GraphQLQuery { Query = query });
var expected = new
{
@ -181,7 +194,7 @@ namespace Squidex.Domain.Apps.Read.Contents
A.CallTo(() => assetRepository.FindAssetAsync(assetId))
.Returns(Task.FromResult(assetEntity));
var result = await sut.QueryAsync(appEntity, new GraphQLQuery { Query = query });
var result = await sut.QueryAsync(appEntity, user, new GraphQLQuery { Query = query });
var expected = new
{
@ -255,7 +268,7 @@ namespace Squidex.Domain.Apps.Read.Contents
A.CallTo(() => contentRepository.QueryAsync(appEntity, schemaId, false, null, "?$top=30&$skip=5"))
.Returns(Task.FromResult<IReadOnlyList<IContentEntity>>(contents));
var result = await sut.QueryAsync(appEntity, new GraphQLQuery { Query = query });
var result = await sut.QueryAsync(appEntity, user, new GraphQLQuery { Query = query });
var expected = new
{
@ -356,7 +369,7 @@ namespace Squidex.Domain.Apps.Read.Contents
A.CallTo(() => contentRepository.FindContentAsync(appEntity, schemaId, contentId))
.Returns(Task.FromResult(contentEntity));
var result = await sut.QueryAsync(appEntity, new GraphQLQuery { Query = query });
var result = await sut.QueryAsync(appEntity, user, new GraphQLQuery { Query = query });
var expected = new
{
@ -443,7 +456,7 @@ namespace Squidex.Domain.Apps.Read.Contents
A.CallTo(() => contentRepository.QueryAsync(appEntity, schemaId, false, A<HashSet<Guid>>.That.Matches(x => x.Contains(contentRefId)), null))
.Returns(Task.FromResult<IReadOnlyList<IContentEntity>>(refContents));
var result = await sut.QueryAsync(appEntity, new GraphQLQuery { Query = query });
var result = await sut.QueryAsync(appEntity, user, new GraphQLQuery { Query = query });
var expected = new
{
@ -503,7 +516,7 @@ namespace Squidex.Domain.Apps.Read.Contents
A.CallTo(() => assetRepository.QueryAsync(appEntity.Id, null, A<HashSet<Guid>>.That.Matches(x => x.Contains(assetRefId)), null, int.MaxValue, 0))
.Returns(Task.FromResult<IReadOnlyList<IAssetEntity>>(refAssets));
var result = await sut.QueryAsync(appEntity, new GraphQLQuery { Query = query });
var result = await sut.QueryAsync(appEntity, user, new GraphQLQuery { Query = query });
var expected = new
{
@ -532,11 +545,64 @@ namespace Squidex.Domain.Apps.Read.Contents
AssertJson(expected, new { data = result.Data });
}
private static IContentEntity CreateContent(Guid id, Guid refId, Guid assetId)
[Fact]
public async Task Should_not_return_value_when_field_not_part_of_content()
{
var contentId = Guid.NewGuid();
var contentEntity = CreateContent(contentId, Guid.Empty, Guid.Empty, new NamedContentData());
var query = $@"
query {{
findMySchemaContent(id: ""{contentId}"") {{
id
version
created
createdBy
lastModified
lastModifiedBy
url
data {{
myString {{
iv
}}
}}
}}
}}";
A.CallTo(() => contentRepository.FindContentAsync(appEntity, schemaId, contentId))
.Returns(Task.FromResult(contentEntity));
var result = await sut.QueryAsync(appEntity, user, new GraphQLQuery { Query = query });
var expected = new
{
data = new
{
findMySchemaContent = new
{
id = contentEntity.Id,
version = 1,
created = contentEntity.Created.ToDateTimeUtc(),
createdBy = "subject:user1",
lastModified = contentEntity.LastModified.ToDateTimeUtc(),
lastModifiedBy = "subject:user2",
url = $"contents/my-schema/{contentEntity.Id}",
data = new
{
myString = (object)null
}
}
}
};
AssertJson(expected, new { data = result.Data });
}
private static IContentEntity CreateContent(Guid id, Guid refId, Guid assetId, NamedContentData data = null)
{
var now = DateTime.UtcNow.ToInstant();
var data =
data = data ??
new NamedContentData()
.AddField("my-json",
new ContentFieldData().AddValue("iv", JToken.FromObject(new { value = 1 })))

12
tests/Squidex.Domain.Apps.Read.Tests/Schemas/CachingSchemaProviderTests.cs

@ -67,13 +67,13 @@ namespace Squidex.Domain.Apps.Read.Schemas
[Fact]
public async Task Should_also_retrieve_schema_by_name_if_retrieved_by_id_before()
{
A.CallTo(() => repository.FindSchemaAsync(schemaId.Id))
A.CallTo(() => repository.FindSchemaAsync(schemaId.Id, false))
.Returns(Task.FromResult(schemaV1));
await ProvideSchemaById(schemaV1);
await ProvideSchemaByName(schemaV1);
A.CallTo(() => repository.FindSchemaAsync(schemaId.Id)).MustHaveHappened();
A.CallTo(() => repository.FindSchemaAsync(schemaId.Id, false)).MustHaveHappened();
A.CallTo(() => repository.FindSchemaAsync(appId.Id, schemaId.Name)).MustNotHaveHappened();
}
@ -86,16 +86,16 @@ namespace Squidex.Domain.Apps.Read.Schemas
await ProvideSchemaByName(schemaV1);
await ProvideSchemaById(schemaV1);
A.CallTo(() => repository.FindSchemaAsync(schemaId.Id)).MustNotHaveHappened();
A.CallTo(() => repository.FindSchemaAsync(schemaId.Id, false)).MustNotHaveHappened();
A.CallTo(() => repository.FindSchemaAsync(appId.Id, schemaId.Name)).MustHaveHappened();
}
[Fact]
public async Task Should_clear_cache_for_id_after_update_event()
{
A.CallTo(() => repository.FindSchemaAsync(schemaId.Id))
A.CallTo(() => repository.FindSchemaAsync(schemaId.Id, false))
.Returns(schemaV2);
A.CallTo(() => repository.FindSchemaAsync(schemaId.Id))
A.CallTo(() => repository.FindSchemaAsync(schemaId.Id, false))
.Returns(schemaV1).Once();
await ProvideSchemaById(schemaV1);
@ -104,7 +104,7 @@ namespace Squidex.Domain.Apps.Read.Schemas
await ProvideSchemaById(schemaV2);
A.CallTo(() => repository.FindSchemaAsync(schemaId.Id)).MustHaveHappened(Repeated.Exactly.Times(2));
A.CallTo(() => repository.FindSchemaAsync(schemaId.Id, false)).MustHaveHappened(Repeated.Exactly.Times(2));
}
[Fact]

6
tests/Squidex.Domain.Apps.Write.Tests/Contents/ContentCommandHandlerTests.cs

@ -34,7 +34,7 @@ namespace Squidex.Domain.Apps.Write.Contents
{
private readonly ContentCommandMiddleware sut;
private readonly ContentDomainObject content;
private readonly ISchemaProvider schemaProvider = A.Fake<ISchemaProvider>();
private readonly ISchemaProvider schemas = A.Fake<ISchemaProvider>();
private readonly ISchemaEntity schemaEntity = A.Fake<ISchemaEntity>();
private readonly IScriptEngine scriptEngine = A.Fake<IScriptEngine>();
private readonly IAppProvider appProvider = A.Fake<IAppProvider>();
@ -54,14 +54,14 @@ namespace Squidex.Domain.Apps.Write.Contents
content = new ContentDomainObject(contentId, -1);
sut = new ContentCommandMiddleware(Handler, appProvider, A.Dummy<IAssetRepository>(), schemaProvider, scriptEngine, A.Dummy<IContentRepository>());
sut = new ContentCommandMiddleware(Handler, appProvider, A.Dummy<IAssetRepository>(), schemas, scriptEngine, A.Dummy<IContentRepository>());
A.CallTo(() => appEntity.LanguagesConfig).Returns(languagesConfig);
A.CallTo(() => appEntity.PartitionResolver).Returns(languagesConfig.ToResolver());
A.CallTo(() => appProvider.FindAppByIdAsync(AppId)).Returns(Task.FromResult(appEntity));
A.CallTo(() => schemaEntity.Schema).Returns(schema);
A.CallTo(() => schemaProvider.FindSchemaByIdAsync(SchemaId, false)).Returns(Task.FromResult(schemaEntity));
A.CallTo(() => schemas.FindSchemaByIdAsync(SchemaId, false)).Returns(Task.FromResult(schemaEntity));
}
[Fact]

12
tests/Squidex.Domain.Apps.Write.Tests/Schemas/SchemaCommandHandlerTests.cs

@ -25,7 +25,7 @@ namespace Squidex.Domain.Apps.Write.Schemas
{
public class SchemaCommandMiddlewareTests : HandlerTestBase<SchemaDomainObject>
{
private readonly ISchemaProvider schemaProvider = A.Fake<ISchemaProvider>();
private readonly ISchemaProvider schemas = A.Fake<ISchemaProvider>();
private readonly SchemaCommandMiddleware sut;
private readonly SchemaDomainObject schema;
private readonly FieldRegistry registry = new FieldRegistry(new TypeNameRegistry());
@ -35,7 +35,7 @@ namespace Squidex.Domain.Apps.Write.Schemas
{
schema = new SchemaDomainObject(SchemaId, -1, registry);
sut = new SchemaCommandMiddleware(Handler, schemaProvider);
sut = new SchemaCommandMiddleware(Handler, schemas);
}
[Fact]
@ -43,7 +43,7 @@ namespace Squidex.Domain.Apps.Write.Schemas
{
var context = CreateContextForCommand(new CreateSchema { Name = SchemaName, SchemaId = SchemaId });
A.CallTo(() => schemaProvider.FindSchemaByNameAsync(AppId, SchemaName))
A.CallTo(() => schemas.FindSchemaByNameAsync(AppId, SchemaName))
.Returns(Task.FromResult(A.Dummy<ISchemaEntity>()));
await TestCreate(schema, async _ =>
@ -51,7 +51,7 @@ namespace Squidex.Domain.Apps.Write.Schemas
await Assert.ThrowsAsync<ValidationException>(async () => await sut.HandleAsync(context));
}, false);
A.CallTo(() => schemaProvider.FindSchemaByNameAsync(AppId, SchemaName)).MustHaveHappened();
A.CallTo(() => schemas.FindSchemaByNameAsync(AppId, SchemaName)).MustHaveHappened();
}
[Fact]
@ -59,7 +59,7 @@ namespace Squidex.Domain.Apps.Write.Schemas
{
var context = CreateContextForCommand(new CreateSchema { Name = SchemaName, SchemaId = SchemaId });
A.CallTo(() => schemaProvider.FindSchemaByNameAsync(AppId, SchemaName))
A.CallTo(() => schemas.FindSchemaByNameAsync(AppId, SchemaName))
.Returns(Task.FromResult<ISchemaEntity>(null));
await TestCreate(schema, async _ =>
@ -69,7 +69,7 @@ namespace Squidex.Domain.Apps.Write.Schemas
Assert.Equal(SchemaId, context.Result<EntityCreatedResult<Guid>>().IdOrValue);
A.CallTo(() => schemaProvider.FindSchemaByNameAsync(AppId, SchemaName)).MustHaveHappened();
A.CallTo(() => schemas.FindSchemaByNameAsync(AppId, SchemaName)).MustHaveHappened();
}
[Fact]

28
tests/Squidex.Domain.Apps.Write.Tests/Webhooks/WebhookCommandMiddlewareTests.cs

@ -26,47 +26,47 @@ namespace Squidex.Domain.Apps.Write.Webhooks
{
public class WebhookCommandMiddlewareTests : HandlerTestBase<WebhookDomainObject>
{
private readonly ISchemaProvider schemaProvider = A.Fake<ISchemaProvider>();
private readonly ISchemaProvider schemas = A.Fake<ISchemaProvider>();
private readonly WebhookCommandMiddleware sut;
private readonly WebhookDomainObject webhook;
private readonly Uri url = new Uri("http://squidex.io");
private readonly Guid schemaId = Guid.NewGuid();
private readonly Guid webhookId = Guid.NewGuid();
private readonly List<WebhookSchema> schemas;
private readonly List<WebhookSchema> webhookSchemas;
public WebhookCommandMiddlewareTests()
{
webhook = new WebhookDomainObject(webhookId, -1);
schemas = new List<WebhookSchema>
webhookSchemas = new List<WebhookSchema>
{
new WebhookSchema { SchemaId = schemaId }
};
sut = new WebhookCommandMiddleware(Handler, schemaProvider);
sut = new WebhookCommandMiddleware(Handler, schemas);
}
[Fact]
public async Task Create_should_create_webhook()
{
var context = CreateContextForCommand(new CreateWebhook { Schemas = schemas, Url = url, WebhookId = webhookId });
var context = CreateContextForCommand(new CreateWebhook { Schemas = webhookSchemas, Url = url, WebhookId = webhookId });
A.CallTo(() => schemaProvider.FindSchemaByIdAsync(schemaId, false)).Returns(Task.FromResult(A.Fake<ISchemaEntity>()));
A.CallTo(() => schemas.FindSchemaByIdAsync(schemaId, false)).Returns(Task.FromResult(A.Fake<ISchemaEntity>()));
await TestCreate(webhook, async _ =>
{
await sut.HandleAsync(context);
});
A.CallTo(() => schemaProvider.FindSchemaByIdAsync(schemaId, false)).MustHaveHappened();
A.CallTo(() => schemas.FindSchemaByIdAsync(schemaId, false)).MustHaveHappened();
}
[Fact]
public async Task Create_should_throw_exception_when_schema_is_not_found()
{
var context = CreateContextForCommand(new CreateWebhook { Schemas = schemas, Url = url, WebhookId = webhookId });
var context = CreateContextForCommand(new CreateWebhook { Schemas = webhookSchemas, Url = url, WebhookId = webhookId });
A.CallTo(() => schemaProvider.FindSchemaByIdAsync(schemaId, false)).Returns(Task.FromResult<ISchemaEntity>(null));
A.CallTo(() => schemas.FindSchemaByIdAsync(schemaId, false)).Returns(Task.FromResult<ISchemaEntity>(null));
await Assert.ThrowsAsync<ValidationException>(async () =>
{
@ -80,9 +80,9 @@ namespace Squidex.Domain.Apps.Write.Webhooks
[Fact]
public async Task Update_should_update_domain_object()
{
var context = CreateContextForCommand(new UpdateWebhook { Schemas = schemas, Url = url, WebhookId = webhookId });
var context = CreateContextForCommand(new UpdateWebhook { Schemas = webhookSchemas, Url = url, WebhookId = webhookId });
A.CallTo(() => schemaProvider.FindSchemaByIdAsync(schemaId, false)).Returns(Task.FromResult(A.Fake<ISchemaEntity>()));
A.CallTo(() => schemas.FindSchemaByIdAsync(schemaId, false)).Returns(Task.FromResult(A.Fake<ISchemaEntity>()));
CreateWebhook();
@ -91,15 +91,15 @@ namespace Squidex.Domain.Apps.Write.Webhooks
await sut.HandleAsync(context);
});
A.CallTo(() => schemaProvider.FindSchemaByIdAsync(schemaId, false)).MustHaveHappened();
A.CallTo(() => schemas.FindSchemaByIdAsync(schemaId, false)).MustHaveHappened();
}
[Fact]
public async Task Update_should_throw_exception_when_schema_is_not_found()
{
var context = CreateContextForCommand(new UpdateWebhook { Schemas = schemas, Url = url, WebhookId = webhookId });
var context = CreateContextForCommand(new UpdateWebhook { Schemas = webhookSchemas, Url = url, WebhookId = webhookId });
A.CallTo(() => schemaProvider.FindSchemaByIdAsync(schemaId, false)).Returns(Task.FromResult<ISchemaEntity>(null));
A.CallTo(() => schemas.FindSchemaByIdAsync(schemaId, false)).Returns(Task.FromResult<ISchemaEntity>(null));
CreateWebhook();

Loading…
Cancel
Save