Browse Source

API hopefully finalized.

pull/297/head
Sebastian 8 years ago
parent
commit
0e6c97faef
  1. 2
      src/Squidex.Domain.Apps.Core.Operations/ValidateContent/ContentValidator.cs
  2. 4
      src/Squidex.Domain.Apps.Entities/Apps/AppGrain.cs
  3. 6
      src/Squidex.Domain.Apps.Entities/Apps/Templates/CreateBlogCommandMiddleware.cs
  4. 14
      src/Squidex.Domain.Apps.Entities/Apps/Templates/CreateProfileCommandMiddleware.cs
  5. 2
      src/Squidex.Domain.Apps.Entities/Schemas/Commands/CreateSchemaField.cs
  6. 2
      src/Squidex.Domain.Apps.Entities/Schemas/Commands/CreateSchemaNestedField.cs
  7. 1
      src/Squidex.Domain.Apps.Entities/Schemas/Guards/FieldPropertiesValidator.cs
  8. 37
      src/Squidex.Domain.Apps.Entities/Schemas/Guards/GuardSchema.cs
  9. 1
      src/Squidex.Domain.Apps.Entities/Schemas/Guards/GuardSchemaField.cs
  10. 80
      src/Squidex.Domain.Apps.Entities/Schemas/SchemaGrain.cs
  11. 2
      src/Squidex.Domain.Apps.Entities/Schemas/State/SchemaState.cs
  12. 2
      src/Squidex.Domain.Apps.Events/Schemas/SchemaFieldsReordered.cs
  13. 2
      src/Squidex.Infrastructure/Json/NamedStringIdConverter.cs
  14. 61
      src/Squidex.Infrastructure/NamedId.cs
  15. 70
      src/Squidex.Infrastructure/NamedId{T}.cs
  16. 6
      src/Squidex.Infrastructure/ValidationError.cs
  17. 4
      src/Squidex/Areas/Api/Controllers/Schemas/Models/AddFieldDto.cs
  18. 8
      src/Squidex/Areas/Api/Controllers/Schemas/Models/Converters/FieldPropertiesDtoFactory.cs
  19. 17
      src/Squidex/Areas/Api/Controllers/Schemas/Models/CreateSchemaDto.cs
  20. 6
      src/Squidex/Areas/Api/Controllers/Schemas/Models/CreateSchemaFieldDto.cs
  21. 37
      src/Squidex/Areas/Api/Controllers/Schemas/Models/CreateSchemaNestedFieldDto.cs
  22. 6
      src/Squidex/Areas/Api/Controllers/Schemas/Models/FieldDto.cs
  23. 34
      src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ArrayFieldPropertiesDto.cs
  24. 42
      src/Squidex/Areas/Api/Controllers/Schemas/Models/NestedFieldDto.cs
  25. 4
      src/Squidex/Areas/Api/Controllers/Schemas/Models/ReorderFieldsDto.cs
  26. 23
      src/Squidex/Areas/Api/Controllers/Schemas/Models/SchemaDetailsDto.cs
  27. 4
      src/Squidex/Areas/Api/Controllers/Schemas/Models/UpdateFieldDto.cs
  28. 221
      src/Squidex/Areas/Api/Controllers/Schemas/SchemaFieldsController.cs
  29. 2
      src/Squidex/Pipeline/CommandMiddlewares/EnrichWithAppIdCommandMiddleware.cs
  30. 4
      src/Squidex/Pipeline/CommandMiddlewares/EnrichWithSchemaIdCommandMiddleware.cs
  31. 4
      tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleEventFormatterTests.cs
  32. 4
      tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleServiceTests.cs
  33. 4
      tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/Triggers/ContentChangedTriggerTests.cs
  34. 1
      tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ArrayFieldTests.cs
  35. 1
      tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/TagsFieldTests.cs
  36. 9
      tests/Squidex.Domain.Apps.Core.Tests/TestData.cs
  37. 2
      tests/Squidex.Domain.Apps.Entities.Tests/Rules/Guards/GuardRuleTests.cs
  38. 4
      tests/Squidex.Domain.Apps.Entities.Tests/Rules/Indexes/RulesByAppIndexCommandMiddlewareTests.cs
  39. 2
      tests/Squidex.Domain.Apps.Entities.Tests/Rules/RuleEnqueuerTests.cs
  40. 26
      tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/GuardSchemaTests.cs
  41. 4
      tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Indexes/SchemasByAppIndexCommandMiddlewareTests.cs
  42. 289
      tests/Squidex.Domain.Apps.Entities.Tests/Schemas/SchemaGrainTests.cs
  43. 4
      tests/Squidex.Domain.Apps.Entities.Tests/TestHelpers/HandlerTestBase.cs
  44. 34
      tests/Squidex.Infrastructure.Tests/NamedIdTests.cs
  45. 6
      tests/Squidex.Tests/Pipeline/CommandMiddlewares/EnrichWithAppIdCommandMiddlewareTests.cs
  46. 12
      tests/Squidex.Tests/Pipeline/CommandMiddlewares/EnrichWithSchemaIdCommandMiddlewareTests.cs

2
src/Squidex.Domain.Apps.Core.Operations/ValidateContent/ContentValidator.cs

@ -5,11 +5,9 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Contents;

4
src/Squidex.Domain.Apps.Entities/Apps/AppGrain.cs

