Browse Source

Reordering API.

pull/65/head
Sebastian Stehle 9 years ago
parent
commit
17022b6375
  1. 19
      src/Squidex.Events/Schemas/SchemaFieldsReordered.cs
  2. 2
      src/Squidex.Events/Schemas/SchemaPublished.cs
  3. 2
      src/Squidex.Events/Schemas/SchemaUnpublished.cs
  4. 5
      src/Squidex.Events/Schemas/Utils/SchemaEventDispatcher.cs
  5. 26
      src/Squidex.Write/Schemas/Commands/ReorderFields.cs
  6. 5
      src/Squidex.Write/Schemas/SchemaCommandHandler.cs
  7. 18
      src/Squidex.Write/Schemas/SchemaDomainObject.cs
  8. 22
      src/Squidex/Controllers/Api/Schemas/Models/ReorderFieldsDto.cs
  9. 50
      src/Squidex/Controllers/Api/Schemas/SchemaFieldsController.cs
  10. 16
      src/Squidex/Controllers/Api/Schemas/SchemasController.cs
  11. 14
      tests/Squidex.Write.Tests/Schemas/SchemaCommandHandlerTests.cs
  12. 58
      tests/Squidex.Write.Tests/Schemas/SchemaDomainObjectTests.cs

19
src/Squidex.Events/Schemas/SchemaFieldsReordered.cs

@ -0,0 +1,19 @@
// ==========================================================================
// SchemaFieldsReordered.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using System.Collections.Generic;
using Squidex.Infrastructure;
namespace Squidex.Events.Schemas
{
[TypeName("SchemaFieldsReorderedEvent")]
public class SchemaFieldsReordered : SchemaEvent
{
public List<long> FieldIds { get; set; }
}
}

2
src/Squidex.Events/Schemas/SchemaPublished.cs

