Browse Source

Everything saved.

pull/364/head
Sebastian Stehle 7 years ago
parent
commit
9e735959f2
  1. 1
      Squidex.ruleset
  2. 1
      src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository.cs
  3. 6
      src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Visitors/FilterFactory.cs
  4. 49
      src/Squidex.Domain.Apps.Entities/Contents/ContentQueryService.cs
  5. 2
      src/Squidex.Domain.Apps.Entities/Contents/StatusForApi.cs
  6. 16
      src/Squidex.Domain.Apps.Entities/Contents/StatusForFrontend.cs
  7. 19
      src/Squidex.Domain.Apps.Entities/QueryContext.cs
  8. 76
      tests/Squidex.Domain.Apps.Entities.Tests/Contents/ContentQueryServiceTests.cs
  9. 5
      tests/Squidex.Domain.Apps.Entities.Tests/TestHelpers/AExtensions.cs

1
Squidex.ruleset

@ -63,6 +63,7 @@
<Rule Id="SA1601" Action="None" /> <Rule Id="SA1601" Action="None" />
<Rule Id="SA1413" Action="None" /> <Rule Id="SA1413" Action="None" />
<Rule Id="SA0001" Action="None" /> <Rule Id="SA0001" Action="None" />
<Rule Id="SA1602" Action="None" />
</Rules> </Rules>
<Rules AnalyzerId="RefactoringEssentials" RuleNamespace="RefactoringEssentials"> <Rules AnalyzerId="RefactoringEssentials" RuleNamespace="RefactoringEssentials">
<Rule Id="RECS0061" Action="Error" /> <Rule Id="RECS0061" Action="Error" />

1
src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository.cs