@ -200,7 +200,7 @@ namespace Squidex.Domain.Apps.Entities.Apps
public void Create(CreateApp command)
{
var appId = new NamedId<Guid>(command.AppId, command.Name);
var appId = NamedId.Of(command.AppId, command.Name);
var events = new List<AppEvent>
{
@ -308,7 +308,7 @@ namespace Squidex.Domain.Apps.Entities.Apps
{
if (@event.AppId == null)
{
@event.AppId = new NamedId<Guid>(Snapshot.Id, Snapshot.Name);
@event.AppId = NamedId.Of(Snapshot.Id, Snapshot.Name);
}
RaiseEvent(Envelope.Create(@event));

6
src/Squidex.Domain.Apps.Entities/Apps/Templates/CreateBlogCommandMiddleware.cs

@ -32,7 +32,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Templates
{
if (context.IsCompleted && context.Command is CreateApp createApp && IsRightTemplate(createApp))
{
var appId = new NamedId<Guid>(createApp.AppId, createApp.Name);
var appId = NamedId.Of(createApp.AppId, createApp.Name);
var publish = new Func<ICommand, Task>(command =>
{
@ -156,7 +156,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Templates
await publish(command);
var schemaId = new NamedId<Guid>(command.SchemaId, command.Name);
var schemaId = NamedId.Of(command.SchemaId, command.Name);
await publish(new ConfigureScripts
{
@ -222,7 +222,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Templates
await publish(command);
var schemaId = new NamedId<Guid>(command.SchemaId, command.Name);
var schemaId = NamedId.Of(command.SchemaId, command.Name);
await publish(new ConfigureScripts
{

14
src/Squidex.Domain.Apps.Entities/Apps/Templates/CreateProfileCommandMiddleware.cs

@ -27,7 +27,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Templates
{
if (context.IsCompleted && context.Command is CreateApp createApp && IsRightTemplate(createApp))
{
var appId = new NamedId<Guid>(createApp.AppId, createApp.Name);
var appId = NamedId.Of(createApp.AppId, createApp.Name);
var publish = new Func<ICommand, Task>(command =>
{
@ -233,7 +233,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Templates
await publish(command);
return new NamedId<Guid>(command.SchemaId, command.Name);
return NamedId.Of(command.SchemaId, command.Name);
}
private async Task<NamedId<Guid>> CreateProjectsSchemaAsync(Func<ICommand, Task> publish)
@ -324,7 +324,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Templates
await publish(command);
return new NamedId<Guid>(command.SchemaId, command.Name);
return NamedId.Of(command.SchemaId, command.Name);
}
private async Task<NamedId<Guid>> CreateExperienceSchemaAsync(Func<ICommand, Task> publish)
@ -404,7 +404,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Templates
await publish(command);
return new NamedId<Guid>(command.SchemaId, command.Name);
return NamedId.Of(command.SchemaId, command.Name);
}
private async Task<NamedId<Guid>> CreateEducationSchemaAsync(Func<ICommand, Task> publish)
@ -484,7 +484,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Templates
await publish(command);
return new NamedId<Guid>(command.SchemaId, command.Name);
return NamedId.Of(command.SchemaId, command.Name);
}
private async Task<NamedId<Guid>> CreatePublicationsSchemaAsync(Func<ICommand, Task> publish)
@ -552,7 +552,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Templates
await publish(command);
return new NamedId<Guid>(command.SchemaId, command.Name);
return NamedId.Of(command.SchemaId, command.Name);
}
private async Task<NamedId<Guid>> CreateSkillsSchemaAsync(Func<ICommand, Task> publish)
@ -597,7 +597,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Templates
await publish(command);
return new NamedId<Guid>(command.SchemaId, command.Name);
return NamedId.Of(command.SchemaId, command.Name);
}
}
}

2
src/Squidex.Domain.Apps.Entities/Schemas/Commands/CreateSchemaField.cs

@ -6,7 +6,7 @@
// ==========================================================================
using Squidex.Domain.Apps.Core.Schemas;
using FieldNested = System.Collections.Generic.List<Squidex.Domain.Apps.Entities.Schemas.Commands.CreateNestedSchemaField>;
using FieldNested = System.Collections.Generic.List<Squidex.Domain.Apps.Entities.Schemas.Commands.CreateSchemaNestedField>;
namespace Squidex.Domain.Apps.Entities.Schemas.Commands
{

2
src/Squidex.Domain.Apps.Entities/Schemas/Commands/CreateNestedSchemaField.cs → src/Squidex.Domain.Apps.Entities/Schemas/Commands/CreateSchemaNestedField.cs

@ -9,7 +9,7 @@ using Squidex.Domain.Apps.Core.Schemas;
namespace Squidex.Domain.Apps.Entities.Schemas.Commands
{
public sealed class CreateNestedSchemaField
public sealed class CreateSchemaNestedField
{
public string Name { get; set; }

1
src/Squidex.Domain.Apps.Entities/Schemas/Guards/FieldPropertiesValidator.cs

@ -6,7 +6,6 @@
// ==========================================================================
using System.Collections.Generic;
using System.Linq;
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure;

37
src/Squidex.Domain.Apps.Entities/Schemas/Guards/GuardSchema.cs

@ -5,6 +5,8 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Squidex.Domain.Apps.Core;
@ -20,7 +22,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards
{
Guard.NotNull(command, nameof(command));
return Validate.It(() => "Cannot create schema.", (System.Func<System.Action<ValidationError>, Task>)(async (System.Action<ValidationError> error) =>
return Validate.It(() => "Cannot create schema.", async error =>
{
if (!command.Name.IsSlug())
{
@ -115,16 +117,27 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards
error(new ValidationError("Fields cannot have duplicate names.", nameof(command.Fields)));
}
}
}));
});
}
public static void CanReorder(Schema schema, ReorderFields command)
{
Guard.NotNull(command, nameof(command));
if (command.ParentFieldId.HasValue && !schema.FieldsById.ContainsKey(command.ParentFieldId.Value))
IArrayField arrayField = null;
if (command.ParentFieldId.HasValue)
{
throw new DomainObjectNotFoundException(command.ParentFieldId.ToString(), "Fields", typeof(Schema));
var parentId = command.ParentFieldId.Value;
if (schema.FieldsById.TryGetValue(parentId, out var field) && field is IArrayField a)
{
arrayField = a;
}
else
{
throw new DomainObjectNotFoundException(parentId.ToString(), "Fields", typeof(Schema));
}
}
Validate.It(() => "Cannot reorder schema fields.", error =>
@ -134,13 +147,25 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards
error(new ValidationError("Field ids is required.", nameof(command.FieldIds)));
}
if (command.FieldIds != null && (command.FieldIds.Count != schema.Fields.Count || command.FieldIds.Any(x => !schema.FieldsById.ContainsKey(x))))
if (arrayField == null)
{
error(new ValidationError("Ids must cover all fields.", nameof(command.FieldIds)));
CheckFields(error, command, schema.FieldsById);
}
else
{
CheckFields(error, command, arrayField.FieldsById);
}
});
}
private static void CheckFields<T>(Action<ValidationError> error, ReorderFields c, IReadOnlyDictionary<long, T> fields)
{
if (c.FieldIds != null && (c.FieldIds.Count != fields.Count || c.FieldIds.Any(x => !fields.ContainsKey(x))))
{
error(new ValidationError("Ids must cover all fields.", nameof(c.FieldIds)));
}
}
public static void CanPublish(Schema schema, PublishSchema command)
{
Guard.NotNull(command, nameof(command));

1
src/Squidex.Domain.Apps.Entities/Schemas/Guards/GuardSchemaField.cs

@ -5,7 +5,6 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Linq;
using Squidex.Domain.Apps.Core;
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Entities.Schemas.Commands;

80
src/Squidex.Domain.Apps.Entities/Schemas/SchemaGrain.cs

@ -47,14 +47,6 @@ namespace Squidex.Domain.Apps.Entities.Schemas
switch (command)
{
case CreateSchema createSchema:
return CreateAsync(createSchema, async c =>
{
await GuardSchema.CanCreate(c, appProvider);
Create(c);
});
case AddField addField:
return UpdateReturnAsync(addField, c =>
{
@ -62,7 +54,26 @@ namespace Squidex.Domain.Apps.Entities.Schemas
Add(c);
return EntityCreatedResult.Create(Snapshot.SchemaDef.FieldsById.Values.First(x => x.Name == addField.Name).Id, NewVersion);
var id = 0L;
if (c.ParentFieldId == null)
{
id = Snapshot.SchemaDef.FieldsByName[c.Name].Id;
}
else
{
id = ((IArrayField)Snapshot.SchemaDef.FieldsById[c.ParentFieldId.Value]).FieldsByName[c.Name].Id;
}
return EntityCreatedResult.Create(id, NewVersion);
});
case CreateSchema createSchema:
return CreateAsync(createSchema, async c =>
{
await GuardSchema.CanCreate(c, appProvider);
Create(c);
});
case DeleteField deleteField:
@ -184,7 +195,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas
public void Create(CreateSchema command)
{
var @event = SimpleMapper.Map(command, new SchemaCreated { SchemaId = new NamedId<Guid>(command.SchemaId, command.Name) });
var @event = SimpleMapper.Map(command, new SchemaCreated { SchemaId = NamedId.Of(command.SchemaId, command.Name) });
if (command.Fields != null)
{
@ -195,6 +206,18 @@ namespace Squidex.Domain.Apps.Entities.Schemas
var eventField = SimpleMapper.Map(commandField, new SchemaCreatedField());
@event.Fields.Add(eventField);
if (commandField.Nested != null)
{
eventField.Nested = new List<SchemaCreatedNestedField>();
foreach (var nestedField in commandField.Nested)
{
var eventNestedField = SimpleMapper.Map(nestedField, new SchemaCreatedNestedField());
eventField.Nested.Add(eventNestedField);
}
}
}
}
@ -203,7 +226,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas
public void Add(AddField command)
{
RaiseEvent(SimpleMapper.Map(command, new FieldAdded { FieldId = new NamedId<long>(Snapshot.TotalFields + 1, command.Name) }));
RaiseEvent(SimpleMapper.Map(command, new FieldAdded { ParentFieldId = GetFieldId(command.ParentFieldId), FieldId = CreateFieldId(command) }));
}
public void UpdateField(UpdateField command)
@ -243,7 +266,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas
public void Reorder(ReorderFields command)
{
RaiseEvent(SimpleMapper.Map(command, new SchemaFieldsReordered()));
RaiseEvent(SimpleMapper.Map(command, new SchemaFieldsReordered { ParentFieldId = GetFieldId(command.ParentFieldId) }));
}
public void Publish(PublishSchema command)
@ -280,19 +303,46 @@ namespace Squidex.Domain.Apps.Entities.Schemas
{
SimpleMapper.Map(fieldCommand, @event);
if (Snapshot.SchemaDef.FieldsById.TryGetValue(fieldCommand.FieldId, out var field))
if (fieldCommand.ParentFieldId.HasValue)
{
if (Snapshot.SchemaDef.FieldsById.TryGetValue(fieldCommand.ParentFieldId.Value, out var field))
{
@event.ParentFieldId = NamedId.Of(field.Id, field.Name);
if (field is IArrayField arrayField && arrayField.FieldsById.TryGetValue(fieldCommand.FieldId, out var nestedField))
{
@event.FieldId = NamedId.Of(nestedField.Id, nestedField.Name);
}
}
}
else
{
@event.FieldId = new NamedId<long>(field.Id, field.Name);
@event.FieldId = GetFieldId(fieldCommand.FieldId);
}
RaiseEvent(@event);
}
private NamedId<long> CreateFieldId(AddField command)
{
return NamedId.Of(Snapshot.TotalFields + 1L, command.Name);
}
private NamedId<long> GetFieldId(long? id)
{
if (id.HasValue && Snapshot.SchemaDef.FieldsById.TryGetValue(id.Value, out var field))
{
return NamedId.Of(field.Id, field.Name);
}
return null;
}
private void RaiseEvent(SchemaEvent @event)
{
if (@event.SchemaId == null)
{
@event.SchemaId = new NamedId<Guid>(Snapshot.Id, Snapshot.Name);
@event.SchemaId = NamedId.Of(Snapshot.Id, Snapshot.Name);
}
if (@event.AppId == null)

2
src/Squidex.Domain.Apps.Entities/Schemas/State/SchemaState.cs

@ -178,7 +178,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.State
protected void On(SchemaFieldsReordered @event, FieldRegistry registry)
{
SchemaDef = SchemaDef.ReorderFields(@event.FieldIds, @event.ParentFieldIdId?.Id);
SchemaDef = SchemaDef.ReorderFields(@event.FieldIds, @event.ParentFieldId?.Id);
}
protected void On(FieldUpdated @event, FieldRegistry registry)

2
src/Squidex.Domain.Apps.Events/Schemas/SchemaFieldsReordered.cs

@ -14,7 +14,7 @@ namespace Squidex.Domain.Apps.Events.Schemas
[EventType(nameof(SchemaFieldsReordered))]
public sealed class SchemaFieldsReordered : SchemaEvent
{
public NamedId<long> ParentFieldIdId { get; set; }
public NamedId<long> ParentFieldId { get; set; }
public List<long> FieldIds { get; set; }
}

2
src/Squidex.Infrastructure/Json/NamedStringIdConverter.cs

@ -32,7 +32,7 @@ namespace Squidex.Infrastructure.Json
throw new JsonException("Named id must have more than 2 parts divided by colon.");
}
return new NamedId<string>(parts[0], string.Join(",", parts.Skip(1)));
return NamedId.Of(parts[0], string.Join(",", parts.Skip(1)));
}
}
}

61
src/Squidex.Infrastructure/NamedId.cs

@ -1,70 +1,17 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt)
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Linq;
namespace Squidex.Infrastructure
{
public delegate bool Parser<T>(string input, out T result);
public sealed class NamedId<T> : IEquatable<NamedId<T>>
public static class NamedId
{
public T Id { get; }
public string Name { get; }
public NamedId(T id, string name)
public static NamedId<T> Of<T>(T id, string name)
{
Guard.NotNull(id, nameof(id));
Guard.NotNull(name, nameof(name));
Id = id;
Name = name;
}
public override string ToString()
{
return $"{Id},{Name}";
}
public override bool Equals(object obj)
{
return Equals(obj as NamedId<T>);
}
public bool Equals(NamedId<T> other)
{
return other != null && (ReferenceEquals(this, other) || (Id.Equals(other.Id) && Name.Equals(other.Name)));
}
public override int GetHashCode()
{
return (Id.GetHashCode() * 397) ^ Name.GetHashCode();
}
public static NamedId<T> Parse(string value, Parser<T> parser)
{
Guard.NotNull(value, nameof(value));
var parts = value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length < 2)
{
throw new ArgumentException("Named id must have more than 2 parts divided by commata.");
}
if (!parser(parts[0], out var id))
{
throw new ArgumentException("Named id must be a valid guid.");
}
return new NamedId<T>(id, string.Join(",", parts.Skip(1)));
return new NamedId<T>(id, name);
}
}
}

70
src/Squidex.Infrastructure/NamedId{T}.cs

@ -0,0 +1,70 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Linq;
namespace Squidex.Infrastructure
{
public delegate bool Parser<T>(string input, out T result);
public sealed class NamedId<T> : IEquatable<NamedId<T>>
{
public T Id { get; }
public string Name { get; }
public NamedId(T id, string name)
{
Guard.NotNull(id, nameof(id));
Guard.NotNull(name, nameof(name));
Id = id;
Name = name;
}
public override string ToString()
{
return $"{Id},{Name}";
}
public override bool Equals(object obj)
{
return Equals(obj as NamedId<T>);
}
public bool Equals(NamedId<T> other)
{
return other != null && (ReferenceEquals(this, other) || (Id.Equals(other.Id) && Name.Equals(other.Name)));
}
public override int GetHashCode()
{
return (Id.GetHashCode() * 397) ^ Name.GetHashCode();
}
public static NamedId<T> Parse(string value, Parser<T> parser)
{
Guard.NotNull(value, nameof(value));
var parts = value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length < 2)
{
throw new ArgumentException("Named id must have more than 2 parts divided by commata.");
}
if (!parser(parts[0], out var id))
{
throw new ArgumentException("Named id must be a valid guid.");
}
return new NamedId<T>(id, string.Join(",", parts.Skip(1)));
}
}
}

6
src/Squidex.Infrastructure/ValidationError.cs

@ -41,8 +41,10 @@ namespace Squidex.Infrastructure
{
return new ValidationError(Message, propertyNames.Select(x => $"{prefix}.{x}").ToArray());
}
return this;
else
{
return new ValidationError(Message, prefix);
}
}
}
}

