Browse Source

Code cleanup.

pull/107/head
Sebastian Stehle 9 years ago
parent
commit
c50d6768e1
  1. 28
      src/Squidex.Domain.Apps.Read.MongoDb/Contents/MongoContentRepository.cs
  2. 8
      src/Squidex.Domain.Apps.Read.MongoDb/Contents/MongoContentRepository_EventHandling.cs
  3. 2
      src/Squidex.Domain.Apps.Read.MongoDb/Schemas/MongoSchemaEntity.cs
  4. 4
      src/Squidex.Domain.Apps.Read.MongoDb/Utils/EntityMapper.cs
  5. 54
      src/Squidex.Domain.Apps.Read/Contents/ContentQueryService.cs
  6. 8
      src/Squidex.Domain.Apps.Read/Contents/Edm/EdmModelBuilder.cs
  7. 22
      src/Squidex.Domain.Apps.Read/Contents/GraphQL/GraphQLModel.cs
  8. 2
      src/Squidex.Domain.Apps.Read/Contents/GraphQL/IGraphQLContext.cs
  9. 6
      src/Squidex.Domain.Apps.Read/Contents/GraphQL/IGraphQLUrlGenerator.cs
  10. 23
      src/Squidex.Domain.Apps.Read/Contents/GraphQL/QueryContext.cs
  11. 14
      src/Squidex.Domain.Apps.Read/Contents/GraphQL/Types/ContentGraphType.cs
  12. 24
      src/Squidex.Domain.Apps.Read/Contents/GraphQL/Types/ContentQueryGraphType.cs
  13. 6
      src/Squidex.Domain.Apps.Read/Contents/IContentQueryService.cs
  14. 6
      src/Squidex.Domain.Apps.Read/Contents/Repositories/IContentRepository.cs
  15. 2
      src/Squidex.Domain.Apps.Read/Schemas/ISchemaEntity.cs
  16. 6
      src/Squidex.Domain.Apps.Write/Contents/ContentCommandMiddleware.cs
  17. 10
      src/Squidex/Controllers/Api/Schemas/Models/Converters/SchemaConverter.cs
  18. 15
      src/Squidex/Controllers/ContentApi/ContentsController.cs
  19. 2
      src/Squidex/Controllers/ContentApi/Generator/SchemasSwaggerGenerator.cs
  20. 12
      src/Squidex/Pipeline/GraphQLUrlGenerator.cs
  21. 161
      tests/Squidex.Domain.Apps.Read.Tests/Contents/GraphQLTests.cs
  22. 24
      tests/Squidex.Domain.Apps.Read.Tests/Contents/ODataQueryTests.cs
  23. 12
      tests/Squidex.Domain.Apps.Read.Tests/Contents/TestData/FakeUrlGenerator.cs
  24. 28
      tests/Squidex.Domain.Apps.Write.Tests/Contents/ContentCommandHandlerTests.cs

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

@ -71,19 +71,19 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Contents
this.database = database; this.database = database;
} }
public async Task<IReadOnlyList<IContentEntity>> QueryAsync(IAppEntity appEntity, ISchemaEntity schemaEntity, bool nonPublished, HashSet<Guid> ids, ODataUriParser odataQuery) public async Task<IReadOnlyList<IContentEntity>> QueryAsync(IAppEntity app, ISchemaEntity schema, bool nonPublished, HashSet<Guid> ids, ODataUriParser odataQuery)
{ {
var collection = GetCollection(appEntity.Id); var collection = GetCollection(app.Id);
IFindFluent<MongoContentEntity, MongoContentEntity> cursor; IFindFluent<MongoContentEntity, MongoContentEntity> cursor;
try try
{ {
cursor = cursor =
collection collection
.Find(odataQuery, ids, schemaEntity.Id, schemaEntity.Schema, nonPublished) .Find(odataQuery, ids, schema.Id, schema.SchemaDef, nonPublished)
.Take(odataQuery) .Take(odataQuery)
.Skip(odataQuery) .Skip(odataQuery)
.Sort(odataQuery, schemaEntity.Schema); .Sort(odataQuery, schema.SchemaDef);
} }
catch (NotSupportedException) catch (NotSupportedException)
{ {
@ -98,20 +98,20 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Contents
foreach (var entity in entities) foreach (var entity in entities)
{ {
entity.ParseData(schemaEntity.Schema); entity.ParseData(schema.SchemaDef);
} }
return entities; return entities;
} }
public Task<long> CountAsync(IAppEntity appEntity, ISchemaEntity schemaEntity, bool nonPublished, HashSet<Guid> ids, ODataUriParser odataQuery) public Task<long> CountAsync(IAppEntity app, ISchemaEntity schema, bool nonPublished, HashSet<Guid> ids, ODataUriParser odataQuery)
{ {
var collection = GetCollection(appEntity.Id); var collection = GetCollection(app.Id);
IFindFluent<MongoContentEntity, MongoContentEntity> cursor; IFindFluent<MongoContentEntity, MongoContentEntity> cursor;
try try
{ {
cursor = collection.Find(odataQuery, ids, schemaEntity.Id, schemaEntity.Schema, nonPublished); cursor = collection.Find(odataQuery, ids, schema.Id, schema.SchemaDef, nonPublished);
} }
catch (NotSupportedException) catch (NotSupportedException)
{ {
@ -136,15 +136,15 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Contents
return contentIds.Except(contentEntities.Select(x => Guid.Parse(x["_id"].AsString))).ToList(); return contentIds.Except(contentEntities.Select(x => Guid.Parse(x["_id"].AsString))).ToList();
} }
public async Task<IContentEntity> FindContentAsync(IAppEntity appEntity, ISchemaEntity schemaEntity, Guid id) public async Task<IContentEntity> FindContentAsync(IAppEntity app, ISchemaEntity schema, Guid id)
{ {
var collection = GetCollection(appEntity.Id); var collection = GetCollection(app.Id);
var contentEntity = var contentEntity =
await collection.Find(x => x.Id == id) await collection.Find(x => x.Id == id)
.FirstOrDefaultAsync(); .FirstOrDefaultAsync();
contentEntity?.ParseData(schemaEntity.Schema); contentEntity?.ParseData(schema.SchemaDef);
return contentEntity; return contentEntity;
} }
@ -153,14 +153,14 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Contents
{ {
var collection = GetCollection(appId); var collection = GetCollection(appId);
var schemaEntity = await schemas.FindSchemaByIdAsync(schemaId); var schema = await schemas.FindSchemaByIdAsync(schemaId);
if (schemaEntity == null) if (schema == null)
{ {
return; return;
} }
await action(collection, schemaEntity); await action(collection, schema);
} }
} }
} }

8
src/Squidex.Domain.Apps.Read.MongoDb/Contents/MongoContentRepository_EventHandling.cs

@ -71,7 +71,7 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Contents
protected Task On(ContentCreated @event, EnvelopeHeaders headers) protected Task On(ContentCreated @event, EnvelopeHeaders headers)
{ {
return ForSchemaAsync(@event.AppId.Id, @event.SchemaId.Id, (collection, schemaEntity) => return ForSchemaAsync(@event.AppId.Id, @event.SchemaId.Id, (collection, schema) =>
{ {
return collection.CreateAsync(@event, headers, x => return collection.CreateAsync(@event, headers, x =>
{ {
@ -79,18 +79,18 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Contents
SimpleMapper.Map(@event, x); SimpleMapper.Map(@event, x);
x.SetData(schemaEntity.Schema, @event.Data); x.SetData(schema.SchemaDef, @event.Data);
}); });
}); });
} }
protected Task On(ContentUpdated @event, EnvelopeHeaders headers) protected Task On(ContentUpdated @event, EnvelopeHeaders headers)
{ {
return ForSchemaAsync(@event.AppId.Id, @event.SchemaId.Id, (collection, schemaEntity) => return ForSchemaAsync(@event.AppId.Id, @event.SchemaId.Id, (collection, schema) =>
{ {
return collection.UpdateAsync(@event, headers, x => return collection.UpdateAsync(@event, headers, x =>
{ {
x.SetData(schemaEntity.Schema, @event.Data); x.SetData(schema.SchemaDef, @event.Data);
}); });
}); });
} }

2
src/Squidex.Domain.Apps.Read.MongoDb/Schemas/MongoSchemaEntity.cs

@ -75,7 +75,7 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Schemas
[BsonElement] [BsonElement]
public string ScriptPublish { get; set; } public string ScriptPublish { get; set; }
Schema ISchemaEntity.Schema Schema ISchemaEntity.SchemaDef
{ {
get { return schema.Value; } get { return schema.Value; }
} }

4
src/Squidex.Domain.Apps.Read.MongoDb/Utils/EntityMapper.cs

@ -82,9 +82,9 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Utils
private static void SetAppId(SquidexEvent @event, IMongoEntity entity) private static void SetAppId(SquidexEvent @event, IMongoEntity entity)
{ {
if (entity is IAppRefEntity appEntity && @event is AppEvent appEvent) if (entity is IAppRefEntity app && @event is AppEvent appEvent)
{ {
appEntity.AppId = appEvent.AppId.Id; app.AppId = appEvent.AppId.Id;
} }
} }
} }

54
src/Squidex.Domain.Apps.Read/Contents/ContentQueryService.cs