@ -64,7 +64,6 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents
{ {
Guard.NotNull(app, nameof(app)); Guard.NotNull(app, nameof(app));
Guard.NotNull(schema, nameof(schema)); Guard.NotNull(schema, nameof(schema));
Guard.NotNull(status, nameof(status));
Guard.NotNull(query, nameof(query)); Guard.NotNull(query, nameof(query));
using (Profiler.TraceMethod<MongoContentRepository>("QueryAsyncByQuery")) using (Profiler.TraceMethod<MongoContentRepository>("QueryAsyncByQuery"))

6
src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Visitors/FilterFactory.cs

@ -162,7 +162,11 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents.Visitors
} }
filters.Add(Filter.Ne(x => x.IsDeleted, true)); filters.Add(Filter.Ne(x => x.IsDeleted, true));
filters.Add(Filter.In(x => x.Status, status));
if (status != null)
{
filters.Add(Filter.In(x => x.Status, status));
}
if (ids != null && ids.Count > 0) if (ids != null && ids.Count > 0)
{ {

49
src/Squidex.Domain.Apps.Entities/Contents/ContentQueryService.cs

@ -33,10 +33,7 @@ namespace Squidex.Domain.Apps.Entities.Contents
{ {
public sealed class ContentQueryService : IContentQueryService public sealed class ContentQueryService : IContentQueryService
{ {
private static readonly Status[] StatusAll = { Status.Archived, Status.Draft, Status.Published };
private static readonly Status[] StatusArchived = { Status.Archived };
private static readonly Status[] StatusPublishedOnly = { Status.Published }; private static readonly Status[] StatusPublishedOnly = { Status.Published };
private static readonly Status[] StatusPublishedDraft = { Status.Published, Status.Draft };
private readonly IContentRepository contentRepository; private readonly IContentRepository contentRepository;
private readonly IContentVersionLoader contentVersionLoader; private readonly IContentVersionLoader contentVersionLoader;
private readonly IAppProvider appProvider; private readonly IAppProvider appProvider;
@ -93,7 +90,7 @@ namespace Squidex.Domain.Apps.Entities.Contents
{ {
var isVersioned = version > EtagVersion.Empty; var isVersioned = version > EtagVersion.Empty;
var status = GetFindStatus(context); var status = GetStatus(context);
var content = var content =
isVersioned ? isVersioned ?
@ -119,7 +116,7 @@ namespace Squidex.Domain.Apps.Entities.Contents
using (Profiler.TraceMethod<ContentQueryService>()) using (Profiler.TraceMethod<ContentQueryService>())
{ {
var status = GetQueryStatus(context); var status = GetStatus(context);
IResultList<IContentEntity> contents; IResultList<IContentEntity> contents;
@ -145,7 +142,7 @@ namespace Squidex.Domain.Apps.Entities.Contents
using (Profiler.TraceMethod<ContentQueryService>()) using (Profiler.TraceMethod<ContentQueryService>())
{ {
var status = GetQueryStatus(context); var status = GetStatus(context);
List<IContentEntity> result; List<IContentEntity> result;
@ -217,7 +214,7 @@ namespace Squidex.Domain.Apps.Entities.Contents
result.Data = result.Data.ConvertName2Name(schema.SchemaDef, converters); result.Data = result.Data.ConvertName2Name(schema.SchemaDef, converters);
} }
if (result.DataDraft != null && (context.ApiStatus == StatusForApi.PublishedDraft || context.IsFrontendClient)) if (result.DataDraft != null && (context.ApiStatus == StatusForApi.All || context.IsFrontendClient))
{ {
result.DataDraft = result.DataDraft.ConvertName2Name(schema.SchemaDef, converters); result.DataDraft = result.DataDraft.ConvertName2Name(schema.SchemaDef, converters);
} }
@ -340,15 +337,11 @@ namespace Squidex.Domain.Apps.Entities.Contents
return permissions.Allows(permission); return permissions.Allows(permission);
} }
private static Status[] GetFindStatus(QueryContext context) private static Status[] GetStatus(QueryContext context)
{ {
if (context.IsFrontendClient) if (context.IsFrontendClient || context.ApiStatus == StatusForApi.All)
{ {
return StatusAll; return null;
}
else if (context.ApiStatus == StatusForApi.PublishedDraft)
{
return StatusPublishedDraft;
} }
else else
{ {
@ -356,32 +349,6 @@ namespace Squidex.Domain.Apps.Entities.Contents
} }
} }
private static Status[] GetQueryStatus(QueryContext context)
{
if (context.IsFrontendClient)
{
switch (context.FrontendStatus)
{
case StatusForFrontend.Archived:
return StatusArchived;
case StatusForFrontend.PublishedOnly:
return StatusPublishedOnly;
default:
return StatusPublishedDraft;
}
}
else
{
switch (context.ApiStatus)
{
case StatusForApi.PublishedDraft:
return StatusPublishedDraft;
default:
return StatusPublishedOnly;
}
}
}
private Task<List<(IContentEntity Content, ISchemaEntity Schema)>> QueryAsync(QueryContext context, IReadOnlyList<Guid> ids, Status[] status) private Task<List<(IContentEntity Content, ISchemaEntity Schema)>> QueryAsync(QueryContext context, IReadOnlyList<Guid> ids, Status[] status)
{ {
return contentRepository.QueryAsync(context.App, status, new HashSet<Guid>(ids), ShouldIncludeDraft(context)); return contentRepository.QueryAsync(context.App, status, new HashSet<Guid>(ids), ShouldIncludeDraft(context));
@ -409,7 +376,7 @@ namespace Squidex.Domain.Apps.Entities.Contents
private static bool ShouldIncludeDraft(QueryContext context) private static bool ShouldIncludeDraft(QueryContext context)
{ {
return context.ApiStatus == StatusForApi.PublishedDraft || context.IsFrontendClient; return context.ApiStatus == StatusForApi.All || context.IsFrontendClient;
} }
} }
} }

2
src/Squidex.Domain.Apps.Entities/Contents/StatusForApi.cs

@ -10,6 +10,6 @@ namespace Squidex.Domain.Apps.Entities.Contents
public enum StatusForApi public enum StatusForApi
{ {
PublishedOnly, PublishedOnly,
PublishedDraft, All,
} }
} }

16
src/Squidex.Domain.Apps.Entities/Contents/StatusForFrontend.cs

@ -1,16 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
namespace Squidex.Domain.Apps.Entities.Contents
{
public enum StatusForFrontend
{
PublishedDraft,
PublishedOnly,
Archived
}
}

19
src/Squidex.Domain.Apps.Entities/QueryContext.cs

@ -27,8 +27,6 @@ namespace Squidex.Domain.Apps.Entities
public StatusForApi ApiStatus { get; private set; } public StatusForApi ApiStatus { get; private set; }
public StatusForFrontend FrontendStatus { get; private set; }
public IReadOnlyCollection<string> AssetUrlsToResolve { get; private set; } public IReadOnlyCollection<string> AssetUrlsToResolve { get; private set; }
public IReadOnlyCollection<Language> Languages { get; private set; } public IReadOnlyCollection<Language> Languages { get; private set; }
@ -49,7 +47,7 @@ namespace Squidex.Domain.Apps.Entities
public QueryContext WithUnpublished(bool unpublished) public QueryContext WithUnpublished(bool unpublished)
{ {
return WithApiStatus(unpublished ? StatusForApi.PublishedDraft : StatusForApi.PublishedOnly); return WithApiStatus(unpublished ? StatusForApi.All : StatusForApi.PublishedOnly);
} }
public QueryContext WithApiStatus(StatusForApi status) public QueryContext WithApiStatus(StatusForApi status)
@ -57,21 +55,6 @@ namespace Squidex.Domain.Apps.Entities
return Clone(c => c.ApiStatus = status); return Clone(c => c.ApiStatus = status);
} }
public QueryContext WithFrontendStatus(StatusForFrontend status)
{
return Clone(c => c.FrontendStatus = status);
}
public QueryContext WithFrontendStatus(string status)
{
if (status != null && Enum.TryParse<StatusForFrontend>(status, out var result))
{
return WithFrontendStatus(result);
}
return this;
}
public QueryContext WithAssetUrlsToResolve(IEnumerable<string> fieldNames) public QueryContext WithAssetUrlsToResolve(IEnumerable<string> fieldNames)
{ {
if (fieldNames != null) if (fieldNames != null)

76
tests/Squidex.Domain.Apps.Entities.Tests/Contents/ContentQueryServiceTests.cs

@ -54,6 +54,12 @@ namespace Squidex.Domain.Apps.Entities.Contents
private readonly QueryContext context; private readonly QueryContext context;
private readonly ContentQueryService sut; private readonly ContentQueryService sut;
public static IEnumerable<object[]> ApiStatusTests = new[]
{
new object[] { StatusForApi.PublishedOnly, 0, new[] { Status.Published } },
new object[] { StatusForApi.All, 1, null }
};
public ContentQueryServiceTests() public ContentQueryServiceTests()
{ {
user = new ClaimsPrincipal(identity); user = new ClaimsPrincipal(identity);
@ -187,31 +193,17 @@ namespace Squidex.Domain.Apps.Entities.Contents
await Assert.ThrowsAsync<DomainObjectNotFoundException>(async () => await sut.FindContentAsync(ctx, schemaId.Name, contentId)); await Assert.ThrowsAsync<DomainObjectNotFoundException>(async () => await sut.FindContentAsync(ctx, schemaId.Name, contentId));
} }
public static IEnumerable<object[]> SingleDataFrontend = new[] [Fact]
{ public async Task Should_return_single_content_for_frontend_without_transform()
new object[] { StatusForFrontend.PublishedOnly, new[] { Status.Archived, Status.Draft, Status.Published } },
new object[] { StatusForFrontend.PublishedDraft, new[] { Status.Archived, Status.Draft, Status.Published } },
new object[] { StatusForFrontend.Archived, new[] { Status.Archived, Status.Draft, Status.Published } },
};
public static IEnumerable<object[]> SingleDataApi = new[]
{
new object[] { StatusForApi.PublishedOnly, 0, new[] { Status.Published } },
new object[] { StatusForApi.PublishedDraft, 1, new[] { Status.Published, Status.Draft } }
};
[Theory]
[MemberData(nameof(SingleDataFrontend))]
public async Task Should_return_single_content_for_frontend_without_transform(StatusForFrontend request, Status[] status)
{ {
var content = CreateContent(contentId); var content = CreateContent(contentId);
SetupClaims(isFrontend: true); SetupClaims(isFrontend: true);
SetupSchemaFound(); SetupSchemaFound();
SetupScripting(contentId); SetupScripting(contentId);
SetupContent(status, content, includeDraft: true); SetupContent(null, content, includeDraft: true);
var ctx = context.WithFrontendStatus(request); var ctx = context;
var result = await sut.FindContentAsync(ctx, schemaId.Name, contentId); var result = await sut.FindContentAsync(ctx, schemaId.Name, contentId);
@ -223,7 +215,7 @@ namespace Squidex.Domain.Apps.Entities.Contents
} }
[Theory] [Theory]
[MemberData(nameof(SingleDataApi))] [MemberData(nameof(ApiStatusTests))]
public async Task Should_return_single_content_for_api_with_transform(StatusForApi request, int includeDraft, Status[] status) public async Task Should_return_single_content_for_api_with_transform(StatusForApi request, int includeDraft, Status[] status)
{ {
var content = CreateContent(contentId); var content = CreateContent(contentId);
@ -275,9 +267,8 @@ namespace Squidex.Domain.Apps.Entities.Contents
await Assert.ThrowsAsync<DomainForbiddenException>(() => sut.QueryAsync(ctx, schemaId.Name, Q.Empty)); await Assert.ThrowsAsync<DomainForbiddenException>(() => sut.QueryAsync(ctx, schemaId.Name, Q.Empty));
} }
[Theory] [Fact]
[MemberData(nameof(ManyDataFrontend))] public async Task Should_query_contents_by_query_for_frontend_without_transform()
public async Task Should_query_contents_by_query_for_frontend_without_transform(StatusForFrontend request, Status[] status)
{ {
const int count = 5, total = 200; const int count = 5, total = 200;
@ -286,9 +277,9 @@ namespace Squidex.Domain.Apps.Entities.Contents
SetupClaims(isFrontend: true); SetupClaims(isFrontend: true);
SetupSchemaFound(); SetupSchemaFound();
SetupScripting(contentId); SetupScripting(contentId);
SetupContents(status, count, total, content, inDraft: true, includeDraft: true); SetupContents(null, count, total, content, inDraft: true, includeDraft: true);
var ctx = context.WithFrontendStatus(request); var ctx = context;
var result = await sut.QueryAsync(ctx, schemaId.Name, Q.Empty); var result = await sut.QueryAsync(ctx, schemaId.Name, Q.Empty);
@ -302,7 +293,7 @@ namespace Squidex.Domain.Apps.Entities.Contents
} }
[Theory] [Theory]
[MemberData(nameof(ManyDataApi))] [MemberData(nameof(ApiStatusTests))]
public async Task Should_query_contents_by_query_for_api_and_transform(StatusForApi request, int includeDraft, Status[] status) public async Task Should_query_contents_by_query_for_api_and_transform(StatusForApi request, int includeDraft, Status[] status)
{ {
const int count = 5, total = 200; const int count = 5, total = 200;
@ -338,22 +329,8 @@ namespace Squidex.Domain.Apps.Entities.Contents
await Assert.ThrowsAsync<ValidationException>(() => sut.QueryAsync(context, schemaId.Name, query)); await Assert.ThrowsAsync<ValidationException>(() => sut.QueryAsync(context, schemaId.Name, query));
} }
public static IEnumerable<object[]> ManyDataFrontend = new[] [Fact]
{ public async Task Should_query_contents_by_id_for_frontend_and_transform()
new object[] { StatusForFrontend.PublishedOnly, new[] { Status.Published } },
new object[] { StatusForFrontend.PublishedDraft, new[] { Status.Published, Status.Draft } },
new object[] { StatusForFrontend.Archived, new[] { Status.Archived } }
};
public static IEnumerable<object[]> ManyDataApi = new[]
{
new object[] { StatusForApi.PublishedOnly, 0, new[] { Status.Published } },
new object[] { StatusForApi.PublishedDraft, 1, new[] { Status.Published, Status.Draft } }
};
[Theory]
[MemberData(nameof(ManyDataFrontend))]
public async Task Should_query_contents_by_id_for_frontend_and_transform(StatusForFrontend request, Status[] status)
{ {
const int count = 5, total = 200; const int count = 5, total = 200;
@ -362,9 +339,9 @@ namespace Squidex.Domain.Apps.Entities.Contents
SetupClaims(isFrontend: true); SetupClaims(isFrontend: true);
SetupSchemaFound(); SetupSchemaFound();
SetupScripting(ids.ToArray()); SetupScripting(ids.ToArray());
SetupContents(status, total, ids, includeDraft: true); SetupContents(null, total, ids, includeDraft: true);
var ctx = context.WithFrontendStatus(request); var ctx = context;
var result = await sut.QueryAsync(ctx, schemaId.Name, Q.Empty.WithIds(ids)); var result = await sut.QueryAsync(ctx, schemaId.Name, Q.Empty.WithIds(ids));
@ -376,7 +353,7 @@ namespace Squidex.Domain.Apps.Entities.Contents
} }
[Theory] [Theory]
[MemberData(nameof(ManyDataApi))] [MemberData(nameof(ApiStatusTests))]
public async Task Should_query_contents_by_id_for_api_and_transform(StatusForApi request, int includeDraft, Status[] status) public async Task Should_query_contents_by_id_for_api_and_transform(StatusForApi request, int includeDraft, Status[] status)
{ {
const int count = 5, total = 200; const int count = 5, total = 200;
@ -399,9 +376,8 @@ namespace Squidex.Domain.Apps.Entities.Contents
.MustHaveHappened(count, Times.Exactly); .MustHaveHappened(count, Times.Exactly);
} }
[Theory] [Fact]
[MemberData(nameof(ManyDataFrontend))] public async Task Should_query_all_contents_by_id_for_frontend_and_transform()
public async Task Should_query_all_contents_by_id_for_frontend_and_transform(StatusForFrontend request, Status[] status)
{ {
const int count = 5; const int count = 5;
@ -410,9 +386,9 @@ namespace Squidex.Domain.Apps.Entities.Contents
SetupClaims(isFrontend: true); SetupClaims(isFrontend: true);
SetupSchemaFound(); SetupSchemaFound();
SetupScripting(ids.ToArray()); SetupScripting(ids.ToArray());
SetupContents(status, ids, includeDraft: true); SetupContents(null, ids, includeDraft: true);
var ctx = context.WithFrontendStatus(request); var ctx = context;
var result = await sut.QueryAsync(ctx, ids); var result = await sut.QueryAsync(ctx, ids);
@ -423,7 +399,7 @@ namespace Squidex.Domain.Apps.Entities.Contents
} }
[Theory] [Theory]
[MemberData(nameof(ManyDataApi))] [MemberData(nameof(ApiStatusTests))]
public async Task Should_query_all_contents_by_id_for_api_and_transform(StatusForApi request, int includeDraft, Status[] status) public async Task Should_query_all_contents_by_id_for_api_and_transform(StatusForApi request, int includeDraft, Status[] status)
{ {
const int count = 5; const int count = 5;

5
tests/Squidex.Domain.Apps.Entities.Tests/TestHelpers/AExtensions.cs

@ -19,6 +19,11 @@ namespace Squidex.Domain.Apps.Entities.TestHelpers
public static T[] Is<T>(this INegatableArgumentConstraintManager<T[]> that, params T[] values) public static T[] Is<T>(this INegatableArgumentConstraintManager<T[]> that, params T[] values)
{ {
if (values == null)
{
return that.IsNull();
}
return that.IsSameSequenceAs(values); return that.IsSameSequenceAs(values);
} }
} }

Loading…
Cancel
Save