4
src/Squidex/Areas/Api/Controllers/Schemas/Models/AddFieldDto.cs

@ -31,9 +31,9 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models
[Required]
public FieldPropertiesDto Properties { get; set; }
public AddField ToCommand()
public AddField ToCommand(long? parentId = null)
{
return SimpleMapper.Map(this, new AddField { Properties = Properties.ToProperties() });
return SimpleMapper.Map(this, new AddField { ParentFieldId = parentId, Properties = Properties.ToProperties() });
}
}
}

8
src/Squidex/Areas/Api/Controllers/Schemas/Models/Converters/FieldPropertiesDtoFactory.cs

@ -20,14 +20,14 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models.Converters
{
}
public FieldPropertiesDto Visit(ArrayFieldProperties properties)
public static FieldPropertiesDto Create(FieldProperties properties)
{
throw new System.NotImplementedException();
return properties.Accept(Instance);
}
public static FieldPropertiesDto Create(FieldProperties properties)
public FieldPropertiesDto Visit(ArrayFieldProperties properties)
{
return properties.Accept(Instance);
return SimpleMapper.Map(properties, new ArrayFieldPropertiesDto());
}
public FieldPropertiesDto Visit(BooleanFieldProperties properties)

17
src/Squidex/Areas/Api/Controllers/Schemas/Models/CreateSchemaDto.cs

@ -57,9 +57,22 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models
foreach (var fieldDto in Fields)
{
var fieldProperties = fieldDto?.Properties.ToProperties();
var fieldInstance = SimpleMapper.Map(fieldDto, new CreateSchemaField { Properties = fieldProperties });
var field = SimpleMapper.Map(fieldDto, new CreateSchemaField { Properties = fieldProperties });
command.Fields.Add(fieldInstance);
if (fieldDto.Nested != null)
{
field.Nested = new List<CreateSchemaNestedField>();
foreach (var nestedFieldDto in fieldDto.Nested)
{
var nestedFieldProperties = nestedFieldDto?.Properties.ToProperties();
var nestedField = SimpleMapper.Map(fieldDto, new CreateSchemaNestedField { Properties = fieldProperties });
field.Nested.Add(nestedField);
}
}
command.Fields.Add(field);
}
}

6
src/Squidex/Areas/Api/Controllers/Schemas/Models/CreateSchemaFieldDto.cs

@ -5,6 +5,7 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace Squidex.Areas.Api.Controllers.Schemas.Models
@ -43,5 +44,10 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models
/// </summary>
[Required]
public FieldPropertiesDto Properties { get; set; }
/// <summary>
/// The nested fields.
/// </summary>
public List<CreateSchemaNestedFieldDto> Nested { get; set; }
}
}

37
src/Squidex/Areas/Api/Controllers/Schemas/Models/CreateSchemaNestedFieldDto.cs

@ -0,0 +1,37 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.ComponentModel.DataAnnotations;
namespace Squidex.Areas.Api.Controllers.Schemas.Models
{
public sealed class CreateSchemaNestedFieldDto
{
/// <summary>
/// The name of the field. Must be unique within the schema.
/// </summary>
[Required]
[RegularExpression("^[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*$")]
public string Name { get; set; }
/// <summary>
/// Defines if the field is hidden.
/// </summary>
public bool IsHidden { get; set; }
/// <summary>
/// Defines if the field is disabled.
/// </summary>
public bool IsDisabled { get; set; }
/// <summary>
/// The field properties.
/// </summary>
[Required]
public FieldPropertiesDto Properties { get; set; }
}
}

6
src/Squidex/Areas/Api/Controllers/Schemas/Models/FieldDto.cs

@ -5,6 +5,7 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace Squidex.Areas.Api.Controllers.Schemas.Models
@ -49,5 +50,10 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models
/// </summary>
[Required]
public FieldPropertiesDto Properties { get; set; }
/// <summary>
/// The nested fields.
/// </summary>
public List<NestedFieldDto> Nested { get; set; }
}
}

34
src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ArrayFieldPropertiesDto.cs

@ -0,0 +1,34 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using NJsonSchema.Annotations;
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure.Reflection;
namespace Squidex.Areas.Api.Controllers.Schemas.Models.Fields
{
[JsonSchema("Array")]
public sealed class ArrayFieldPropertiesDto : FieldPropertiesDto
{
/// <summary>
/// The minimum allowed items for the field value.
/// </summary>
public int? MinItems { get; set; }
/// <summary>
/// The maximum allowed items for the field value.
/// </summary>
public int? MaxItems { get; set; }
public override FieldProperties ToProperties()
{
var result = SimpleMapper.Map(this, new ArrayFieldProperties());
return result;
}
}
}

42
src/Squidex/Areas/Api/Controllers/Schemas/Models/NestedFieldDto.cs

@ -0,0 +1,42 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.ComponentModel.DataAnnotations;
namespace Squidex.Areas.Api.Controllers.Schemas.Models
{
public sealed class NestedFieldDto
{
/// <summary>
/// The id of the field.
/// </summary>
public long FieldId { get; set; }
/// <summary>
/// The name of the field. Must be unique within the schema.
/// </summary>
[Required]
[RegularExpression("^[a-z0-9]+(\\-[a-z0-9]+)*$")]
public string Name { get; set; }
/// <summary>
/// Defines if the field is hidden.
/// </summary>
public bool IsHidden { get; set; }
/// <summary>
/// Defines if the field is disabled.
/// </summary>
public bool IsDisabled { get; set; }
/// <summary>
/// The field properties.
/// </summary>
[Required]
public FieldPropertiesDto Properties { get; set; }
}
}

4
src/Squidex/Areas/Api/Controllers/Schemas/Models/ReorderFieldsDto.cs

@ -19,9 +19,9 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models
[Required]
public List<long> FieldIds { get; set; }
public ReorderFields ToCommand()
public ReorderFields ToCommand(long? parentId = null)
{
return new ReorderFields { FieldIds = FieldIds };
return new ReorderFields { ParentFieldId = parentId, FieldIds = FieldIds };
}
}
}

23
src/Squidex/Areas/Api/Controllers/Schemas/Models/SchemaDetailsDto.cs