@ -54,71 +54,71 @@ namespace Squidex.Domain.Apps.Read.Contents
this.modelBuilder = modelBuilder; this.modelBuilder = modelBuilder;
} }
public async Task<(ISchemaEntity SchemaEntity, IContentEntity ContentEntity)> FindContentAsync(IAppEntity appEntity, string schemaIdOrName, ClaimsPrincipal user, Guid id) public async Task<(ISchemaEntity Schema, IContentEntity Content)> FindContentAsync(IAppEntity app, string schemaIdOrName, ClaimsPrincipal user, Guid id)
{ {
Guard.NotNull(appEntity, nameof(appEntity)); Guard.NotNull(app, nameof(app));
Guard.NotNull(user, nameof(user)); Guard.NotNull(user, nameof(user));
Guard.NotNullOrEmpty(schemaIdOrName, nameof(schemaIdOrName)); Guard.NotNullOrEmpty(schemaIdOrName, nameof(schemaIdOrName));
var schemaEntity = await FindSchemaAsync(appEntity, schemaIdOrName); var schema = await FindSchemaAsync(app, schemaIdOrName);
var contentEntity = await contentRepository.FindContentAsync(appEntity, schemaEntity, id); var content = await contentRepository.FindContentAsync(app, schema, id);
if (contentEntity == null) if (content == null)
{ {
throw new DomainObjectNotFoundException(id.ToString(), typeof(ISchemaEntity)); throw new DomainObjectNotFoundException(id.ToString(), typeof(ISchemaEntity));
} }
contentEntity = TransformContent(user, schemaEntity, new List<IContentEntity> { contentEntity })[0]; content = TransformContent(user, schema, new List<IContentEntity> { content })[0];
return (schemaEntity, contentEntity); return (schema, content);
} }
public async Task<(ISchemaEntity SchemaEntity, long Total, IReadOnlyList<IContentEntity> Items)> QueryWithCountAsync(IAppEntity appEntity, string schemaIdOrName, ClaimsPrincipal user, HashSet<Guid> ids, string query) public async Task<(ISchemaEntity Schema, long Total, IReadOnlyList<IContentEntity> Items)> QueryWithCountAsync(IAppEntity app, string schemaIdOrName, ClaimsPrincipal user, HashSet<Guid> ids, string query)
{ {
Guard.NotNull(appEntity, nameof(appEntity)); Guard.NotNull(app, nameof(app));
Guard.NotNull(user, nameof(user)); Guard.NotNull(user, nameof(user));
Guard.NotNullOrEmpty(schemaIdOrName, nameof(schemaIdOrName)); Guard.NotNullOrEmpty(schemaIdOrName, nameof(schemaIdOrName));
var schemaEntity = await FindSchemaAsync(appEntity, schemaIdOrName); var schema = await FindSchemaAsync(app, schemaIdOrName);
var parsedQuery = ParseQuery(appEntity, query, schemaEntity); var parsedQuery = ParseQuery(app, query, schema);
var isFrontendClient = user.IsInClient("squidex-frontend"); var isFrontendClient = user.IsInClient("squidex-frontend");
var taskForItems = contentRepository.QueryAsync(appEntity, schemaEntity, isFrontendClient, ids, parsedQuery); var taskForItems = contentRepository.QueryAsync(app, schema, isFrontendClient, ids, parsedQuery);
var taskForCount = contentRepository.CountAsync(appEntity, schemaEntity, isFrontendClient, ids, parsedQuery); var taskForCount = contentRepository.CountAsync(app, schema, isFrontendClient, ids, parsedQuery);
await Task.WhenAll(taskForItems, taskForCount); await Task.WhenAll(taskForItems, taskForCount);
var list = TransformContent(user, schemaEntity, taskForItems.Result.ToList()); var list = TransformContent(user, schema, taskForItems.Result.ToList());
return (schemaEntity, taskForCount.Result, list); return (schema, taskForCount.Result, list);
} }
private List<IContentEntity> TransformContent(ClaimsPrincipal user, ISchemaEntity schemaEntity, List<IContentEntity> contentEntities) private List<IContentEntity> TransformContent(ClaimsPrincipal user, ISchemaEntity schema, List<IContentEntity> contents)
{ {
var scriptText = schemaEntity.ScriptQuery; var scriptText = schema.ScriptQuery;
if (!string.IsNullOrWhiteSpace(scriptText)) if (!string.IsNullOrWhiteSpace(scriptText))
{ {
for (var i = 0; i < contentEntities.Count; i++) for (var i = 0; i < contents.Count; i++)
{ {
var contentEntity = contentEntities[i]; var content = contents[i];
var contentData = scriptEngine.Transform(new ScriptContext { User = user, Data = contentEntity.Data, ContentId = contentEntity.Id }, scriptText); var contentData = scriptEngine.Transform(new ScriptContext { User = user, Data = content.Data, ContentId = content.Id }, scriptText);
contentEntities[i] = SimpleMapper.Map(contentEntity, new Content { Data = contentData }); contents[i] = SimpleMapper.Map(content, new Content { Data = contentData });
} }
} }
return contentEntities; return contents;
} }
private ODataUriParser ParseQuery(IAppEntity appEntity, string query, ISchemaEntity schemaEntity) private ODataUriParser ParseQuery(IAppEntity app, string query, ISchemaEntity schema)
{ {
try try
{ {
var model = modelBuilder.BuildEdmModel(schemaEntity, appEntity); var model = modelBuilder.BuildEdmModel(schema, app);
return model.ParseQuery(query); return model.ParseQuery(query);
} }
@ -128,9 +128,9 @@ namespace Squidex.Domain.Apps.Read.Contents
} }
} }
public async Task<ISchemaEntity> FindSchemaAsync(IEntity appEntity, string schemaIdOrName) public async Task<ISchemaEntity> FindSchemaAsync(IEntity app, string schemaIdOrName)
{ {
Guard.NotNull(appEntity, nameof(appEntity)); Guard.NotNull(app, nameof(app));
ISchemaEntity schema = null; ISchemaEntity schema = null;
@ -141,7 +141,7 @@ namespace Squidex.Domain.Apps.Read.Contents
if (schema == null) if (schema == null)
{ {
schema = await schemas.FindSchemaByNameAsync(appEntity.Id, schemaIdOrName); schema = await schemas.FindSchemaByNameAsync(app.Id, schemaIdOrName);
} }
if (schema == null) if (schema == null)

8
src/Squidex.Domain.Apps.Read/Contents/Edm/EdmModelBuilder.cs

@ -25,17 +25,17 @@ namespace Squidex.Domain.Apps.Read.Contents.Edm
{ {
} }
public IEdmModel BuildEdmModel(ISchemaEntity schemaEntity, IAppEntity app) public IEdmModel BuildEdmModel(ISchemaEntity schema, IAppEntity app)
{ {
Guard.NotNull(schemaEntity, nameof(schemaEntity)); Guard.NotNull(schema, nameof(schema));
var cacheKey = $"{schemaEntity.Id}_{schemaEntity.Version}_{app.Id}_{app.Version}"; var cacheKey = $"{schema.Id}_{schema.Version}_{app.Id}_{app.Version}";
var result = Cache.GetOrCreate<IEdmModel>(cacheKey, entry => var result = Cache.GetOrCreate<IEdmModel>(cacheKey, entry =>
{ {
entry.AbsoluteExpiration = DateTimeOffset.UtcNow.AddMinutes(60); entry.AbsoluteExpiration = DateTimeOffset.UtcNow.AddMinutes(60);
return BuildEdmModel(schemaEntity.Schema, app.PartitionResolver); return BuildEdmModel(schema.SchemaDef, app.PartitionResolver);
}); });
return result; return result;

22
src/Squidex.Domain.Apps.Read/Contents/GraphQL/GraphQLModel.cs

@ -36,20 +36,20 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL
private readonly Dictionary<Guid, ContentGraphType> schemaTypes = new Dictionary<Guid, ContentGraphType>(); private readonly Dictionary<Guid, ContentGraphType> schemaTypes = new Dictionary<Guid, ContentGraphType>();
private readonly Dictionary<Guid, ISchemaEntity> schemas; private readonly Dictionary<Guid, ISchemaEntity> schemas;
private readonly PartitionResolver partitionResolver; private readonly PartitionResolver partitionResolver;
private readonly IAppEntity appEntity; private readonly IAppEntity app;
private readonly IGraphType assetType; private readonly IGraphType assetType;
private readonly IGraphType assetListType; private readonly IGraphType assetListType;
private readonly GraphQLSchema graphQLSchema; private readonly GraphQLSchema graphQLSchema;
public bool CanGenerateAssetSourceUrl { get; } public bool CanGenerateAssetSourceUrl { get; }
public GraphQLModel(IAppEntity appEntity, IEnumerable<ISchemaEntity> schemas, IGraphQLUrlGenerator urlGenerator) public GraphQLModel(IAppEntity app, IEnumerable<ISchemaEntity> schemas, IGraphQLUrlGenerator urlGenerator)
{ {
this.appEntity = appEntity; this.app = app;
CanGenerateAssetSourceUrl = urlGenerator.CanGenerateAssetSourceUrl; CanGenerateAssetSourceUrl = urlGenerator.CanGenerateAssetSourceUrl;
partitionResolver = appEntity.PartitionResolver; partitionResolver = app.PartitionResolver;
assetType = new AssetGraphType(this); assetType = new AssetGraphType(this);
assetListType = new ListGraphType(new NonNullGraphType(assetType)); assetListType = new ListGraphType(new NonNullGraphType(assetType));
@ -111,7 +111,7 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL
{ {
var context = (QueryContext)c.UserContext; var context = (QueryContext)c.UserContext;
return context.UrlGenerator.GenerateAssetUrl(appEntity, c.Source); return context.UrlGenerator.GenerateAssetUrl(app, c.Source);
}); });
return resolver; return resolver;
@ -123,7 +123,7 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL
{ {
var context = (QueryContext)c.UserContext; var context = (QueryContext)c.UserContext;
return context.UrlGenerator.GenerateAssetSourceUrl(appEntity, c.Source); return context.UrlGenerator.GenerateAssetSourceUrl(app, c.Source);
}); });
return resolver; return resolver;
@ -135,19 +135,19 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL
{ {
var context = (QueryContext)c.UserContext; var context = (QueryContext)c.UserContext;
return context.UrlGenerator.GenerateAssetThumbnailUrl(appEntity, c.Source); return context.UrlGenerator.GenerateAssetThumbnailUrl(app, c.Source);
}); });
return resolver; return resolver;
} }
public IFieldResolver ResolveContentUrl(ISchemaEntity schemaEntity) public IFieldResolver ResolveContentUrl(ISchemaEntity schema)
{ {
var resolver = new FuncFieldResolver<IContentEntity, object>(c => var resolver = new FuncFieldResolver<IContentEntity, object>(c =>
{ {
var context = (QueryContext)c.UserContext; var context = (QueryContext)c.UserContext;
return context.UrlGenerator.GenerateContentUrl(appEntity, schemaEntity, c.Source); return context.UrlGenerator.GenerateContentUrl(app, schema, c.Source);
}); });
return resolver; return resolver;
@ -222,9 +222,9 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL
public IGraphType GetSchemaType(Guid schemaId) public IGraphType GetSchemaType(Guid schemaId)
{ {
var schemaEntity = schemas.GetOrDefault(schemaId); var schema = schemas.GetOrDefault(schemaId);
return schemaEntity != null ? schemaTypes.GetOrAdd(schemaId, k => new ContentGraphType(schemaEntity, this)) : null; return schema != null ? schemaTypes.GetOrAdd(schemaId, k => new ContentGraphType(schema, this)) : null;
} }
} }
} }