@ -10,7 +10,7 @@ using Squidex.Infrastructure;
namespace Squidex.Events.Schemas
{
[TypeName("SchemaPublished")]
[TypeName("SchemaPublishedEvent")]
public class SchemaPublished : SchemaEvent
{
}

2
src/Squidex.Events/Schemas/SchemaUnpublished.cs

@ -10,7 +10,7 @@ using Squidex.Infrastructure;
namespace Squidex.Events.Schemas
{
[TypeName("SchemaUnpublished")]
[TypeName("SchemaUnpublishedEvent")]
public class SchemaUnpublished : SchemaEvent
{
}

5
src/Squidex.Events/Schemas/Utils/SchemaEventDispatcher.cs

@ -54,6 +54,11 @@ namespace Squidex.Events.Schemas.Utils
return schema.Update(@event.Properties);
}
public static Schema Dispatch(SchemaFieldsReordered @event, Schema schema)
{
return schema.ReorderFields(@event.FieldIds);
}
public static Schema Dispatch(FieldDeleted @event, Schema schema)
{
return schema.DeleteField(@event.FieldId.Id);

26
src/Squidex.Write/Schemas/Commands/ReorderFields.cs

@ -0,0 +1,26 @@
// ==========================================================================
// ReorderFields.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using System.Collections.Generic;
using Squidex.Infrastructure;
namespace Squidex.Write.Schemas.Commands
{
public class ReorderFields : SchemaAggregateCommand, IValidatable
{
public List<long> FieldIds { get; set; }
public void Validate(IList<ValidationError> errors)
{
if (FieldIds == null)
{
errors.Add(new ValidationError("Field ids must be specified", nameof(FieldIds)));
}
}
}
}

5
src/Squidex.Write/Schemas/SchemaCommandHandler.cs

@ -90,6 +90,11 @@ namespace Squidex.Write.Schemas
return handler.UpdateAsync<SchemaDomainObject>(context, s => s.ShowField(command));
}
protected Task On(ReorderFields command, CommandContext context)
{
return handler.UpdateAsync<SchemaDomainObject>(context, s => s.Reorder(command));
}
protected Task On(UpdateSchema command, CommandContext context)
{
return handler.UpdateAsync<SchemaDomainObject>(context, s => s.Update(command));

18
src/Squidex.Write/Schemas/SchemaDomainObject.cs

@ -91,6 +91,11 @@ namespace Squidex.Write.Schemas
schema = SchemaEventDispatcher.Dispatch(@event, schema);
}
protected void On(SchemaFieldsReordered @event)
{
schema = SchemaEventDispatcher.Dispatch(@event, schema);
}
protected void On(SchemaPublished @event)
{
schema = SchemaEventDispatcher.Dispatch(@event, schema);
@ -112,7 +117,7 @@ namespace Squidex.Write.Schemas
VerifyCreatedAndNotDeleted();
RaiseEvent(SimpleMapper.Map(command, new FieldAdded { FieldId = new NamedId<long>(++totalFields, command.Name) }));
RaiseEvent(SimpleMapper.Map(command, new FieldAdded { FieldId = new NamedId<long>(totalFields + 1, command.Name) }));
return this;
}
@ -139,6 +144,17 @@ namespace Squidex.Write.Schemas
return this;
}
public SchemaDomainObject Reorder(ReorderFields command)
{
Guard.Valid(command, nameof(command), () => $"Cannot reorder fields for schema '{Id}'");
VerifyCreatedAndNotDeleted();
RaiseEvent(SimpleMapper.Map(command, new SchemaFieldsReordered()));
return this;
}
public SchemaDomainObject Update(UpdateSchema command)
{
Guard.Valid(command, nameof(command), () => $"Cannot update schema '{Id}'");

22
src/Squidex/Controllers/Api/Schemas/Models/ReorderFieldsDto.cs

@ -0,0 +1,22 @@
// ==========================================================================
// ReorderFieldsDto.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace Squidex.Controllers.Api.Schemas.Models
{
public class ReorderFieldsDto
{
/// <summary>
/// The field ids in the target order.
/// </summary>
[Required]
public List<long> FieldIds { get; set; }
}
}

50
src/Squidex/Controllers/Api/Schemas/SchemaFieldsController.cs

@ -40,9 +40,9 @@ namespace Squidex.Controllers.Api.Schemas
/// <param name="request">The field object that needs to be added to the schema.</param>
/// <returns>
/// 201 => Schema field created.
/// 409 => Schema field name already in use.
/// 404 => App or schema not found.
/// 400 => Schema field properties not valid.
/// 404 => Schema or app not found.
/// 409 => Schema field name already in use.
/// </returns>
[HttpPost]
[Route("apps/{app}/schemas/{name}/fields/")]
@ -61,6 +61,29 @@ namespace Squidex.Controllers.Api.Schemas
return StatusCode(201, response);
}
/// <summary>
/// Reorders the fields.
/// </summary>
/// <param name="app">The name of the app.</param>
/// <param name="name">The name of the schema.</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 => Schema or app not found.
/// </returns>
[HttpPost]
[Route("apps/{app}/schemas/{name}/fields/ordering")]
[ProducesResponseType(typeof(ErrorDto), 400)]
public async Task<IActionResult> PutFieldOrdering(string app, string name, [FromBody] ReorderFields request)
{
var command = new ReorderFields { FieldIds = request.FieldIds };
await CommandBus.PublishAsync(command);
return NoContent();
}
/// <summary>
/// Update a schema field.
/// </summary>
@ -69,10 +92,9 @@ namespace Squidex.Controllers.Api.Schemas
/// <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 created.
/// 409 => Schema field name already in use.
/// 404 => App, schema or field not found.
/// 204 => Schema field updated.
/// 400 => Schema field properties not valid.
/// 404 => Schema, field or app not found.
/// </returns>
[HttpPut]
[Route("apps/{app}/schemas/{name}/fields/{id:long}/")]
@ -94,9 +116,9 @@ namespace Squidex.Controllers.Api.Schemas
/// <param name="name">The name of the schema.</param>
/// <param name="id">The id of the field to hide.</param>
/// <returns>
/// 400 => Schema field already hidden.
/// 204 => Schema field hidden.
/// 404 => App, schema or field not found.
/// 400 => Schema field already hidden.
/// 404 => Schema, field or app not found.
/// </returns>
/// <remarks>
/// A hidden field is not part of the API response, but can still be edited in the portal.
@ -120,9 +142,9 @@ namespace Squidex.Controllers.Api.Schemas
/// <param name="name">The name of the schema.</param>
/// <param name="id">The id of the field to shows.</param>
/// <returns>
/// 400 => Schema field already visible.
/// 204 => Schema field shown.
/// 404 => App, schema or field not found.
/// 400 => Schema field already visible.
/// 404 => Schema, field or app not found.
/// </returns>
/// <remarks>
/// A hidden field is not part of the API response, but can still be edited in the portal.
@ -146,9 +168,9 @@ namespace Squidex.Controllers.Api.Schemas
/// <param name="name">The name of the schema.</param>
/// <param name="id">The id of the field to enable.</param>
/// <returns>
/// 400 => Schema field already enabled.
/// 204 => Schema field enabled.
/// 404 => App, schema or field not found.
/// 400 => Schema field already enabled.
/// 404 => Schema, field or app not found.
/// </returns>
/// <remarks>
/// A disabled field cannot not be edited in the squidex portal anymore,
@ -173,9 +195,9 @@ namespace Squidex.Controllers.Api.Schemas
/// <param name="name">The name of the schema.</param>
/// <param name="id">The id of the field to disable.</param>
/// <returns>
/// 400 => Schema field already disabled.
/// 204 => Schema field disabled.
/// 404 => App, schema or field not found.
/// 400 => Schema field already disabled.
/// 404 => Schema, field or app not found.
/// </returns>
/// <remarks>
/// A disabled field cannot not be edited in the squidex portal anymore,
@ -201,7 +223,7 @@ namespace Squidex.Controllers.Api.Schemas
/// <param name="id">The id of the field to disable.</param>
/// <returns>
/// 204 => Schema field deleted.
/// 404 => App, schema or field not found.
/// 404 => Schema, field or app not found.
/// </returns>
[HttpDelete]
[Route("apps/{app}/schemas/{name}/fields/{id:long}/")]