@ -10,6 +10,7 @@ using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using NodaTime;
using Squidex.Areas.Api.Controllers.Schemas.Models.Converters;
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Entities.Schemas;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Reflection;
@ -117,7 +118,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models
foreach (var field in schema.SchemaDef.Fields)
{
var fieldPropertiesDto = FieldPropertiesDtoFactory.Create(field.RawProperties);
var fieldInstanceDto = SimpleMapper.Map(field,
var fieldDto = SimpleMapper.Map(field,
new FieldDto
{
FieldId = field.Id,
@ -125,7 +126,25 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models
Partitioning = field.Partitioning.Key
});
response.Fields.Add(fieldInstanceDto);
if (field is IArrayField arrayField)
{
fieldDto.Nested = new List<NestedFieldDto>();
foreach (var nestedField in arrayField.Fields)
{
var nestedFieldPropertiesDto = FieldPropertiesDtoFactory.Create(nestedField.RawProperties);
var nestedFieldDto = SimpleMapper.Map(nestedField,
new NestedFieldDto
{
FieldId = nestedField.Id,
Properties = nestedFieldPropertiesDto,
});
fieldDto.Nested.Add(nestedFieldDto);
}
}
response.Fields.Add(fieldDto);
}
return response;

4
src/Squidex/Areas/Api/Controllers/Schemas/Models/UpdateFieldDto.cs

@ -18,9 +18,9 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models
[Required]
public FieldPropertiesDto Properties { get; set; }
public UpdateField ToCommand(long id)
public UpdateField ToCommand(long id, long? parentId = null)
{
return new UpdateField { FieldId = id, Properties = Properties?.ToProperties() };
return new UpdateField { ParentFieldId = parentId, FieldId = id, Properties = Properties?.ToProperties() };
}
}
}

221
src/Squidex/Areas/Api/Controllers/Schemas/SchemaFieldsController.cs

@ -58,6 +58,35 @@ namespace Squidex.Areas.Api.Controllers.Schemas
return StatusCode(201, response);
}
/// <summary>
/// Add a nested schema field.
/// </summary>
/// <param name="app">The name of the app.</param>
/// <param name="name">The name of the schema.</param>
/// <param name="parentId">The parent field id.</param>
/// <param name="request">The field object that needs to be added to the schema.</param>
/// <returns>
/// 201 => Schema field created.
/// 400 => Schema field properties not valid.
/// 409 => Schema field name already in use.
/// 404 => Field, schema or app not found.
/// </returns>
[HttpPost]
[Route("apps/{app}/schemas/{name}/fields/{parentId:long}/nested/")]
[ProducesResponseType(typeof(EntityCreatedDto), 201)]
[ProducesResponseType(typeof(ErrorDto), 409)]
[ProducesResponseType(typeof(ErrorDto), 400)]
[ApiCosts(1)]
public async Task<IActionResult> PostNestedField(string app, string name, long parentId, [FromBody] AddFieldDto request)
{
var context = await CommandBus.PublishAsync(request.ToCommand(parentId));
var result = context.Result<EntityCreatedResult<long>>();
var response = EntityCreatedDto.FromResult(result);
return StatusCode(201, response);
}
/// <summary>
/// Reorders the fields.
/// </summary>
@ -73,13 +102,36 @@ namespace Squidex.Areas.Api.Controllers.Schemas
[Route("apps/{app}/schemas/{name}/fields/ordering/")]
[ProducesResponseType(typeof(ErrorDto), 400)]
[ApiCosts(1)]
public async Task<IActionResult> PutFieldOrdering(string app, string name, [FromBody] ReorderFieldsDto request)
public async Task<IActionResult> PutSchemaFieldOrdering(string app, string name, [FromBody] ReorderFieldsDto request)
{
await CommandBus.PublishAsync(request.ToCommand());
return NoContent();
}
/// <summary>
/// Reorders the nested fields.
/// </summary>
/// <param name="app">The name of the app.</param>
/// <param name="name">The name of the schema.</param>
/// <param name="parentId">The parent field id.</param>
/// <param name="request">The request that contains the field ids.</param>
/// <returns>
/// 204 => Schema fields reorderd.
/// 400 => Schema field ids do not cover the fields of the schema.
/// 404 => Field, schema or app not found.
/// </returns>
[HttpPut]
[Route("apps/{app}/schemas/{name}/fields/{parentId:long}/ordering/")]
[ProducesResponseType(typeof(ErrorDto), 400)]
[ApiCosts(1)]
public async Task<IActionResult> PutNestedFieldOrdering(string app, string name, long parentId, [FromBody] ReorderFieldsDto request)
{
await CommandBus.PublishAsync(request.ToCommand(parentId));
return NoContent();
}
/// <summary>
/// Update a schema field.
/// </summary>
@ -90,7 +142,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
/// <returns>
/// 204 => Schema field updated.
/// 400 => Schema field properties not valid or field is locked.
/// 404 => Schema, field or app not found.
/// 404 => Field, schema or app not found.
/// </returns>
[HttpPut]
[Route("apps/{app}/schemas/{name}/fields/{id:long}/")]
@ -104,6 +156,31 @@ namespace Squidex.Areas.Api.Controllers.Schemas
return NoContent();
}
/// <summary>
/// Update a nested schema field.
/// </summary>
/// <param name="app">The name of the app.</param>
/// <param name="name">The name of the schema.</param>
/// <param name="parentId">The parent field id.</param>
/// <param name="id">The id of the field to update.</param>
/// <param name="request">The field object that needs to be added to the schema.</param>
/// <returns>
/// 204 => Schema field updated.
/// 400 => Schema field properties not valid or field is locked.
/// 404 => Field, schema or app not found.
/// </returns>
[HttpPut]
[Route("apps/{app}/schemas/{name}/fields/{parentId:long}/nested/{id:long}/")]
[ProducesResponseType(typeof(ErrorDto), 409)]
[ProducesResponseType(typeof(ErrorDto), 400)]
[ApiCosts(1)]
public async Task<IActionResult> PutNestedField(string app, string name, long parentId, long id, [FromBody] UpdateFieldDto request)
{
await CommandBus.PublishAsync(request.ToCommand(id, parentId));
return NoContent();
}
/// <summary>
/// Lock a schema field.
/// </summary>
@ -113,7 +190,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
/// <returns>
/// 204 => Schema field shown.
/// 400 => Schema field already locked.
/// 404 => Schema, field or app not found.
/// 404 => Field, schema or app not found.
/// </returns>
/// <remarks>
/// A hidden field is not part of the API response, but can still be edited in the portal.
@ -138,7 +215,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
/// <returns>
/// 204 => Schema field hidden.
/// 400 => Schema field already hidden.
/// 404 => Schema, field or app not found.
/// 404 => Field, schema or app not found.
/// </returns>
/// <remarks>
/// A locked field cannot be edited or deleted.
@ -154,6 +231,32 @@ namespace Squidex.Areas.Api.Controllers.Schemas
return NoContent();
}
/// <summary>
/// Hide a nested schema field.
/// </summary>
/// <param name="app">The name of the app.</param>
/// <param name="name">The name of the schema.</param>
/// <param name="parentId">The parent field id.</param>
/// <param name="id">The id of the field to hide.</param>
/// <returns>
/// 204 => Schema field hidden.
/// 400 => Schema field already hidden.
/// 404 => Field, schema, or app not found.
/// </returns>
/// <remarks>
/// A locked field cannot be edited or deleted.
/// </remarks>
[HttpPut]
[Route("apps/{app}/schemas/{name}/fields/{parentId:long}/nested/{id:long}/hide/")]
[ProducesResponseType(typeof(ErrorDto), 400)]
[ApiCosts(1)]
public async Task<IActionResult> HideNestedField(string app, string name, long parentId, long id)
{
await CommandBus.PublishAsync(new HideField { ParentFieldId = parentId, FieldId = id });
return NoContent();
}
/// <summary>
/// Show a schema field.
/// </summary>
@ -163,7 +266,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
/// <returns>
/// 204 => Schema field shown.
/// 400 => Schema field already visible.
/// 404 => Schema, field or app not found.
/// 404 => Field, schema or app not found.
/// </returns>
/// <remarks>
/// A hidden field is not part of the API response, but can still be edited in the portal.
@ -179,6 +282,32 @@ namespace Squidex.Areas.Api.Controllers.Schemas
return NoContent();
}
/// <summary>
/// Show a nested schema field.
/// </summary>
/// <param name="app">The name of the app.</param>
/// <param name="name">The name of the schema.</param>
/// <param name="parentId">The parent field id.</param>
/// <param name="id">The id of the field to show.</param>
/// <returns>
/// 204 => Schema field shown.
/// 400 => Schema field already visible.
/// 404 => Field, schema or app not found.
/// </returns>
/// <remarks>
/// A hidden field is not part of the API response, but can still be edited in the portal.
/// </remarks>
[HttpPut]
[Route("apps/{app}/schemas/{name}/fields/{parentId:long}/nested/{id:long}/show/")]
[ProducesResponseType(typeof(ErrorDto), 400)]
[ApiCosts(1)]
public async Task<IActionResult> ShowNestedField(string app, string name, long parentId, long id)
{
await CommandBus.PublishAsync(new ShowField { ParentFieldId = parentId, FieldId = id });
return NoContent();
}
/// <summary>
/// Enable a schema field.
/// </summary>
@ -188,7 +317,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
/// <returns>
/// 204 => Schema field enabled.
/// 400 => Schema field already enabled.
/// 404 => Schema, field or app not found.
/// 404 => Field, schema or app not found.
/// </returns>
/// <remarks>
/// A disabled field cannot not be edited in the squidex portal anymore,
@ -205,6 +334,33 @@ namespace Squidex.Areas.Api.Controllers.Schemas
return NoContent();
}
/// <summary>
/// Enable a nested schema field.
/// </summary>
/// <param name="app">The name of the app.</param>
/// <param name="name">The name of the schema.</param>
/// <param name="parentId">The parent field id.</param>
/// <param name="id">The id of the field to enable.</param>
/// <returns>
/// 204 => Schema field enabled.
/// 400 => Schema field already enabled.
/// 404 => Field, schema or app not found.
/// </returns>
/// <remarks>
/// A disabled field cannot not be edited in the squidex portal anymore,
/// but will be part of the API response.
/// </remarks>
[HttpPut]
[Route("apps/{app}/schemas/{name}/fields/{parentId:long}/nested/{id:long}/enable/")]
[ProducesResponseType(typeof(ErrorDto), 400)]
[ApiCosts(1)]
public async Task<IActionResult> EnableNestedField(string app, string name, long parentId, long id)
{
await CommandBus.PublishAsync(new EnableField { ParentFieldId = parentId, FieldId = id });
return NoContent();
}
/// <summary>
/// Disable a schema field.
/// </summary>
@ -214,7 +370,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
/// <returns>
/// 204 => Schema field disabled.
/// 400 => Schema field already disabled.
/// 404 => Schema, field or app not found.
/// 404 => Field, schema or app not found.
/// </returns>
/// <remarks>
/// A disabled field cannot not be edited in the squidex portal anymore,
@ -231,6 +387,33 @@ namespace Squidex.Areas.Api.Controllers.Schemas
return NoContent();
}
/// <summary>
/// Disable nested a schema field.
/// </summary>
/// <param name="app">The name of the app.</param>
/// <param name="name">The name of the schema.</param>
/// <param name="parentId">The parent field id.</param>
/// <param name="id">The id of the field to disable.</param>
/// <returns>
/// 204 => Schema field disabled.
/// 400 => Schema field already disabled.
/// 404 => Field, schema or app not found.
/// </returns>
/// <remarks>
/// A disabled field cannot not be edited in the squidex portal anymore,
/// but will be part of the API response.
/// </remarks>
[HttpPut]
[Route("apps/{app}/schemas/{name}/fields/{parentId:long}/nested/{id:long}/disable/")]
[ProducesResponseType(typeof(ErrorDto), 400)]
[ApiCosts(1)]
public async Task<IActionResult> DisableNestedField(string app, string name, long parentId, long id)
{
await CommandBus.PublishAsync(new DisableField { ParentFieldId = parentId, FieldId = id });
return NoContent();
}
/// <summary>
/// Delete a schema field.
/// </summary>
@ -240,7 +423,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
/// <returns>
/// 204 => Schema field deleted.
/// 400 => Field is locked.
/// 404 => Schema, field or app not found.
/// 404 => Field, schema or app not found.
/// </returns>
[HttpDelete]
[Route("apps/{app}/schemas/{name}/fields/{id:long}/")]
@ -251,5 +434,27 @@ namespace Squidex.Areas.Api.Controllers.Schemas
return NoContent();
}
/// <summary>
/// Delete a nested schema field.
/// </summary>
/// <param name="app">The name of the app.</param>
/// <param name="name">The name of the schema.</param>
/// <param name="parentId">The parent field id.</param>
/// <param name="id">The id of the field to disable.</param>
/// <returns>
/// 204 => Schema field deleted.
/// 400 => Field is locked.
/// 404 => Field, schema or app not found.
/// </returns>
[HttpDelete]
[Route("apps/{app}/schemas/{name}/fields/{parentId:long}/nested/{id:long}/")]
[ApiCosts(1)]
public async Task<IActionResult> DeleteNestedField(string app, string name, long parentId, long id)
{
await CommandBus.PublishAsync(new DeleteField { ParentFieldId = parentId, FieldId = id });
return NoContent();
}
}
}