2
src/Squidex.Domain.Apps.Read/Contents/GraphQL/IGraphQLContext.cs

@ -31,7 +31,7 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL
IFieldResolver ResolveAssetThumbnailUrl(); IFieldResolver ResolveAssetThumbnailUrl();
IFieldResolver ResolveContentUrl(ISchemaEntity schemaEntity); IFieldResolver ResolveContentUrl(ISchemaEntity schema);
(IGraphType ResolveType, IFieldResolver Resolver) GetGraphType(Field field); (IGraphType ResolveType, IFieldResolver Resolver) GetGraphType(Field field);
} }

6
src/Squidex.Domain.Apps.Read/Contents/GraphQL/IGraphQLUrlGenerator.cs

@ -16,12 +16,12 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL
{ {
bool CanGenerateAssetSourceUrl { get; } bool CanGenerateAssetSourceUrl { get; }
string GenerateAssetUrl(IAppEntity app, IAssetEntity assetEntity); string GenerateAssetUrl(IAppEntity app, IAssetEntity asset);
string GenerateAssetThumbnailUrl(IAppEntity app, IAssetEntity asset); string GenerateAssetThumbnailUrl(IAppEntity app, IAssetEntity asset);
string GenerateAssetSourceUrl(IAppEntity appEntity, IAssetEntity assetEntity); string GenerateAssetSourceUrl(IAppEntity app, IAssetEntity asset);
string GenerateContentUrl(IAppEntity appEntity, ISchemaEntity schemaEntity, IContentEntity contentEntity); string GenerateContentUrl(IAppEntity app, ISchemaEntity schema, IContentEntity content);
} }
} }

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