16
src/Squidex/Controllers/Api/Schemas/SchemasController.cs

@ -46,6 +46,7 @@ namespace Squidex.Controllers.Api.Schemas
/// </summary>
/// <returns>
/// 200 => Schemas returned.
/// 404 => App not found.
/// </returns>
[HttpGet]
[Route("apps/{app}/schemas/")]
@ -65,7 +66,7 @@ namespace Squidex.Controllers.Api.Schemas
/// <param name="name">The name of the schema to retrieve.</param>
/// <returns>
/// 200 => Schema found.
/// 404 => Schema not found.
/// 404 => Schema or app not found.
/// </returns>
[HttpGet]
[Route("apps/{app}/schemas/{name}/")]
@ -93,7 +94,7 @@ namespace Squidex.Controllers.Api.Schemas
/// <param name="app">The name of the app to create the schema to.</param>
/// <returns>
/// 201 => Schema created.
/// 400 => Schema name is not valid.
/// 400 => Schema name or properties are not valid.
/// 409 => Schema name already in use.
/// </returns>
[HttpPost]
@ -117,7 +118,9 @@ namespace Squidex.Controllers.Api.Schemas
/// <param name="name">The name of the schema.</param>
/// <param name="request">The schema object that needs to updated.</param>
/// <returns>
/// 204 => Schema updated.
/// 204 => Schema has been updated.
/// 400 => Schema properties are not valid.
/// 404 => Schema or app not found.
/// </returns>
[HttpPut]
[Route("apps/{app}/schemas/{name}/")]
@ -136,8 +139,9 @@ namespace Squidex.Controllers.Api.Schemas
/// <param name="app">The app where the schema is a part of.</param>
/// <param name="name">The name of the schema to publish.</param>
/// <returns>
/// 204 => Schema has been published.
/// 400 => Schema is already published.
/// 204 => Schema has been deleted.
/// 404 => Schema or app not found.
/// </returns>
[HttpPut]
[Route("apps/{app}/schemas/{name}/publish")]
@ -155,8 +159,9 @@ namespace Squidex.Controllers.Api.Schemas
/// <param name="app">The app where the schema is a part of.</param>
/// <param name="name">The name of the schema to unpublish.</param>
/// <returns>
/// 204 => Schema has been unpublished.
/// 400 => Schema is not published.
/// 204 => Schema has been deleted.
/// 404 => Schema or app not found.
/// </returns>
[HttpPut]
[Route("apps/{app}/schemas/{name}/unpublish")]
@ -175,6 +180,7 @@ namespace Squidex.Controllers.Api.Schemas
/// <param name="name">The name of the schema to delete.</param>
/// <returns>
/// 204 => Schema has been deleted.
/// 404 => Schema or app not found.
/// </returns>
[HttpDelete]
[Route("apps/{app}/schemas/{name}/")]