2
src/Squidex/Pipeline/CommandMiddlewares/EnrichWithAppIdCommandMiddleware.cs

@ -57,7 +57,7 @@ namespace Squidex.Pipeline.CommandMiddlewares
throw new InvalidOperationException("Cannot resolve app.");
}
return new NamedId<Guid>(appFeature.App.Id, appFeature.App.Name);
return NamedId.Of(appFeature.App.Id, appFeature.App.Name);
}
}
}

4
src/Squidex/Pipeline/CommandMiddlewares/EnrichWithSchemaIdCommandMiddleware.cs

@ -68,7 +68,7 @@ namespace Squidex.Pipeline.CommandMiddlewares
if (appFeature != null && appFeature.App != null)
{
appId = new NamedId<Guid>(appFeature.App.Id, appFeature.App.Name);
appId = NamedId.Of(appFeature.App.Id, appFeature.App.Name);
}
}
@ -96,7 +96,7 @@ namespace Squidex.Pipeline.CommandMiddlewares
throw new DomainObjectNotFoundException(schemaName, typeof(ISchemaEntity));
}
return new NamedId<Guid>(schema.Id, schema.Name);
return NamedId.Of(schema.Id, schema.Name);
}
}

4
tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleEventFormatterTests.cs

@ -34,8 +34,8 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules
private readonly IUserResolver userResolver = A.Fake<IUserResolver>();
private readonly IUser user = A.Fake<IUser>();
private readonly IRuleUrlGenerator urlGenerator = A.Fake<IRuleUrlGenerator>();
private readonly NamedId<Guid> appId = new NamedId<Guid>(Guid.NewGuid(), "my-app");
private readonly NamedId<Guid> schemaId = new NamedId<Guid>(Guid.NewGuid(), "my-schema");
private readonly NamedId<Guid> appId = NamedId.Of(Guid.NewGuid(), "my-app");
private readonly NamedId<Guid> schemaId = NamedId.Of(Guid.NewGuid(), "my-schema");
private readonly Guid contentId = Guid.NewGuid();
private readonly RuleEventFormatter sut;

4
tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleServiceTests.cs