@ -9,17 +9,14 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Read.Contents.Repositories;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Linq; using System.Linq;
using System.Security.Claims; using System.Security.Claims;
using System.Threading.Tasks; using System.Threading.Tasks;
using Squidex.Domain.Apps.Core.Scripting;
using Squidex.Domain.Apps.Read.Apps; using Squidex.Domain.Apps.Read.Apps;
using Squidex.Domain.Apps.Read.Assets; using Squidex.Domain.Apps.Read.Assets;
using Squidex.Domain.Apps.Read.Assets.Repositories; using Squidex.Domain.Apps.Read.Assets.Repositories;
using Squidex.Domain.Apps.Read.Schemas.Services;
// ReSharper disable InvertIf // ReSharper disable InvertIf
@ -32,7 +29,7 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL
private readonly IContentQueryService contentQuery; private readonly IContentQueryService contentQuery;
private readonly IAssetRepository assetRepository; private readonly IAssetRepository assetRepository;
private readonly IGraphQLUrlGenerator urlGenerator; private readonly IGraphQLUrlGenerator urlGenerator;
private readonly IAppEntity appEntity; private readonly IAppEntity app;
private readonly ClaimsPrincipal user; private readonly ClaimsPrincipal user;
public IGraphQLUrlGenerator UrlGenerator public IGraphQLUrlGenerator UrlGenerator
@ -41,7 +38,7 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL
} }
public QueryContext( public QueryContext(
IAppEntity appEntity, IAppEntity app,
IAssetRepository assetRepository, IAssetRepository assetRepository,
IContentQueryService contentQuery, IContentQueryService contentQuery,
IGraphQLUrlGenerator urlGenerator, IGraphQLUrlGenerator urlGenerator,
@ -50,14 +47,16 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL
Guard.NotNull(assetRepository, nameof(assetRepository)); Guard.NotNull(assetRepository, nameof(assetRepository));
Guard.NotNull(urlGenerator, nameof(urlGenerator)); Guard.NotNull(urlGenerator, nameof(urlGenerator));
Guard.NotNull(contentQuery, nameof(contentQuery)); Guard.NotNull(contentQuery, nameof(contentQuery));
Guard.NotNull(appEntity, nameof(appEntity)); Guard.NotNull(app, nameof(app));
Guard.NotNull(user, nameof(user)); Guard.NotNull(user, nameof(user));
this.assetRepository = assetRepository; this.assetRepository = assetRepository;
this.appEntity = appEntity;
this.contentQuery = contentQuery; this.contentQuery = contentQuery;
this.urlGenerator = urlGenerator; this.urlGenerator = urlGenerator;
this.user = user; this.user = user;
this.app = app;
} }
public async Task<IAssetEntity> FindAssetAsync(Guid id) public async Task<IAssetEntity> FindAssetAsync(Guid id)
@ -83,7 +82,7 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL
if (content == null) if (content == null)
{ {
content = (await contentQuery.FindContentAsync(appEntity, schemaId.ToString(), user, id).ConfigureAwait(false)).ContentEntity; content = (await contentQuery.FindContentAsync(app, schemaId.ToString(), user, id).ConfigureAwait(false)).Content;
if (content != null) if (content != null)
{ {
@ -96,7 +95,7 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL
public async Task<IReadOnlyList<IAssetEntity>> QueryAssetsAsync(string query, int skip = 0, int take = 10) public async Task<IReadOnlyList<IAssetEntity>> QueryAssetsAsync(string query, int skip = 0, int take = 10)
{ {
var assets = await assetRepository.QueryAsync(appEntity.Id, null, null, query, take, skip); var assets = await assetRepository.QueryAsync(app.Id, null, null, query, take, skip);
foreach (var asset in assets) foreach (var asset in assets)
{ {
@ -108,7 +107,7 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL
public async Task<IReadOnlyList<IContentEntity>> QueryContentsAsync(Guid schemaId, string query) public async Task<IReadOnlyList<IContentEntity>> QueryContentsAsync(Guid schemaId, string query)
{ {
var contents = (await contentQuery.QueryWithCountAsync(appEntity, schemaId.ToString(), user, null, query).ConfigureAwait(false)).Items; var contents = (await contentQuery.QueryWithCountAsync(app, schemaId.ToString(), user, null, query).ConfigureAwait(false)).Items;
foreach (var content in contents) foreach (var content in contents)
{ {
@ -133,7 +132,7 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL
if (notLoadedAssets.Count > 0) if (notLoadedAssets.Count > 0)
{ {
var assets = await assetRepository.QueryAsync(appEntity.Id, null, notLoadedAssets, null, int.MaxValue).ConfigureAwait(false); var assets = await assetRepository.QueryAsync(app.Id, null, notLoadedAssets, null, int.MaxValue).ConfigureAwait(false);
foreach (var asset in assets) foreach (var asset in assets)
{ {
@ -159,7 +158,7 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL
if (notLoadedContents.Count > 0) if (notLoadedContents.Count > 0)
{ {
var contents = (await contentQuery.QueryWithCountAsync(appEntity, schemaId.ToString(), user, notLoadedContents, null).ConfigureAwait(false)).Items; var contents = (await contentQuery.QueryWithCountAsync(app, schemaId.ToString(), user, notLoadedContents, null).ConfigureAwait(false)).Items;
foreach (var content in contents) foreach (var content in contents)
{ {

14
src/Squidex.Domain.Apps.Read/Contents/GraphQL/Types/ContentGraphType.cs

@ -16,20 +16,20 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL.Types
{ {
public sealed class ContentGraphType : ObjectGraphType<IContentEntity> public sealed class ContentGraphType : ObjectGraphType<IContentEntity>
{ {
private readonly ISchemaEntity schemaEntity; private readonly ISchemaEntity schema;
private readonly IGraphQLContext context; private readonly IGraphQLContext context;
public ContentGraphType(ISchemaEntity schemaEntity, IGraphQLContext context) public ContentGraphType(ISchemaEntity schema, IGraphQLContext context)
{ {
this.context = context; this.context = context;
this.schemaEntity = schemaEntity; this.schema = schema;
Name = $"{schemaEntity.Name.ToPascalCase()}Dto"; Name = $"{schema.Name.ToPascalCase()}Dto";
} }
public void Initialize() public void Initialize()
{ {
var schemaName = schemaEntity.Schema.Properties.Label.WithFallback(schemaEntity.Name); var schemaName = schema.SchemaDef.Properties.Label.WithFallback(schema.Name);
AddField(new FieldType AddField(new FieldType
{ {
@ -82,7 +82,7 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL.Types
AddField(new FieldType AddField(new FieldType
{ {
Name = "url", Name = "url",
Resolver = context.ResolveContentUrl(schemaEntity), Resolver = context.ResolveContentUrl(schema),
ResolvedType = new NonNullGraphType(new StringGraphType()), ResolvedType = new NonNullGraphType(new StringGraphType()),
Description = $"The url to the the {schemaName} content." Description = $"The url to the the {schemaName} content."
}); });
@ -91,7 +91,7 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL.Types
{ {
Name = "data", Name = "data",
Resolver = Resolver(x => x.Data), Resolver = Resolver(x => x.Data),
ResolvedType = new NonNullGraphType(new ContentDataGraphType(schemaEntity.Schema, context)), ResolvedType = new NonNullGraphType(new ContentDataGraphType(schema.SchemaDef, context)),
Description = $"The data of the {schemaName} content." Description = $"The data of the {schemaName} content."
}); });

24
src/Squidex.Domain.Apps.Read/Contents/GraphQL/Types/ContentQueryGraphType.cs

@ -20,18 +20,18 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL.Types
{ {
public sealed class ContentQueryGraphType : ObjectGraphType public sealed class ContentQueryGraphType : ObjectGraphType
{ {
public ContentQueryGraphType(IGraphQLContext graphQLContext, IEnumerable<ISchemaEntity> schemaEntities) public ContentQueryGraphType(IGraphQLContext graphQLContext, IEnumerable<ISchemaEntity> schemas)
{ {
AddAssetFind(graphQLContext); AddAssetFind(graphQLContext);
AddAssetsQuery(graphQLContext); AddAssetsQuery(graphQLContext);
foreach (var schemaEntity in schemaEntities) foreach (var schema in schemas)
{ {
var schemaName = schemaEntity.Schema.Properties.Label.WithFallback(schemaEntity.Schema.Name); var schemaName = schema.SchemaDef.Properties.Label.WithFallback(schema.SchemaDef.Name);
var schemaType = graphQLContext.GetSchemaType(schemaEntity.Id); var schemaType = graphQLContext.GetSchemaType(schema.Id);
AddContentFind(schemaEntity, schemaType, schemaName); AddContentFind(schema, schemaType, schemaName);
AddContentQuery(schemaEntity, schemaType, schemaName); AddContentQuery(schema, schemaType, schemaName);
} }
Description = "The app queries."; Description = "The app queries.";
@ -63,11 +63,11 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL.Types
}); });
} }
private void AddContentFind(ISchemaEntity schemaEntity, IGraphType schemaType, string schemaName) private void AddContentFind(ISchemaEntity schema, IGraphType schemaType, string schemaName)
{ {
AddField(new FieldType AddField(new FieldType
{ {
Name = $"find{schemaEntity.Name.ToPascalCase()}Content", Name = $"find{schema.Name.ToPascalCase()}Content",
Arguments = new QueryArguments Arguments = new QueryArguments
{ {
new QueryArgument(typeof(StringGraphType)) new QueryArgument(typeof(StringGraphType))
@ -83,7 +83,7 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL.Types
var context = (QueryContext)c.UserContext; var context = (QueryContext)c.UserContext;
var contentId = Guid.Parse(c.GetArgument("id", Guid.Empty.ToString())); var contentId = Guid.Parse(c.GetArgument("id", Guid.Empty.ToString()));
return context.FindContentAsync(schemaEntity.Id, contentId); return context.FindContentAsync(schema.Id, contentId);
}), }),
Description = $"Find an {schemaName} content by id." Description = $"Find an {schemaName} content by id."
}); });
@ -130,11 +130,11 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL.Types
}); });
} }
private void AddContentQuery(ISchemaEntity schemaEntity, IGraphType schemaType, string schemaName) private void AddContentQuery(ISchemaEntity schema, IGraphType schemaType, string schemaName)
{ {
AddField(new FieldType AddField(new FieldType
{ {
Name = $"query{schemaEntity.Name.ToPascalCase()}Contents", Name = $"query{schema.Name.ToPascalCase()}Contents",
Arguments = new QueryArguments Arguments = new QueryArguments
{ {
new QueryArgument(typeof(IntGraphType)) new QueryArgument(typeof(IntGraphType))
@ -174,7 +174,7 @@ namespace Squidex.Domain.Apps.Read.Contents.GraphQL.Types
var context = (QueryContext)c.UserContext; var context = (QueryContext)c.UserContext;
var contentQuery = BuildODataQuery(c); var contentQuery = BuildODataQuery(c);
return context.QueryContentsAsync(schemaEntity.Id, contentQuery); return context.QueryContentsAsync(schema.Id, contentQuery);
}), }),
Description = $"Query {schemaName} content items." Description = $"Query {schemaName} content items."
}); });

6
src/Squidex.Domain.Apps.Read/Contents/IContentQueryService.cs

@ -17,10 +17,10 @@ namespace Squidex.Domain.Apps.Read.Contents
{ {
public interface IContentQueryService public interface IContentQueryService
{ {
Task<(ISchemaEntity SchemaEntity, long Total, IReadOnlyList<IContentEntity> Items)> QueryWithCountAsync(IAppEntity appEntity, string schemaIdOrName, ClaimsPrincipal user, HashSet<Guid> ids, string query); Task<(ISchemaEntity Schema, long Total, IReadOnlyList<IContentEntity> Items)> QueryWithCountAsync(IAppEntity app, string schemaIdOrName, ClaimsPrincipal user, HashSet<Guid> ids, string query);
Task<(ISchemaEntity SchemaEntity, IContentEntity ContentEntity)> FindContentAsync(IAppEntity appEntity, string schemaIdOrName, ClaimsPrincipal user, Guid id); Task<(ISchemaEntity Schema, IContentEntity Content)> FindContentAsync(IAppEntity app, string schemaIdOrName, ClaimsPrincipal user, Guid id);
Task<ISchemaEntity> FindSchemaAsync(IEntity appEntity, string schemaIdOrName); Task<ISchemaEntity> FindSchemaAsync(IEntity app, string schemaIdOrName);
} }
} }

6
src/Squidex.Domain.Apps.Read/Contents/Repositories/IContentRepository.cs

@ -17,12 +17,12 @@ namespace Squidex.Domain.Apps.Read.Contents.Repositories
{ {
public interface IContentRepository public interface IContentRepository
{ {
Task<IReadOnlyList<IContentEntity>> QueryAsync(IAppEntity appEntity, ISchemaEntity schemaEntity, bool nonPublished, HashSet<Guid> ids, ODataUriParser odataQuery); Task<IReadOnlyList<IContentEntity>> QueryAsync(IAppEntity app, ISchemaEntity schema, bool nonPublished, HashSet<Guid> ids, ODataUriParser odataQuery);
Task<IReadOnlyList<Guid>> QueryNotFoundAsync(Guid appId, Guid schemaId, IList<Guid> contentIds); Task<IReadOnlyList<Guid>> QueryNotFoundAsync(Guid appId, Guid schemaId, IList<Guid> contentIds);
Task<long> CountAsync(IAppEntity appEntity, ISchemaEntity schemaEntity, bool nonPublished, HashSet<Guid> ids, ODataUriParser odataQuery); Task<long> CountAsync(IAppEntity app, ISchemaEntity schema, bool nonPublished, HashSet<Guid> ids, ODataUriParser odataQuery);
Task<IContentEntity> FindContentAsync(IAppEntity appEntity, ISchemaEntity schemaEntity, Guid id); Task<IContentEntity> FindContentAsync(IAppEntity app, ISchemaEntity schema, Guid id);
} }
} }

2
src/Squidex.Domain.Apps.Read/Schemas/ISchemaEntity.cs

@ -30,6 +30,6 @@ namespace Squidex.Domain.Apps.Read.Schemas
string ScriptUnpublish { get; } string ScriptUnpublish { get; }
Schema Schema { get; } Schema SchemaDef { get; }
} }
} }

6
src/Squidex.Domain.Apps.Write/Contents/ContentCommandMiddleware.cs

@ -69,7 +69,7 @@ namespace Squidex.Domain.Apps.Write.Contents
var scriptContext = CreateScriptContext(content, command, command.Data); var scriptContext = CreateScriptContext(content, command, command.Data);
command.Data = scriptEngine.ExecuteAndTransform(scriptContext, schemaAndApp.SchemaEntity.ScriptCreate, "create content"); command.Data = scriptEngine.ExecuteAndTransform(scriptContext, schemaAndApp.SchemaEntity.ScriptCreate, "create content");
command.Data.Enrich(schemaAndApp.SchemaEntity.Schema, schemaAndApp.AppEntity.PartitionResolver); command.Data.Enrich(schemaAndApp.SchemaEntity.SchemaDef, schemaAndApp.AppEntity.PartitionResolver);
await ValidateAsync(schemaAndApp, command, () => "Failed to create content", false); await ValidateAsync(schemaAndApp, command, () => "Failed to create content", false);
@ -181,11 +181,11 @@ namespace Squidex.Domain.Apps.Write.Contents
if (partial) if (partial)
{ {
await command.Data.ValidatePartialAsync(validationContext, schemaAndApp.Schema.Schema, schemaAndApp.App.PartitionResolver, schemaErrors); await command.Data.ValidatePartialAsync(validationContext, schemaAndApp.Schema.SchemaDef, schemaAndApp.App.PartitionResolver, schemaErrors);
} }
else else
{ {
await command.Data.ValidateAsync(validationContext, schemaAndApp.Schema.Schema, schemaAndApp.App.PartitionResolver, schemaErrors); await command.Data.ValidateAsync(validationContext, schemaAndApp.Schema.SchemaDef, schemaAndApp.App.PartitionResolver, schemaErrors);
} }
if (schemaErrors.Count > 0) if (schemaErrors.Count > 0)

10
src/Squidex/Controllers/Api/Schemas/Models/Converters/SchemaConverter.cs

@ -62,8 +62,8 @@ namespace Squidex.Controllers.Api.Schemas.Models.Converters
var dto = new SchemaDto { Properties = new SchemaPropertiesDto() }; var dto = new SchemaDto { Properties = new SchemaPropertiesDto() };
SimpleMapper.Map(entity, dto); SimpleMapper.Map(entity, dto);
SimpleMapper.Map(entity.Schema, dto); SimpleMapper.Map(entity.SchemaDef, dto);
SimpleMapper.Map(entity.Schema.Properties, dto.Properties); SimpleMapper.Map(entity.SchemaDef.Properties, dto.Properties);
return dto; return dto;
} }
@ -73,12 +73,12 @@ namespace Squidex.Controllers.Api.Schemas.Models.Converters
var dto = new SchemaDetailsDto { Properties = new SchemaPropertiesDto() }; var dto = new SchemaDetailsDto { Properties = new SchemaPropertiesDto() };
SimpleMapper.Map(entity, dto); SimpleMapper.Map(entity, dto);
SimpleMapper.Map(entity.Schema, dto); SimpleMapper.Map(entity.SchemaDef, dto);
SimpleMapper.Map(entity.Schema.Properties, dto.Properties); SimpleMapper.Map(entity.SchemaDef.Properties, dto.Properties);
dto.Fields = new List<FieldDto>(); dto.Fields = new List<FieldDto>();
foreach (var field in entity.Schema.Fields) foreach (var field in entity.SchemaDef.Fields)
{ {
var fieldPropertiesDto = Factories[field.RawProperties.GetType()](field.RawProperties); var fieldPropertiesDto = Factories[field.RawProperties.GetType()](field.RawProperties);
var fieldInstanceDto = SimpleMapper.Map(field, var fieldInstanceDto = SimpleMapper.Map(field,

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

@ -15,15 +15,10 @@ using Microsoft.Extensions.Primitives;
using NSwag.Annotations; using NSwag.Annotations;
using Squidex.Controllers.ContentApi.Models; using Squidex.Controllers.ContentApi.Models;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Scripting;
using Squidex.Domain.Apps.Read.Contents; using Squidex.Domain.Apps.Read.Contents;
using Squidex.Domain.Apps.Read.Contents.GraphQL; using Squidex.Domain.Apps.Read.Contents.GraphQL;
using Squidex.Domain.Apps.Read.Contents.Repositories;
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;
using Squidex.Domain.Apps.Write.Contents.Commands; using Squidex.Domain.Apps.Write.Contents.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.CQRS.Commands; using Squidex.Infrastructure.CQRS.Commands;
using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Reflection;
using Squidex.Pipeline; using Squidex.Pipeline;
@ -101,7 +96,7 @@ namespace Squidex.Controllers.ContentApi
if (item.Data != null) if (item.Data != null)
{ {
itemModel.Data = item.Data.ToApiModel(contents.SchemaEntity.Schema, App.LanguagesConfig, null, !isFrontendClient); itemModel.Data = item.Data.ToApiModel(contents.Schema.SchemaDef, App.LanguagesConfig, null, !isFrontendClient);
} }
return itemModel; return itemModel;
@ -119,16 +114,16 @@ namespace Squidex.Controllers.ContentApi
{ {
var content = await contentQuery.FindContentAsync(App, name, User, id); var content = await contentQuery.FindContentAsync(App, name, User, id);
var response = SimpleMapper.Map(content.ContentEntity, new ContentDto()); var response = SimpleMapper.Map(content.Content, new ContentDto());
if (content.ContentEntity.Data != null) if (content.Content.Data != null)
{ {
var isFrontendClient = User.IsFrontendClient(); var isFrontendClient = User.IsFrontendClient();
response.Data = content.ContentEntity.Data.ToApiModel(content.SchemaEntity.Schema, App.LanguagesConfig, null, !isFrontendClient); response.Data = content.Content.Data.ToApiModel(content.Schema.SchemaDef, App.LanguagesConfig, null, !isFrontendClient);
} }
Response.Headers["ETag"] = new StringValues(content.ContentEntity.Version.ToString()); Response.Headers["ETag"] = new StringValues(content.Content.Version.ToString());
return Ok(response); return Ok(response);
} }

2
src/Squidex/Controllers/ContentApi/Generator/SchemasSwaggerGenerator.cs

@ -64,7 +64,7 @@ namespace Squidex.Controllers.ContentApi.Generator
{ {
var appBasePath = $"/content/{app.Name}"; var appBasePath = $"/content/{app.Name}";
foreach (var schema in schemas.Where(x => x.IsPublished).Select(x => x.Schema)) foreach (var schema in schemas.Where(x => x.IsPublished).Select(x => x.SchemaDef))
{ {
new SchemaSwaggerGenerator(document, appBasePath, schema, AppendSchema, app.PartitionResolver).GenerateSchemaOperations(); new SchemaSwaggerGenerator(document, appBasePath, schema, AppendSchema, app.PartitionResolver).GenerateSchemaOperations();
} }

12
src/Squidex/Pipeline/GraphQLUrlGenerator.cs

@ -44,19 +44,19 @@ namespace Squidex.Pipeline
return urlsOptions.BuildUrl($"api/assets/{asset.Id}?version={asset.Version}&width=100&mode=Max"); return urlsOptions.BuildUrl($"api/assets/{asset.Id}?version={asset.Version}&width=100&mode=Max");
} }
public string GenerateAssetUrl(IAppEntity app, IAssetEntity assetEntity) public string GenerateAssetUrl(IAppEntity app, IAssetEntity asset)
{ {
return urlsOptions.BuildUrl($"api/assets/{assetEntity.Id}?version={assetEntity.Version}"); return urlsOptions.BuildUrl($"api/assets/{asset.Id}?version={asset.Version}");
} }
public string GenerateContentUrl(IAppEntity appEntity, ISchemaEntity schemaEntity, IContentEntity contentEntity) public string GenerateContentUrl(IAppEntity app, ISchemaEntity schema, IContentEntity content)
{ {
return urlsOptions.BuildUrl($"api/content/{appEntity.Name}/{schemaEntity.Name}/{contentEntity.Id}"); return urlsOptions.BuildUrl($"api/content/{app.Name}/{schema.Name}/{content.Id}");
} }
public string GenerateAssetSourceUrl(IAppEntity appEntity, IAssetEntity assetEntity) public string GenerateAssetSourceUrl(IAppEntity app, IAssetEntity asset)
{ {
return assetStore.GenerateSourceUrl(assetEntity.Id.ToString(), assetEntity.FileVersion, null); return assetStore.GenerateSourceUrl(asset.Id.ToString(), asset.FileVersion, null);
} }
} }
} }

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

@ -20,16 +20,13 @@ using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Read.Apps; using Squidex.Domain.Apps.Read.Apps;
using Squidex.Domain.Apps.Read.Assets.Repositories; using Squidex.Domain.Apps.Read.Assets.Repositories;
using Squidex.Domain.Apps.Read.Contents.GraphQL; using Squidex.Domain.Apps.Read.Contents.GraphQL;
using Squidex.Domain.Apps.Read.Contents.Repositories;
using Squidex.Domain.Apps.Read.Contents.TestData; using Squidex.Domain.Apps.Read.Contents.TestData;
using Squidex.Domain.Apps.Read.Schemas; using Squidex.Domain.Apps.Read.Schemas;
using Squidex.Domain.Apps.Read.Schemas.Repositories; using Squidex.Domain.Apps.Read.Schemas.Repositories;
using Xunit; using Xunit;
using NodaTime.Extensions; using NodaTime.Extensions;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Scripting;
using Squidex.Domain.Apps.Read.Assets; using Squidex.Domain.Apps.Read.Assets;
using Squidex.Domain.Apps.Read.Schemas.Services;
using Squidex.Infrastructure; using Squidex.Infrastructure;
// ReSharper disable SimilarAnonymousTypeNearby // ReSharper disable SimilarAnonymousTypeNearby
@ -41,7 +38,7 @@ namespace Squidex.Domain.Apps.Read.Contents
private static readonly Guid schemaId = Guid.NewGuid(); private static readonly Guid schemaId = Guid.NewGuid();
private static readonly Guid appId = Guid.NewGuid(); private static readonly Guid appId = Guid.NewGuid();
private readonly Schema schema = private readonly Schema schemaDef =
Schema.Create("my-schema", new SchemaProperties()) Schema.Create("my-schema", new SchemaProperties())
.AddOrUpdateField(new JsonField(1, "my-json", Partitioning.Invariant, .AddOrUpdateField(new JsonField(1, "my-json", Partitioning.Invariant,
new JsonFieldProperties())) new JsonFieldProperties()))
@ -62,27 +59,27 @@ namespace Squidex.Domain.Apps.Read.Contents
.AddOrUpdateField(new GeolocationField(9, "my-geolocation", Partitioning.Invariant, .AddOrUpdateField(new GeolocationField(9, "my-geolocation", Partitioning.Invariant,
new GeolocationFieldProperties())); new GeolocationFieldProperties()));
private readonly ISchemaRepository schemaRepository = A.Fake<ISchemaRepository>();
private readonly ISchemaEntity schemaEntity = A.Fake<ISchemaEntity>();
private readonly IContentQueryService contentQuery = A.Fake<IContentQueryService>(); private readonly IContentQueryService contentQuery = A.Fake<IContentQueryService>();
private readonly ISchemaRepository schemaRepository = A.Fake<ISchemaRepository>();
private readonly IAssetRepository assetRepository = A.Fake<IAssetRepository>(); private readonly IAssetRepository assetRepository = A.Fake<IAssetRepository>();
private readonly IAppEntity appEntity = A.Dummy<IAppEntity>(); private readonly ISchemaEntity schema = A.Fake<ISchemaEntity>();
private readonly IMemoryCache cache = new MemoryCache(Options.Create(new MemoryCacheOptions())); private readonly IMemoryCache cache = new MemoryCache(Options.Create(new MemoryCacheOptions()));
private readonly IAppEntity app = A.Dummy<IAppEntity>();
private readonly ClaimsPrincipal user = new ClaimsPrincipal(); private readonly ClaimsPrincipal user = new ClaimsPrincipal();
private readonly IGraphQLService sut; private readonly IGraphQLService sut;
public GraphQLTests() public GraphQLTests()
{ {
A.CallTo(() => appEntity.Id).Returns(appId); A.CallTo(() => app.Id).Returns(appId);
A.CallTo(() => appEntity.PartitionResolver).Returns(x => InvariantPartitioning.Instance); A.CallTo(() => app.PartitionResolver).Returns(x => InvariantPartitioning.Instance);
A.CallTo(() => schemaEntity.Id).Returns(schemaId); A.CallTo(() => schema.Id).Returns(schemaId);
A.CallTo(() => schemaEntity.Name).Returns(schema.Name); A.CallTo(() => schema.Name).Returns(schemaDef.Name);
A.CallTo(() => schemaEntity.Schema).Returns(schema); A.CallTo(() => schema.SchemaDef).Returns(schemaDef);
A.CallTo(() => schemaEntity.IsPublished).Returns(true); A.CallTo(() => schema.IsPublished).Returns(true);
A.CallTo(() => schemaEntity.ScriptQuery).Returns("<script-query>"); A.CallTo(() => schema.ScriptQuery).Returns("<script-query>");
var allSchemas = new List<ISchemaEntity> { schemaEntity }; var allSchemas = new List<ISchemaEntity> { schema };
A.CallTo(() => schemaRepository.QueryAllAsync(appId)).Returns(Task.FromResult<IReadOnlyList<ISchemaEntity>>(allSchemas)); A.CallTo(() => schemaRepository.QueryAllAsync(appId)).Returns(Task.FromResult<IReadOnlyList<ISchemaEntity>>(allSchemas));
@ -114,14 +111,14 @@ namespace Squidex.Domain.Apps.Read.Contents
} }
}"; }";
var assetEntity = CreateAsset(Guid.NewGuid()); var asset = CreateAsset(Guid.NewGuid());
var assets = new List<IAssetEntity> { assetEntity }; var assets = new List<IAssetEntity> { asset };
A.CallTo(() => assetRepository.QueryAsync(appEntity.Id, null, null, "my-query", 30, 5)) A.CallTo(() => assetRepository.QueryAsync(app.Id, null, null, "my-query", 30, 5))
.Returns(Task.FromResult<IReadOnlyList<IAssetEntity>>(assets)); .Returns(Task.FromResult<IReadOnlyList<IAssetEntity>>(assets));
var result = await sut.QueryAsync(appEntity, user, new GraphQLQuery { Query = query }); var result = await sut.QueryAsync(app, user, new GraphQLQuery { Query = query });
var expected = new var expected = new
{ {
@ -131,15 +128,15 @@ namespace Squidex.Domain.Apps.Read.Contents
{ {
new new
{ {
id = assetEntity.Id, id = asset.Id,
version = 1, version = 1,
created = assetEntity.Created.ToDateTimeUtc(), created = asset.Created.ToDateTimeUtc(),
createdBy = "subject:user1", createdBy = "subject:user1",
lastModified = assetEntity.LastModified.ToDateTimeUtc(), lastModified = asset.LastModified.ToDateTimeUtc(),
lastModifiedBy = "subject:user2", lastModifiedBy = "subject:user2",
url = $"assets/{assetEntity.Id}", url = $"assets/{asset.Id}",
thumbnailUrl = $"assets/{assetEntity.Id}?width=100", thumbnailUrl = $"assets/{asset.Id}?width=100",
sourceUrl = $"assets/source/{assetEntity.Id}", sourceUrl = $"assets/source/{asset.Id}",
mimeType = "image/png", mimeType = "image/png",
fileName = "MyFile.png", fileName = "MyFile.png",
fileSize = 1024, fileSize = 1024,
@ -159,7 +156,7 @@ namespace Squidex.Domain.Apps.Read.Contents
public async Task Should_return_single_asset_when_finding_asset() public async Task Should_return_single_asset_when_finding_asset()
{ {
var assetId = Guid.NewGuid(); var assetId = Guid.NewGuid();
var assetEntity = CreateAsset(Guid.NewGuid()); var asset = CreateAsset(Guid.NewGuid());
var query = $@" var query = $@"
query {{ query {{
@ -184,9 +181,9 @@ namespace Squidex.Domain.Apps.Read.Contents
}}"; }}";
A.CallTo(() => assetRepository.FindAssetAsync(assetId)) A.CallTo(() => assetRepository.FindAssetAsync(assetId))
.Returns(Task.FromResult(assetEntity)); .Returns(Task.FromResult(asset));
var result = await sut.QueryAsync(appEntity, user, new GraphQLQuery { Query = query }); var result = await sut.QueryAsync(app, user, new GraphQLQuery { Query = query });
var expected = new var expected = new
{ {
@ -194,15 +191,15 @@ namespace Squidex.Domain.Apps.Read.Contents
{ {
findAsset = new findAsset = new
{ {
id = assetEntity.Id, id = asset.Id,
version = 1, version = 1,
created = assetEntity.Created.ToDateTimeUtc(), created = asset.Created.ToDateTimeUtc(),
createdBy = "subject:user1", createdBy = "subject:user1",
lastModified = assetEntity.LastModified.ToDateTimeUtc(), lastModified = asset.LastModified.ToDateTimeUtc(),
lastModifiedBy = "subject:user2", lastModifiedBy = "subject:user2",
url = $"assets/{assetEntity.Id}", url = $"assets/{asset.Id}",
thumbnailUrl = $"assets/{assetEntity.Id}?width=100", thumbnailUrl = $"assets/{asset.Id}?width=100",
sourceUrl = $"assets/source/{assetEntity.Id}", sourceUrl = $"assets/source/{asset.Id}",
mimeType = "image/png", mimeType = "image/png",
fileName = "MyFile.png", fileName = "MyFile.png",
fileSize = 1024, fileSize = 1024,
@ -253,14 +250,14 @@ namespace Squidex.Domain.Apps.Read.Contents
} }
}"; }";
var contentEntity = CreateContent(Guid.NewGuid(), Guid.Empty, Guid.Empty); var content = CreateContent(Guid.NewGuid(), Guid.Empty, Guid.Empty);
var contents = new List<IContentEntity> { contentEntity }; var contents = new List<IContentEntity> { content };
A.CallTo(() => contentQuery.QueryWithCountAsync(appEntity, schemaEntity.Id.ToString(), user, null, "?$top=30&$skip=5")) A.CallTo(() => contentQuery.QueryWithCountAsync(app, schema.Id.ToString(), user, null, "?$top=30&$skip=5"))
.Returns(Task.FromResult((schemaEntity, 0L, (IReadOnlyList<IContentEntity>)contents))); .Returns(Task.FromResult((schema, 0L, (IReadOnlyList<IContentEntity>)contents)));
var result = await sut.QueryAsync(appEntity, user, new GraphQLQuery { Query = query }); var result = await sut.QueryAsync(app, user, new GraphQLQuery { Query = query });
var expected = new var expected = new
{ {
@ -270,13 +267,13 @@ namespace Squidex.Domain.Apps.Read.Contents
{ {
new new
{ {
id = contentEntity.Id, id = content.Id,
version = 1, version = 1,
created = contentEntity.Created.ToDateTimeUtc(), created = content.Created.ToDateTimeUtc(),
createdBy = "subject:user1", createdBy = "subject:user1",
lastModified = contentEntity.LastModified.ToDateTimeUtc(), lastModified = content.LastModified.ToDateTimeUtc(),
lastModifiedBy = "subject:user2", lastModifiedBy = "subject:user2",
url = $"contents/my-schema/{contentEntity.Id}", url = $"contents/my-schema/{content.Id}",
data = new data = new
{ {
myString = new myString = new
@ -293,7 +290,7 @@ namespace Squidex.Domain.Apps.Read.Contents
}, },
myDatetime = new myDatetime = new
{ {
iv = contentEntity.LastModified.ToDateTimeUtc() iv = content.LastModified.ToDateTimeUtc()
}, },
myJson = new myJson = new
{ {
@ -323,7 +320,7 @@ namespace Squidex.Domain.Apps.Read.Contents
public async Task Should_return_single_content_when_finding_content() public async Task Should_return_single_content_when_finding_content()
{ {
var contentId = Guid.NewGuid(); var contentId = Guid.NewGuid();
var contentEntity = CreateContent(contentId, Guid.Empty, Guid.Empty); var content = CreateContent(contentId, Guid.Empty, Guid.Empty);
var query = $@" var query = $@"
query {{ query {{
@ -358,10 +355,10 @@ namespace Squidex.Domain.Apps.Read.Contents
}} }}
}}"; }}";
A.CallTo(() => contentQuery.FindContentAsync(appEntity, schemaEntity.ToString(), user, contentId)) A.CallTo(() => contentQuery.FindContentAsync(app, schema.ToString(), user, contentId))
.Returns(Task.FromResult((schemaEntity, contentEntity))); .Returns(Task.FromResult((schema, content)));
var result = await sut.QueryAsync(appEntity, user, new GraphQLQuery { Query = query }); var result = await sut.QueryAsync(app, user, new GraphQLQuery { Query = query });
var expected = new var expected = new
{ {
@ -369,13 +366,13 @@ namespace Squidex.Domain.Apps.Read.Contents
{ {
findMySchemaContent = new findMySchemaContent = new
{ {
id = contentEntity.Id, id = content.Id,
version = 1, version = 1,
created = contentEntity.Created.ToDateTimeUtc(), created = content.Created.ToDateTimeUtc(),
createdBy = "subject:user1", createdBy = "subject:user1",
lastModified = contentEntity.LastModified.ToDateTimeUtc(), lastModified = content.LastModified.ToDateTimeUtc(),
lastModifiedBy = "subject:user2", lastModifiedBy = "subject:user2",
url = $"contents/my-schema/{contentEntity.Id}", url = $"contents/my-schema/{content.Id}",
data = new data = new
{ {
myString = new myString = new
@ -392,7 +389,7 @@ namespace Squidex.Domain.Apps.Read.Contents
}, },
myDatetime = new myDatetime = new
{ {
iv = contentEntity.LastModified.ToDateTimeUtc() iv = content.LastModified.ToDateTimeUtc()
}, },
myJson = new myJson = new
{ {
@ -421,10 +418,10 @@ namespace Squidex.Domain.Apps.Read.Contents
public async Task Should_also_fetch_referenced_contents_when_field_is_included_in_query() public async Task Should_also_fetch_referenced_contents_when_field_is_included_in_query()
{ {
var contentRefId = Guid.NewGuid(); var contentRefId = Guid.NewGuid();
var contentRefEntity = CreateContent(contentRefId, Guid.Empty, Guid.Empty); var contentRef = CreateContent(contentRefId, Guid.Empty, Guid.Empty);
var contentId = Guid.NewGuid(); var contentId = Guid.NewGuid();
var contentEntity = CreateContent(contentId, contentRefId, Guid.Empty); var content = CreateContent(contentId, contentRefId, Guid.Empty);
var query = $@" var query = $@"
query {{ query {{
@ -440,15 +437,15 @@ namespace Squidex.Domain.Apps.Read.Contents
}} }}
}}"; }}";
var refContents = new List<IContentEntity> { contentRefEntity }; var refContents = new List<IContentEntity> { contentRef };
A.CallTo(() => contentQuery.FindContentAsync(appEntity, schemaEntity.ToString(), user, contentId)) A.CallTo(() => contentQuery.FindContentAsync(app, schema.ToString(), user, contentId))
.Returns(Task.FromResult((schemaEntity, contentEntity))); .Returns(Task.FromResult((schema, content)));
A.CallTo(() => contentQuery.QueryWithCountAsync(appEntity, schemaEntity.Id.ToString(), user, A<HashSet<Guid>>.That.Matches(x => x.Contains(contentRefId)), null)) A.CallTo(() => contentQuery.QueryWithCountAsync(app, schema.Id.ToString(), user, A<HashSet<Guid>>.That.Matches(x => x.Contains(contentRefId)), null))
.Returns(Task.FromResult((schemaEntity, 0L, (IReadOnlyList<IContentEntity>)refContents))); .Returns(Task.FromResult((schema, 0L, (IReadOnlyList<IContentEntity>)refContents)));
var result = await sut.QueryAsync(appEntity, user, new GraphQLQuery { Query = query }); var result = await sut.QueryAsync(app, user, new GraphQLQuery { Query = query });
var expected = new var expected = new
{ {
@ -456,7 +453,7 @@ namespace Squidex.Domain.Apps.Read.Contents
{ {
findMySchemaContent = new findMySchemaContent = new
{ {
id = contentEntity.Id, id = content.Id,
data = new data = new
{ {
myReferences = new myReferences = new
@ -481,10 +478,10 @@ namespace Squidex.Domain.Apps.Read.Contents
public async Task Should_also_fetch_referenced_assets_when_field_is_included_in_query() public async Task Should_also_fetch_referenced_assets_when_field_is_included_in_query()
{ {
var assetRefId = Guid.NewGuid(); var assetRefId = Guid.NewGuid();
var assetRefEntity = CreateAsset(assetRefId); var assetRef = CreateAsset(assetRefId);
var contentId = Guid.NewGuid(); var contentId = Guid.NewGuid();
var contentEntity = CreateContent(contentId, Guid.Empty, assetRefId); var content = CreateContent(contentId, Guid.Empty, assetRefId);
var query = $@" var query = $@"
query {{ query {{
@ -500,15 +497,15 @@ namespace Squidex.Domain.Apps.Read.Contents
}} }}
}}"; }}";
var refAssets = new List<IAssetEntity> { assetRefEntity }; var refAssets = new List<IAssetEntity> { assetRef };
A.CallTo(() => contentQuery.FindContentAsync(appEntity, schemaEntity.ToString(), user, contentId)) A.CallTo(() => contentQuery.FindContentAsync(app, schema.ToString(), user, contentId))
.Returns(Task.FromResult((schemaEntity, contentEntity))); .Returns(Task.FromResult((schema, content)));
A.CallTo(() => assetRepository.QueryAsync(appEntity.Id, null, A<HashSet<Guid>>.That.Matches(x => x.Contains(assetRefId)), null, int.MaxValue, 0)) A.CallTo(() => assetRepository.QueryAsync(app.Id, null, A<HashSet<Guid>>.That.Matches(x => x.Contains(assetRefId)), null, int.MaxValue, 0))
.Returns(Task.FromResult<IReadOnlyList<IAssetEntity>>(refAssets)); .Returns(Task.FromResult<IReadOnlyList<IAssetEntity>>(refAssets));
var result = await sut.QueryAsync(appEntity, user, new GraphQLQuery { Query = query }); var result = await sut.QueryAsync(app, user, new GraphQLQuery { Query = query });
var expected = new var expected = new
{ {
@ -516,7 +513,7 @@ namespace Squidex.Domain.Apps.Read.Contents
{ {
findMySchemaContent = new findMySchemaContent = new
{ {
id = contentEntity.Id, id = content.Id,
data = new data = new
{ {
myAssets = new myAssets = new
@ -541,7 +538,7 @@ namespace Squidex.Domain.Apps.Read.Contents
public async Task Should_not_return_value_when_field_not_part_of_content() public async Task Should_not_return_value_when_field_not_part_of_content()
{ {
var contentId = Guid.NewGuid(); var contentId = Guid.NewGuid();
var contentEntity = CreateContent(contentId, Guid.Empty, Guid.Empty, new NamedContentData()); var content = CreateContent(contentId, Guid.Empty, Guid.Empty, new NamedContentData());
var query = $@" var query = $@"
query {{ query {{
@ -561,10 +558,10 @@ namespace Squidex.Domain.Apps.Read.Contents
}} }}
}}"; }}";
A.CallTo(() => contentQuery.FindContentAsync(appEntity, schemaEntity.ToString(), user, contentId)) A.CallTo(() => contentQuery.FindContentAsync(app, schema.ToString(), user, contentId))
.Returns(Task.FromResult((schemaEntity, contentEntity))); .Returns(Task.FromResult((schema, content)));
var result = await sut.QueryAsync(appEntity, user, new GraphQLQuery { Query = query }); var result = await sut.QueryAsync(app, user, new GraphQLQuery { Query = query });
var expected = new var expected = new
{ {
@ -572,13 +569,13 @@ namespace Squidex.Domain.Apps.Read.Contents
{ {
findMySchemaContent = new findMySchemaContent = new
{ {
id = contentEntity.Id, id = content.Id,
version = 1, version = 1,
created = contentEntity.Created.ToDateTimeUtc(), created = content.Created.ToDateTimeUtc(),
createdBy = "subject:user1", createdBy = "subject:user1",
lastModified = contentEntity.LastModified.ToDateTimeUtc(), lastModified = content.LastModified.ToDateTimeUtc(),
lastModifiedBy = "subject:user2", lastModifiedBy = "subject:user2",
url = $"contents/my-schema/{contentEntity.Id}", url = $"contents/my-schema/{content.Id}",
data = new data = new
{ {
myString = (object)null myString = (object)null
@ -613,7 +610,7 @@ namespace Squidex.Domain.Apps.Read.Contents
.AddField("my-geolocation", .AddField("my-geolocation",
new ContentFieldData().AddValue("iv", JToken.FromObject(new { latitude = 10, longitude = 20 }))); new ContentFieldData().AddValue("iv", JToken.FromObject(new { latitude = 10, longitude = 20 })));
var contentEntity = new FakeContentEntity var content = new FakeContentEntity
{ {
Id = id, Id = id,
Version = 1, Version = 1,
@ -624,14 +621,14 @@ namespace Squidex.Domain.Apps.Read.Contents
Data = data Data = data
}; };
return contentEntity; return content;
} }
private static IAssetEntity CreateAsset(Guid id) private static IAssetEntity CreateAsset(Guid id)
{ {
var now = DateTime.UtcNow.ToInstant(); var now = DateTime.UtcNow.ToInstant();
var assetEntity = new FakeAssetEntity var asset = new FakeAssetEntity
{ {
Id = id, Id = id,
Version = 1, Version = 1,
@ -648,7 +645,7 @@ namespace Squidex.Domain.Apps.Read.Contents
PixelHeight = 600 PixelHeight = 600
}; };
return assetEntity; return asset;
} }
private static void AssertJson(object expected, object result) private static void AssertJson(object expected, object result)

24
tests/Squidex.Domain.Apps.Read.Tests/Contents/ODataQueryTests.cs

@ -31,7 +31,7 @@ namespace Squidex.Domain.Apps.Read.Contents
{ {
public class ODataQueryTests public class ODataQueryTests
{ {
private readonly Schema schema = private readonly Schema schemaDef =
Schema.Create("user", new SchemaProperties { Hints = "The User" }) Schema.Create("user", new SchemaProperties { Hints = "The User" })
.AddOrUpdateField(new StringField(1, "firstName", Partitioning.Language, .AddOrUpdateField(new StringField(1, "firstName", Partitioning.Language,
new StringFieldProperties { Label = "FirstName", IsRequired = true, AllowedValues = new[] { "1", "2" }.ToImmutableList() })) new StringFieldProperties { Label = "FirstName", IsRequired = true, AllowedValues = new[] { "1", "2" }.ToImmutableList() }))
@ -64,17 +64,17 @@ namespace Squidex.Domain.Apps.Read.Contents
{ {
var builder = new EdmModelBuilder(new MemoryCache(Options.Create(new MemoryCacheOptions()))); var builder = new EdmModelBuilder(new MemoryCache(Options.Create(new MemoryCacheOptions())));
var schemaEntity = A.Dummy<ISchemaEntity>(); var schema = A.Dummy<ISchemaEntity>();
A.CallTo(() => schemaEntity.Id).Returns(Guid.NewGuid()); A.CallTo(() => schema.Id).Returns(Guid.NewGuid());
A.CallTo(() => schemaEntity.Version).Returns(3); A.CallTo(() => schema.Version).Returns(3);
A.CallTo(() => schemaEntity.Schema).Returns(schema); A.CallTo(() => schema.SchemaDef).Returns(schemaDef);
var appEntity = A.Dummy<IAppEntity>(); var app = A.Dummy<IAppEntity>();
A.CallTo(() => appEntity.Id).Returns(Guid.NewGuid()); A.CallTo(() => app.Id).Returns(Guid.NewGuid());
A.CallTo(() => appEntity.Version).Returns(3); A.CallTo(() => app.Version).Returns(3);
A.CallTo(() => appEntity.PartitionResolver).Returns(languagesConfig.ToResolver()); A.CallTo(() => app.PartitionResolver).Returns(languagesConfig.ToResolver());
edmModel = builder.BuildEdmModel(schemaEntity, appEntity); edmModel = builder.BuildEdmModel(schema, app);
} }
[Fact] [Fact]
@ -374,7 +374,7 @@ namespace Squidex.Domain.Apps.Read.Contents
i = sortDefinition.Render(serializer, registry).ToString(); i = sortDefinition.Render(serializer, registry).ToString();
}); });
cursor.Sort(parser, schema); cursor.Sort(parser, schemaDef);
return i; return i;
} }
@ -383,7 +383,7 @@ namespace Squidex.Domain.Apps.Read.Contents
{ {
var parser = edmModel.ParseQuery(value); var parser = edmModel.ParseQuery(value);
var query = FilterBuilder.Build(parser, schema).Render(serializer, registry).ToString(); var query = FilterBuilder.Build(parser, schemaDef).Render(serializer, registry).ToString();
return query; return query;
} }

12
tests/Squidex.Domain.Apps.Read.Tests/Contents/TestData/FakeUrlGenerator.cs

@ -17,9 +17,9 @@ namespace Squidex.Domain.Apps.Read.Contents.TestData
{ {
public bool CanGenerateAssetSourceUrl { get; } = true; public bool CanGenerateAssetSourceUrl { get; } = true;
public string GenerateAssetUrl(IAppEntity app, IAssetEntity assetEntity) public string GenerateAssetUrl(IAppEntity app, IAssetEntity asset)
{ {
return $"assets/{assetEntity.Id}"; return $"assets/{asset.Id}";
} }
public string GenerateAssetThumbnailUrl(IAppEntity app, IAssetEntity asset) public string GenerateAssetThumbnailUrl(IAppEntity app, IAssetEntity asset)
@ -27,14 +27,14 @@ namespace Squidex.Domain.Apps.Read.Contents.TestData
return $"assets/{asset.Id}?width=100"; return $"assets/{asset.Id}?width=100";
} }
public string GenerateAssetSourceUrl(IAppEntity appEntity, IAssetEntity assetEntity) public string GenerateAssetSourceUrl(IAppEntity app, IAssetEntity asset)
{ {
return $"assets/source/{assetEntity.Id}"; return $"assets/source/{asset.Id}";
} }
public string GenerateContentUrl(IAppEntity appEntity, ISchemaEntity schemaEntity, IContentEntity contentEntity) public string GenerateContentUrl(IAppEntity app, ISchemaEntity schema, IContentEntity content)
{ {
return $"contents/{schemaEntity.Name}/{contentEntity.Id}"; return $"contents/{schema.Name}/{content.Id}";
} }
} }
} }

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

@ -35,10 +35,10 @@ namespace Squidex.Domain.Apps.Write.Contents
private readonly ContentCommandMiddleware sut; private readonly ContentCommandMiddleware sut;
private readonly ContentDomainObject content; private readonly ContentDomainObject content;
private readonly ISchemaProvider schemas = A.Fake<ISchemaProvider>(); private readonly ISchemaProvider schemas = A.Fake<ISchemaProvider>();
private readonly ISchemaEntity schemaEntity = A.Fake<ISchemaEntity>(); private readonly ISchemaEntity schema = A.Fake<ISchemaEntity>();
private readonly IScriptEngine scriptEngine = A.Fake<IScriptEngine>(); private readonly IScriptEngine scriptEngine = A.Fake<IScriptEngine>();
private readonly IAppProvider appProvider = A.Fake<IAppProvider>(); private readonly IAppProvider appProvider = A.Fake<IAppProvider>();
private readonly IAppEntity appEntity = A.Fake<IAppEntity>(); private readonly IAppEntity app = A.Fake<IAppEntity>();
private readonly ClaimsPrincipal user = new ClaimsPrincipal(); private readonly ClaimsPrincipal user = new ClaimsPrincipal();
private readonly NamedContentData invalidData = new NamedContentData().AddField("my-field", new ContentFieldData().SetValue(null)); private readonly NamedContentData invalidData = new NamedContentData().AddField("my-field", new ContentFieldData().SetValue(null));
private readonly NamedContentData data = new NamedContentData().AddField("my-field", new ContentFieldData().SetValue(1)); private readonly NamedContentData data = new NamedContentData().AddField("my-field", new ContentFieldData().SetValue(1));
@ -47,7 +47,7 @@ namespace Squidex.Domain.Apps.Write.Contents
public ContentCommandMiddlewareTests() public ContentCommandMiddlewareTests()
{ {
var schema = var schemaDef =
Schema.Create("my-schema", new SchemaProperties()) Schema.Create("my-schema", new SchemaProperties())
.AddOrUpdateField(new NumberField(1, "my-field", Partitioning.Invariant, .AddOrUpdateField(new NumberField(1, "my-field", Partitioning.Invariant,
new NumberFieldProperties { IsRequired = true })); new NumberFieldProperties { IsRequired = true }));
@ -56,12 +56,12 @@ namespace Squidex.Domain.Apps.Write.Contents
sut = new ContentCommandMiddleware(Handler, appProvider, A.Dummy<IAssetRepository>(), schemas, 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(() => app.LanguagesConfig).Returns(languagesConfig);
A.CallTo(() => appEntity.PartitionResolver).Returns(languagesConfig.ToResolver()); A.CallTo(() => app.PartitionResolver).Returns(languagesConfig.ToResolver());
A.CallTo(() => appProvider.FindAppByIdAsync(AppId)).Returns(Task.FromResult(appEntity)); A.CallTo(() => appProvider.FindAppByIdAsync(AppId)).Returns(Task.FromResult(app));
A.CallTo(() => schemaEntity.Schema).Returns(schema); A.CallTo(() => schema.SchemaDef).Returns(schemaDef);
A.CallTo(() => schemas.FindSchemaByIdAsync(SchemaId, false)).Returns(Task.FromResult(schemaEntity)); A.CallTo(() => schemas.FindSchemaByIdAsync(SchemaId, false)).Returns(Task.FromResult(schema));
} }
[Fact] [Fact]
@ -81,7 +81,7 @@ namespace Squidex.Domain.Apps.Write.Contents
public async Task Create_should_create_content() public async Task Create_should_create_content()
{ {
A.CallTo(() => scriptEngine.ExecuteAndTransform(A<ScriptContext>.Ignored, A<string>.Ignored, A<string>.Ignored)).Returns(data); A.CallTo(() => scriptEngine.ExecuteAndTransform(A<ScriptContext>.Ignored, A<string>.Ignored, A<string>.Ignored)).Returns(data);
A.CallTo(() => schemaEntity.ScriptCreate).Returns("<create-script>"); A.CallTo(() => schema.ScriptCreate).Returns("<create-script>");
var context = CreateContextForCommand(new CreateContent { ContentId = contentId, Data = data, User = user }); var context = CreateContextForCommand(new CreateContent { ContentId = contentId, Data = data, User = user });
@ -114,7 +114,7 @@ namespace Squidex.Domain.Apps.Write.Contents
public async Task Update_should_update_domain_object() public async Task Update_should_update_domain_object()
{ {
A.CallTo(() => scriptEngine.ExecuteAndTransform(A<ScriptContext>.Ignored, A<string>.Ignored, A<string>.Ignored)).Returns(data); A.CallTo(() => scriptEngine.ExecuteAndTransform(A<ScriptContext>.Ignored, A<string>.Ignored, A<string>.Ignored)).Returns(data);
A.CallTo(() => schemaEntity.ScriptUpdate).Returns("<update-script>"); A.CallTo(() => schema.ScriptUpdate).Returns("<update-script>");
CreateContent(); CreateContent();
@ -149,7 +149,7 @@ namespace Squidex.Domain.Apps.Write.Contents
public async Task Patch_should_update_domain_object() public async Task Patch_should_update_domain_object()
{ {
A.CallTo(() => scriptEngine.ExecuteAndTransform(A<ScriptContext>.Ignored, A<string>.Ignored, A<string>.Ignored)).Returns(data); A.CallTo(() => scriptEngine.ExecuteAndTransform(A<ScriptContext>.Ignored, A<string>.Ignored, A<string>.Ignored)).Returns(data);
A.CallTo(() => schemaEntity.ScriptUpdate).Returns("<update-script>"); A.CallTo(() => schema.ScriptUpdate).Returns("<update-script>");
var patch = new NamedContentData().AddField("my-field", new ContentFieldData().SetValue(3)); var patch = new NamedContentData().AddField("my-field", new ContentFieldData().SetValue(3));
@ -172,7 +172,7 @@ namespace Squidex.Domain.Apps.Write.Contents
[Fact] [Fact]
public async Task Publish_should_publish_domain_object() public async Task Publish_should_publish_domain_object()
{ {
A.CallTo(() => schemaEntity.ScriptPublish).Returns("<publish-script>"); A.CallTo(() => schema.ScriptPublish).Returns("<publish-script>");
CreateContent(); CreateContent();
@ -189,7 +189,7 @@ namespace Squidex.Domain.Apps.Write.Contents
[Fact] [Fact]
public async Task Unpublish_should_unpublish_domain_object() public async Task Unpublish_should_unpublish_domain_object()
{ {
A.CallTo(() => schemaEntity.ScriptUnpublish).Returns("<unpublish-script>"); A.CallTo(() => schema.ScriptUnpublish).Returns("<unpublish-script>");
CreateContent(); CreateContent();
@ -206,7 +206,7 @@ namespace Squidex.Domain.Apps.Write.Contents
[Fact] [Fact]
public async Task Delete_should_update_domain_object() public async Task Delete_should_update_domain_object()
{ {
A.CallTo(() => schemaEntity.ScriptDelete).Returns("<delete-script>"); A.CallTo(() => schema.ScriptDelete).Returns("<delete-script>");
CreateContent(); CreateContent();

Loading…
Cancel
Save