14
tests/Squidex.Write.Tests/Schemas/SchemaCommandHandlerTests.cs

@ -7,6 +7,7 @@
// ==========================================================================
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Moq;
using Squidex.Core.Schemas;
@ -84,6 +85,19 @@ namespace Squidex.Write.Schemas
});
}
[Fact]
public async Task ReorderSchema_should_update_domain_object()
{
CreateSchema();
var context = CreateContextForCommand(new ReorderFields { FieldIds = new List<long>() });
await TestUpdate(schema, async _ =>
{
await sut.HandleAsync(context);
});
}
[Fact]
public async Task PublishSchema_should_update_domain_object()
{

58
tests/Squidex.Write.Tests/Schemas/SchemaDomainObjectTests.cs

@ -6,6 +6,7 @@
// All rights reserved.
// ==========================================================================
using System.Collections.Generic;
using System.Linq;
using Squidex.Core.Schemas;
using Squidex.Events.Schemas;
@ -68,6 +69,7 @@ namespace Squidex.Write.Schemas
CreateEvent(new SchemaCreated { Name = SchemaName, Properties = properties })
);
}
[Fact]
public void Update_should_throw_if_not_created()
{
@ -83,9 +85,9 @@ namespace Squidex.Write.Schemas
CreateSchema();
DeleteSchema();
Assert.Throws<ValidationException>(() =>
Assert.Throws<DomainException>(() =>
{
sut.Update(CreateCommand(new UpdateSchema()));
sut.Update(CreateCommand(new UpdateSchema { Properties = new SchemaProperties() }));
});
}
@ -117,6 +119,58 @@ namespace Squidex.Write.Schemas
);
}
[Fact]
public void Reorder_should_throw_if_not_created()
{
Assert.Throws<DomainException>(() =>
{
sut.Reorder(CreateCommand(new ReorderFields { FieldIds = new List<long>() }));
});
}
[Fact]
public void Reorder_should_throw_if_schema_is_deleted()
{
CreateSchema();
DeleteSchema();
Assert.Throws<DomainException>(() =>
{
sut.Reorder(CreateCommand(new ReorderFields { FieldIds = new List<long>() }));
});
}
[Fact]
public void Reorder_should_throw_if_command_is_not_valid()
{
CreateSchema();
Assert.Throws<ValidationException>(() =>
{
sut.Reorder(CreateCommand(new ReorderFields()));
});
}
[Fact]
public void Reorder_should_refresh_properties_and_create_events()
{
var fieldIds = new List<long> { 1, 2 };
CreateSchema();
sut.AddField(new AddField { Name = "field1", Properties = new StringFieldProperties() });
sut.AddField(new AddField { Name = "field2", Properties = new StringFieldProperties() });
((IAggregate)sut).ClearUncommittedEvents();
sut.Reorder(CreateCommand(new ReorderFields { FieldIds = fieldIds }));
sut.GetUncomittedEvents()
.ShouldHaveSameEvents(
CreateEvent(new SchemaFieldsReordered { FieldIds = fieldIds })
);
}
[Fact]
public void Publish_should_throw_if_not_created()
{

Loading…
Cancel
Save