@ -116,7 +116,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules
[Fact]
public async Task Should_not_create_job_if_too_old()
{
var e = new ContentCreated { SchemaId = new NamedId<Guid>(Guid.NewGuid(), "my-schema"), AppId = new NamedId<Guid>(Guid.NewGuid(), "my-event") };
var e = new ContentCreated { SchemaId = NamedId.Of(Guid.NewGuid(), "my-schema"), AppId = NamedId.Of(Guid.NewGuid(), "my-event") };
var now = SystemClock.Instance.GetCurrentInstant();
@ -147,7 +147,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules
[Fact]
public async Task Should_create_job_if_triggered()
{
var e = new ContentCreated { SchemaId = new NamedId<Guid>(Guid.NewGuid(), "my-schema"), AppId = new NamedId<Guid>(Guid.NewGuid(), "my-event") };
var e = new ContentCreated { SchemaId = NamedId.Of(Guid.NewGuid(), "my-schema"), AppId = NamedId.Of(Guid.NewGuid(), "my-event") };
var now = SystemClock.Instance.GetCurrentInstant();

4
tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/Triggers/ContentChangedTriggerTests.cs

@ -27,8 +27,8 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules.Triggers
public class ContentChangedTriggerTests
{
private readonly IRuleTriggerHandler sut = new ContentChangedTriggerHandler();
private static readonly NamedId<Guid> SchemaMatch = new NamedId<Guid>(Guid.NewGuid(), "my-schema1");
private static readonly NamedId<Guid> SchemaNonMatch = new NamedId<Guid>(Guid.NewGuid(), "my-schema2");
private static readonly NamedId<Guid> SchemaMatch = NamedId.Of(Guid.NewGuid(), "my-schema1");
private static readonly NamedId<Guid> SchemaNonMatch = NamedId.Of(Guid.NewGuid(), "my-schema2");
public static IEnumerable<object[]> TestData = new[]
{

1
tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ArrayFieldTests.cs

@ -5,7 +5,6 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

1
tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/TagsFieldTests.cs

@ -5,7 +5,6 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

9
tests/Squidex.Domain.Apps.Core.Tests/TestData.cs

@ -62,6 +62,7 @@ namespace Squidex.Domain.Apps.Core
.AddDateTime(203, "nested-datetime")
.AddGeolocation(204, "nested-geolocation")
.AddJson(205, "nested-json")
.AddJson(211, "nested-json2")
.AddNumber(206, "nested-number")
.AddReferences(207, "nested-references")
.AddString(208, "nested-string")
@ -89,9 +90,11 @@ namespace Squidex.Domain.Apps.Core
.AddTags(112, "root-tags", Partitioning.Language,
new TagsFieldProperties())
.Update(new SchemaProperties { Hints = "The User" })
.UpdateField(104, f => f.Hide())
.UpdateField(108, f => f.Lock())
.UpdateField(109, f => f.Disable());
.HideField(104)
.HideField(211, 101)
.DisableField(109)
.DisableField(212, 101)
.LockField(105);
return schema;
}

2
tests/Squidex.Domain.Apps.Entities.Tests/Rules/Guards/GuardRuleTests.cs

@ -25,7 +25,7 @@ namespace Squidex.Domain.Apps.Entities.Rules.Guards
{
private readonly Uri validUrl = new Uri("https://squidex.io");
private readonly Rule rule_0 = new Rule(new ContentChangedTrigger(), new WebhookAction());
private readonly NamedId<Guid> appId = new NamedId<Guid>(Guid.NewGuid(), "my-app");
private readonly NamedId<Guid> appId = NamedId.Of(Guid.NewGuid(), "my-app");
private readonly IAppProvider appProvider = A.Fake<IAppProvider>();
public GuardRuleTests()

4
tests/Squidex.Domain.Apps.Entities.Tests/Rules/Indexes/RulesByAppIndexCommandMiddlewareTests.cs

@ -38,7 +38,7 @@ namespace Squidex.Domain.Apps.Entities.Rules.Indexes
public async Task Should_add_rule_to_index_on_create()
{
var context =
new CommandContext(new CreateRule { RuleId = appId, AppId = new NamedId<Guid>(appId, "my-app") }, commandBus)
new CommandContext(new CreateRule { RuleId = appId, AppId = NamedId.Of(appId, "my-app") }, commandBus)
.Complete();
await sut.HandleAsync(context);
@ -60,7 +60,7 @@ namespace Squidex.Domain.Apps.Entities.Rules.Indexes
.Returns(J.AsTask(ruleState));
A.CallTo(() => ruleState.AppId)
.Returns(new NamedId<Guid>(appId, "my-app"));
.Returns(NamedId.Of(appId, "my-app"));
var context =
new CommandContext(new DeleteRule { RuleId = appId }, commandBus)

2
tests/Squidex.Domain.Apps.Entities.Tests/Rules/RuleEnqueuerTests.cs

@ -28,7 +28,7 @@ namespace Squidex.Domain.Apps.Entities.Rules
private readonly IRuleEventRepository ruleEventRepository = A.Fake<IRuleEventRepository>();
private readonly RuleService ruleService = A.Fake<RuleService>();
private readonly Instant now = SystemClock.Instance.GetCurrentInstant();
private readonly NamedId<Guid> appId = new NamedId<Guid>(Guid.NewGuid(), "my-app");
private readonly NamedId<Guid> appId = NamedId.Of(Guid.NewGuid(), "my-app");
private readonly RuleEnqueuer sut;
public RuleEnqueuerTests()

26
tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/GuardSchemaTests.cs

@ -23,7 +23,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards
{
private readonly IAppProvider appProvider = A.Fake<IAppProvider>();
private readonly Schema schema_0;
private readonly NamedId<Guid> appId = new NamedId<Guid>(Guid.NewGuid(), "my-app");
private readonly NamedId<Guid> appId = NamedId.Of(Guid.NewGuid(), "my-app");
public GuardSchemaTests()
{
@ -80,14 +80,14 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards
Name = null,
Properties = new ArrayFieldProperties(),
Partitioning = "invalid",
Nested = new List<CreateNestedSchemaField>
Nested = new List<CreateSchemaNestedField>
{
new CreateNestedSchemaField
new CreateSchemaNestedField
{
Name = null,
Properties = InvalidProperties()
},
new CreateNestedSchemaField
new CreateSchemaNestedField
{
Name = null,
Properties = InvalidProperties()
@ -99,14 +99,14 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards
Name = null,
Properties = InvalidProperties(),
Partitioning = "invalid",
Nested = new List<CreateNestedSchemaField>
Nested = new List<CreateSchemaNestedField>
{
new CreateNestedSchemaField
new CreateSchemaNestedField
{
Name = null,
Properties = InvalidProperties()
},
new CreateNestedSchemaField
new CreateSchemaNestedField
{
Name = null,
Properties = InvalidProperties()
@ -145,14 +145,14 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards
Name = "field1",
Properties = new ArrayFieldProperties(),
Partitioning = "invariant",
Nested = new List<CreateNestedSchemaField>
Nested = new List<CreateSchemaNestedField>
{
new CreateNestedSchemaField
new CreateSchemaNestedField
{
Name = "nested1",
Properties = ValidProperties()
},
new CreateNestedSchemaField
new CreateSchemaNestedField
{
Name = "nested1",
Properties = ValidProperties()
@ -191,14 +191,14 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards
Name = "field3",
Properties = new ArrayFieldProperties(),
Partitioning = "invariant",
Nested = new List<CreateNestedSchemaField>
Nested = new List<CreateSchemaNestedField>
{
new CreateNestedSchemaField
new CreateSchemaNestedField
{
Name = "nested1",
Properties = ValidProperties()
},
new CreateNestedSchemaField
new CreateSchemaNestedField
{
Name = "nested2",
Properties = ValidProperties()

4
tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Indexes/SchemasByAppIndexCommandMiddlewareTests.cs

@ -38,7 +38,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Indexes
public async Task Should_add_schema_to_index_on_create()
{
var context =
new CommandContext(new CreateSchema { SchemaId = appId, Name = "my-schema", AppId = new NamedId<Guid>(appId, "my-app") }, commandBus)
new CommandContext(new CreateSchema { SchemaId = appId, Name = "my-schema", AppId = NamedId.Of(appId, "my-app") }, commandBus)
.Complete();
await sut.HandleAsync(context);
@ -60,7 +60,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Indexes
.Returns(J.AsTask(schemaState));
A.CallTo(() => schemaState.AppId)
.Returns(new NamedId<Guid>(appId, "my-app"));
.Returns(NamedId.Of(appId, "my-app"));
var context =
new CommandContext(new DeleteSchema { SchemaId = appId }, commandBus)

289
tests/Squidex.Domain.Apps.Entities.Tests/Schemas/SchemaGrainTests.cs

@ -10,6 +10,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using FakeItEasy;
using Squidex.Domain.Apps.Core;
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Entities.Schemas.Commands;
using Squidex.Domain.Apps.Entities.Schemas.State;
@ -27,7 +28,10 @@ namespace Squidex.Domain.Apps.Entities.Schemas
private readonly IAppProvider appProvider = A.Fake<IAppProvider>();
private readonly FieldRegistry registry = new FieldRegistry(new TypeNameRegistry());
private readonly string fieldName = "age";
private readonly NamedId<long> fieldId;
private readonly string arrayName = "array";
private readonly NamedId<long> fieldId = NamedId.Of(1L, "age");
private readonly NamedId<long> arrayId = NamedId.Of(1L, "array");
private readonly NamedId<long> nestedId = NamedId.Of(2L, "age");
private readonly SchemaGrain sut;
protected override Guid Id
@ -40,8 +44,6 @@ namespace Squidex.Domain.Apps.Entities.Schemas
A.CallTo(() => appProvider.GetSchemaAsync(AppId, SchemaName))
.Returns((ISchemaEntity)null);
fieldId = new NamedId<long>(1, fieldName);
sut = new SchemaGrain(Store, A.Dummy<ISemanticLog>(), appProvider, registry);
sut.OnActivateAsync(Id).Wait();
}
@ -85,7 +87,18 @@ namespace Squidex.Domain.Apps.Entities.Schemas
var fields = new List<CreateSchemaField>
{
new CreateSchemaField { Name = "field1", Properties = ValidProperties() },
new CreateSchemaField { Name = "field2", Properties = ValidProperties() }
new CreateSchemaField { Name = "field2", Properties = ValidProperties() },
new CreateSchemaField
{
Name = "field3",
Partitioning = Partitioning.Language.Key,
Properties = new ArrayFieldProperties(),
Nested = new List<CreateSchemaNestedField>
{
new CreateSchemaNestedField { Name = "nested1", Properties = ValidProperties() },
new CreateSchemaNestedField { Name = "nested2", Properties = ValidProperties() }
}
}
};
var command = new CreateSchema { Name = SchemaName, SchemaId = SchemaId, Properties = properties, Fields = fields };
@ -100,7 +113,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas
Assert.Equal(SchemaName, sut.Snapshot.Name);
Assert.Equal(SchemaName, sut.Snapshot.SchemaDef.Name);
Assert.Equal(2, @event.Fields.Count);
Assert.Equal(3, @event.Fields.Count);
}
[Fact]
@ -153,25 +166,6 @@ namespace Squidex.Domain.Apps.Entities.Schemas
);
}
[Fact]
public async Task Reorder_should_create_events_and_update_state()
{
var command = new ReorderFields { FieldIds = new List<long> { 1, 2 } };
await ExecuteCreateAsync();
await ExecuteAddFieldAsync("field1");
await ExecuteAddFieldAsync("field2");
var result = await sut.ExecuteAsync(CreateCommand(command));
result.ShouldBeEquivalent(new EntitySavedResult(3));
LastEvents
.ShouldHaveSameEvents(
CreateEvent(new SchemaFieldsReordered { FieldIds = command.FieldIds })
);
}
[Fact]
public async Task Publish_should_create_events_and_update_state()
{
@ -249,6 +243,65 @@ namespace Squidex.Domain.Apps.Entities.Schemas
);
}
[Fact]
public async Task LockField_should_create_events_and_update_state()
{
var command = new LockField { FieldId = 1 };
await ExecuteCreateAsync();
await ExecuteAddFieldAsync(fieldName);
var result = await sut.ExecuteAsync(CreateCommand(command));
result.ShouldBeEquivalent(new EntitySavedResult(2));
Assert.False(GetField(1).IsDisabled);
LastEvents
.ShouldHaveSameEvents(
CreateEvent(new FieldLocked { FieldId = fieldId })
);
}
[Fact]
public async Task Reorder_should_create_events_and_update_state()
{
var command = new ReorderFields { FieldIds = new List<long> { 1, 2 } };
await ExecuteCreateAsync();
await ExecuteAddFieldAsync("field1");
await ExecuteAddFieldAsync("field2");
var result = await sut.ExecuteAsync(CreateCommand(command));
result.ShouldBeEquivalent(new EntitySavedResult(3));
LastEvents
.ShouldHaveSameEvents(
CreateEvent(new SchemaFieldsReordered { FieldIds = command.FieldIds })
);
}
[Fact]
public async Task Reorder_should_create_events_and_update_state_for_array()
{
var command = new ReorderFields { ParentFieldId = 1, FieldIds = new List<long> { 2, 3 } };
await ExecuteCreateAsync();
await ExecuteAddArrayFieldAsync();
await ExecuteAddFieldAsync("field1", 1);
await ExecuteAddFieldAsync("field2", 1);
var result = await sut.ExecuteAsync(CreateCommand(command));
result.ShouldBeEquivalent(new EntitySavedResult(4));
LastEvents
.ShouldHaveSameEvents(
CreateEvent(new SchemaFieldsReordered { ParentFieldId = arrayId, FieldIds = command.FieldIds })
);
}
[Fact]
public async Task Add_should_create_events_and_update_state()
{
@ -260,7 +313,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas
result.ShouldBeEquivalent(EntityCreatedResult.Create(1, 1));
Assert.Equal(command.Properties, sut.Snapshot.SchemaDef.FieldsById[1].RawProperties);
Assert.Equal(command.Properties, GetField(1).RawProperties);
LastEvents
.ShouldHaveSameEvents(
@ -268,6 +321,27 @@ namespace Squidex.Domain.Apps.Entities.Schemas
);
}
[Fact]
public async Task Add_should_create_events_and_update_state_for_array()
{
var command = new AddField { ParentFieldId = 1, Name = fieldName, Properties = ValidProperties() };
await ExecuteCreateAsync();
await ExecuteAddArrayFieldAsync();
var result = await sut.ExecuteAsync(CreateCommand(command));
result.ShouldBeEquivalent(EntityCreatedResult.Create(2, 2));
Assert.NotEqual(command.Properties, GetField(1).RawProperties);
Assert.Equal(command.Properties, GetNestedField(1, 2).RawProperties);
LastEvents
.ShouldHaveSameEvents(
CreateEvent(new FieldAdded { ParentFieldId = arrayId, Name = fieldName, FieldId = nestedId, Properties = command.Properties })
);
}
[Fact]
public async Task UpdateField_should_create_events_and_update_state()
{
@ -280,7 +354,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas
result.ShouldBeEquivalent(new EntitySavedResult(2));
Assert.Equal(command.Properties, sut.Snapshot.SchemaDef.FieldsById[1].RawProperties);
Assert.Equal(command.Properties, GetField(1).RawProperties);
LastEvents
.ShouldHaveSameEvents(
@ -289,22 +363,24 @@ namespace Squidex.Domain.Apps.Entities.Schemas
}
[Fact]
public async Task LockField_should_create_events_and_update_state()
public async Task UpdateField_should_create_events_and_update_state_for_array()
{
var command = new LockField { FieldId = 1 };
var command = new UpdateField { ParentFieldId = 1, FieldId = 2, Properties = new StringFieldProperties() };
await ExecuteCreateAsync();
await ExecuteAddFieldAsync(fieldName);
await ExecuteAddArrayFieldAsync();
await ExecuteAddFieldAsync(fieldName, 1);
var result = await sut.ExecuteAsync(CreateCommand(command));
result.ShouldBeEquivalent(new EntitySavedResult(2));
result.ShouldBeEquivalent(new EntitySavedResult(3));
Assert.False(sut.Snapshot.SchemaDef.FieldsById[1].IsDisabled);
Assert.NotEqual(command.Properties, GetField(1).RawProperties);
Assert.Equal(command.Properties, GetNestedField(1, 2).RawProperties);
LastEvents
.ShouldHaveSameEvents(
CreateEvent(new FieldLocked { FieldId = fieldId })
CreateEvent(new FieldUpdated { ParentFieldId = arrayId, FieldId = nestedId, Properties = command.Properties })
);
}
@ -320,7 +396,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas
result.ShouldBeEquivalent(new EntitySavedResult(2));
Assert.True(sut.Snapshot.SchemaDef.FieldsById[1].IsHidden);
Assert.True(GetField(1).IsHidden);
LastEvents
.ShouldHaveSameEvents(
@ -328,6 +404,28 @@ namespace Squidex.Domain.Apps.Entities.Schemas
);
}
[Fact]
public async Task HideField_should_create_events_and_update_state_for_array()
{
var command = new HideField { ParentFieldId = 1, FieldId = 2 };
await ExecuteCreateAsync();
await ExecuteAddArrayFieldAsync();
await ExecuteAddFieldAsync(fieldName, 1);
var result = await sut.ExecuteAsync(CreateCommand(command));
result.ShouldBeEquivalent(new EntitySavedResult(3));
Assert.False(GetField(1).IsHidden);
Assert.True(GetNestedField(1, 2).IsHidden);
LastEvents
.ShouldHaveSameEvents(
CreateEvent(new FieldHidden { ParentFieldId = arrayId, FieldId = nestedId })
);
}
[Fact]
public async Task ShowField_should_create_events_and_update_state()
{
@ -341,7 +439,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas
result.ShouldBeEquivalent(new EntitySavedResult(3));
Assert.False(sut.Snapshot.SchemaDef.FieldsById[1].IsHidden);
Assert.False(GetField(1).IsHidden);
LastEvents
.ShouldHaveSameEvents(
@ -349,6 +447,29 @@ namespace Squidex.Domain.Apps.Entities.Schemas
);
}
[Fact]
public async Task ShowField_should_create_events_and_update_state_for_array()
{
var command = new ShowField { ParentFieldId = 1, FieldId = 2 };
await ExecuteCreateAsync();
await ExecuteAddArrayFieldAsync();
await ExecuteAddFieldAsync(fieldName, 1);
await ExecuteHideFieldAsync(2, 1);
var result = await sut.ExecuteAsync(CreateCommand(command));
result.ShouldBeEquivalent(new EntitySavedResult(4));
Assert.False(GetField(1).IsHidden);
Assert.False(GetNestedField(1, 2).IsHidden);
LastEvents
.ShouldHaveSameEvents(
CreateEvent(new FieldShown { ParentFieldId = arrayId, FieldId = nestedId })
);
}
[Fact]
public async Task DisableField_should_create_events_and_update_state()
{
@ -361,7 +482,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas
result.ShouldBeEquivalent(new EntitySavedResult(2));
Assert.True(sut.Snapshot.SchemaDef.FieldsById[1].IsDisabled);
Assert.True(GetField(1).IsDisabled);
LastEvents
.ShouldHaveSameEvents(
@ -369,6 +490,28 @@ namespace Squidex.Domain.Apps.Entities.Schemas
);
}
[Fact]
public async Task DisableField_should_create_events_and_update_state_for_array()
{
var command = new DisableField { ParentFieldId = 1, FieldId = 2 };
await ExecuteCreateAsync();
await ExecuteAddArrayFieldAsync();
await ExecuteAddFieldAsync(fieldName, 1);
var result = await sut.ExecuteAsync(CreateCommand(command));
result.ShouldBeEquivalent(new EntitySavedResult(3));
Assert.False(GetField(1).IsDisabled);
Assert.True(GetNestedField(1, 2).IsDisabled);
LastEvents
.ShouldHaveSameEvents(
CreateEvent(new FieldDisabled { ParentFieldId = arrayId, FieldId = nestedId })
);
}
[Fact]
public async Task EnableField_should_create_events_and_update_state()
{
@ -382,7 +525,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas
result.ShouldBeEquivalent(new EntitySavedResult(3));
Assert.False(sut.Snapshot.SchemaDef.FieldsById[1].IsDisabled);
Assert.False(GetField(1).IsDisabled);
LastEvents
.ShouldHaveSameEvents(
@ -390,6 +533,29 @@ namespace Squidex.Domain.Apps.Entities.Schemas
);
}
[Fact]
public async Task EnableField_should_create_events_and_update_state_for_array()
{
var command = new EnableField { ParentFieldId = 1, FieldId = 2 };
await ExecuteCreateAsync();
await ExecuteAddArrayFieldAsync();
await ExecuteAddFieldAsync(fieldName, 1);
await ExecuteDisableFieldAsync(2, 1);
var result = await sut.ExecuteAsync(CreateCommand(command));
result.ShouldBeEquivalent(new EntitySavedResult(4));
Assert.False(GetField(1).IsDisabled);
Assert.False(GetNestedField(1, 2).IsDisabled);
LastEvents
.ShouldHaveSameEvents(
CreateEvent(new FieldEnabled { ParentFieldId = arrayId, FieldId = nestedId })
);
}
[Fact]
public async Task DeleteField_should_create_events_and_update_state()
{
@ -402,7 +568,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas
result.ShouldBeEquivalent(new EntitySavedResult(2));
Assert.False(sut.Snapshot.SchemaDef.FieldsById.ContainsKey(1));
Assert.Null(GetField(1));
LastEvents
.ShouldHaveSameEvents(
@ -410,24 +576,51 @@ namespace Squidex.Domain.Apps.Entities.Schemas
);
}
[Fact]
public async Task DeleteField_should_create_events_and_update_state_for_array()
{
var command = new DeleteField { ParentFieldId = 1, FieldId = 2 };
await ExecuteCreateAsync();
await ExecuteAddArrayFieldAsync();
await ExecuteAddFieldAsync(fieldName, 1);
var result = await sut.ExecuteAsync(CreateCommand(command));
result.ShouldBeEquivalent(new EntitySavedResult(3));
Assert.NotNull(GetField(1));
Assert.Null(GetNestedField(1, 2));
LastEvents
.ShouldHaveSameEvents(
CreateEvent(new FieldDeleted { ParentFieldId = arrayId, FieldId = nestedId })
);
}
private Task ExecuteCreateAsync()
{
return sut.ExecuteAsync(CreateCommand(new CreateSchema { Name = SchemaName }));
}
private Task ExecuteAddFieldAsync(string name)
private Task ExecuteAddArrayFieldAsync()
{
return sut.ExecuteAsync(CreateCommand(new AddField { Properties = ValidProperties(), Name = name }));
return sut.ExecuteAsync(CreateCommand(new AddField { Properties = new ArrayFieldProperties(), Name = arrayName }));
}
private Task ExecuteHideFieldAsync(long id)
private Task ExecuteAddFieldAsync(string name, long? parentId = null)
{
return sut.ExecuteAsync(CreateCommand(new HideField { FieldId = id }));
return sut.ExecuteAsync(CreateCommand(new AddField { ParentFieldId = parentId, Properties = ValidProperties(), Name = name }));
}
private Task ExecuteDisableFieldAsync(long id)
private Task ExecuteHideFieldAsync(long id, long? parentId = null)
{
return sut.ExecuteAsync(CreateCommand(new DisableField { FieldId = id }));
return sut.ExecuteAsync(CreateCommand(new HideField { ParentFieldId = parentId, FieldId = id }));
}
private Task ExecuteDisableFieldAsync(long id, long? parentId = null)
{
return sut.ExecuteAsync(CreateCommand(new DisableField { ParentFieldId = parentId, FieldId = id }));
}
private Task ExecutePublishAsync()
@ -440,6 +633,16 @@ namespace Squidex.Domain.Apps.Entities.Schemas
return sut.ExecuteAsync(CreateCommand(new DeleteSchema()));
}
private IField GetField(int id)
{
return sut.Snapshot.SchemaDef.FieldsById.GetOrDefault(id);
}
private IField GetNestedField(int parentId, int childId)
{
return ((IArrayField)sut.Snapshot.SchemaDef.FieldsById[parentId]).FieldsById.GetOrDefault(childId);
}
private static StringFieldProperties ValidProperties()
{
return new StringFieldProperties { MinLength = 10, MaxLength = 20 };

4
tests/Squidex.Domain.Apps.Entities.Tests/TestHelpers/HandlerTestBase.cs

@ -38,12 +38,12 @@ namespace Squidex.Domain.Apps.Entities.TestHelpers
protected NamedId<Guid> AppNamedId
{
get { return new NamedId<Guid>(AppId, AppName); }
get { return NamedId.Of(AppId, AppName); }
}
protected NamedId<Guid> SchemaNamedId
{
get { return new NamedId<Guid>(SchemaId, SchemaName); }
get { return NamedId.Of(SchemaId, SchemaName); }
}
protected abstract Guid Id { get; }

34
tests/Squidex.Infrastructure.Tests/NamedIdTests.cs

@ -19,7 +19,7 @@ namespace Squidex.Infrastructure
{
var id = Guid.NewGuid();
var namedId = new NamedId<Guid>(id, "my-name");
var namedId = NamedId.Of(id, "my-name");
Assert.Equal(id, namedId.Id);
Assert.Equal("my-name", namedId.Name);
@ -30,7 +30,7 @@ namespace Squidex.Infrastructure
{
var id = Guid.NewGuid();
var namedId = new NamedId<Guid>(id, "my-name");
var namedId = NamedId.Of(id, "my-name");
Assert.Equal($"{id},my-name", namedId.ToString());
}
@ -41,10 +41,10 @@ namespace Squidex.Infrastructure
var id1 = Guid.NewGuid();
var id2 = Guid.NewGuid();
var token1a = new NamedId<Guid>(id1, "my-name1");
var token1b = new NamedId<Guid>(id1, "my-name1");
var token1c = new NamedId<Guid>(id1, "my-name2");
var token2a = new NamedId<Guid>(id2, "my-name1");
var token1a = NamedId.Of(id1, "my-name1");
var token1b = NamedId.Of(id1, "my-name1");
var token1c = NamedId.Of(id1, "my-name2");
var token2a = NamedId.Of(id2, "my-name1");
Assert.True(token1a.Equals(token1b));
@ -58,10 +58,10 @@ namespace Squidex.Infrastructure
var id1 = Guid.NewGuid();
var id2 = Guid.NewGuid();
object token1a = new NamedId<Guid>(id1, "my-name1");
object token1b = new NamedId<Guid>(id1, "my-name1");
object token1c = new NamedId<Guid>(id1, "my-name2");
object token2a = new NamedId<Guid>(id2, "my-name1");
object token1a = NamedId.Of(id1, "my-name1");
object token1b = NamedId.Of(id1, "my-name1");
object token1c = NamedId.Of(id1, "my-name2");
object token2a = NamedId.Of(id2, "my-name1");
Assert.True(token1a.Equals(token1b));
@ -75,10 +75,10 @@ namespace Squidex.Infrastructure
var id1 = Guid.NewGuid();
var id2 = Guid.NewGuid();
object token1a = new NamedId<Guid>(id1, "my-name1");
object token1b = new NamedId<Guid>(id1, "my-name1");
object token1c = new NamedId<Guid>(id1, "my-name2");
object token2a = new NamedId<Guid>(id2, "my-name1");
object token1a = NamedId.Of(id1, "my-name1");
object token1b = NamedId.Of(id1, "my-name1");
object token1c = NamedId.Of(id1, "my-name2");
object token2a = NamedId.Of(id2, "my-name1");
Assert.Equal(token1a.GetHashCode(), token1b.GetHashCode());
@ -97,7 +97,7 @@ namespace Squidex.Infrastructure
[Fact]
public void Should_serialize_and_deserialize_valid_guid_token()
{
var value = new NamedId<Guid>(Guid.NewGuid(), "my-name");
var value = NamedId.Of(Guid.NewGuid(), "my-name");
value.SerializeAndDeserialize(new NamedGuidIdConverter());
}
@ -113,7 +113,7 @@ namespace Squidex.Infrastructure
[Fact]
public void Should_serialize_and_deserialize_valid_long_token()
{
var value = new NamedId<long>(123, "my-name");
var value = NamedId.Of(123L, "my-name");
value.SerializeAndDeserialize(new NamedLongIdConverter());
}
@ -129,7 +129,7 @@ namespace Squidex.Infrastructure
[Fact]
public void Should_serialize_and_deserialize_valid_string_token()
{
var value = new NamedId<string>(Guid.NewGuid().ToString(), "my-name");
var value = NamedId.Of(Guid.NewGuid().ToString(), "my-name");
value.SerializeAndDeserialize(new NamedStringIdConverter());
}

6
tests/Squidex.Tests/Pipeline/CommandMiddlewares/EnrichWithAppIdCommandMiddlewareTests.cs

@ -66,7 +66,7 @@ namespace Squidex.Pipeline.CommandMiddlewares
await sut.HandleAsync(context);
Assert.Equal(new NamedId<Guid>(appId, appName), command.AppId);
Assert.Equal(NamedId.Of(appId, appName), command.AppId);
}
[Fact]
@ -100,12 +100,12 @@ namespace Squidex.Pipeline.CommandMiddlewares
{
SetupApp(out var appId, out var appName);
var command = new CreateContent { AppId = new NamedId<Guid>(Guid.NewGuid(), "other-app") };
var command = new CreateContent { AppId = NamedId.Of(Guid.NewGuid(), "other-app") };
var context = new CommandContext(command, commandBus);
await sut.HandleAsync(context);
Assert.NotEqual(new NamedId<Guid>(appId, appName), command.AppId);
Assert.NotEqual(NamedId.Of(appId, appName), command.AppId);
}
private void SetupApp(out Guid appId, out string appName)

12
tests/Squidex.Tests/Pipeline/CommandMiddlewares/EnrichWithSchemaIdCommandMiddlewareTests.cs

@ -101,7 +101,7 @@ namespace Squidex.Pipeline.CommandMiddlewares
await sut.HandleAsync(context);
Assert.Equal(new NamedId<Guid>(schemaId, schemaName), command.SchemaId);
Assert.Equal(NamedId.Of(schemaId, schemaName), command.SchemaId);
}
[Fact]
@ -117,7 +117,7 @@ namespace Squidex.Pipeline.CommandMiddlewares
await sut.HandleAsync(context);
Assert.Equal(new NamedId<Guid>(schemaId, schemaName), command.SchemaId);
Assert.Equal(NamedId.Of(schemaId, schemaName), command.SchemaId);
}
[Fact]
@ -139,7 +139,7 @@ namespace Squidex.Pipeline.CommandMiddlewares
[Fact]
public async Task Should_use_app_id_from_command()
{
var appId = new NamedId<Guid>(Guid.NewGuid(), "my-app");
var appId = NamedId.Of(Guid.NewGuid(), "my-app");
SetupSchema(appId.Id, out var schemaId, out var schemaName);
@ -150,7 +150,7 @@ namespace Squidex.Pipeline.CommandMiddlewares
await sut.HandleAsync(context);
Assert.Equal(new NamedId<Guid>(schemaId, schemaName), command.SchemaId);
Assert.Equal(NamedId.Of(schemaId, schemaName), command.SchemaId);
}
[Fact]
@ -173,12 +173,12 @@ namespace Squidex.Pipeline.CommandMiddlewares
SetupApp(out var appId, out var appName);
SetupSchema(appId, out var schemaId, out var schemaName);
var command = new CreateContent { SchemaId = new NamedId<Guid>(Guid.NewGuid(), "other-schema") };
var command = new CreateContent { SchemaId = NamedId.Of(Guid.NewGuid(), "other-schema") };
var context = new CommandContext(command, commandBus);
await sut.HandleAsync(context);
Assert.NotEqual(new NamedId<Guid>(appId, appName), command.AppId);
Assert.NotEqual(NamedId.Of(appId, appName), command.AppId);
}
private void SetupSchema(Guid appId, out Guid schemaId, out string schemaName)

Loading…
Cancel
Save