V14: Additional blueprint endpoints (#16047)
* Fix /item endpoint response when 0 ids * Adding GetPagedByContentTypeKeyAsync to IContentBlueprintEditingService * Adding mapping for new DocumentTypeBlueprintItemResponseModel * New endpoint and operation status handling * Fix test cases * Added tests * Fixed partial test references * Rename method * Add ancestors endpoint for blueprints * Change == to is Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com> --------- Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
2a889f502b
commit
3edc783ddb
@@ -29,6 +29,11 @@ public class ItemDocumentBlueprintController : DocumentBlueprintItemControllerBa
|
||||
CancellationToken cancellationToken,
|
||||
[FromQuery(Name = "id")] HashSet<Guid> ids)
|
||||
{
|
||||
if (ids.Count is 0)
|
||||
{
|
||||
return Ok(Enumerable.Empty<DocumentBlueprintItemResponseModel>());
|
||||
}
|
||||
|
||||
IEnumerable<IDocumentEntitySlim> documents = _entityService
|
||||
.GetAll(UmbracoObjectTypes.DocumentBlueprint, ids.ToArray())
|
||||
.Select(x => x as IDocumentEntitySlim)
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Tree;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DocumentBlueprint.Tree;
|
||||
|
||||
[ApiVersion("1.0")]
|
||||
public class AncestorsDocumentBlueprintTreeController : DocumentBlueprintTreeControllerBase
|
||||
{
|
||||
public AncestorsDocumentBlueprintTreeController(IEntityService entityService, IDocumentPresentationFactory documentPresentationFactory)
|
||||
: base(entityService, documentPresentationFactory)
|
||||
{
|
||||
}
|
||||
|
||||
[HttpGet("ancestors")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(IEnumerable<DocumentBlueprintTreeItemResponseModel>), StatusCodes.Status200OK)]
|
||||
public async Task<ActionResult<IEnumerable<DocumentBlueprintTreeItemResponseModel>>> Ancestors(CancellationToken cancellationToken, Guid descendantId)
|
||||
=> await GetAncestors(descendantId);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.DocumentType;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Mapping;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
using Umbraco.Cms.Web.Common.Authorization;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DocumentType;
|
||||
|
||||
[ApiVersion("1.0")]
|
||||
[Authorize(Policy = AuthorizationPolicies.SectionAccessContent)]
|
||||
public class DocumentBlueprintForDocumentTypeController : DocumentTypeControllerBase
|
||||
{
|
||||
private readonly IContentBlueprintEditingService _contentBlueprintEditingService;
|
||||
|
||||
private readonly IUmbracoMapper _umbracoMapper;
|
||||
|
||||
public DocumentBlueprintForDocumentTypeController(IContentBlueprintEditingService contentBlueprintEditingService, IUmbracoMapper umbracoMapper)
|
||||
{
|
||||
_contentBlueprintEditingService = contentBlueprintEditingService;
|
||||
_umbracoMapper = umbracoMapper;
|
||||
}
|
||||
|
||||
[HttpGet("{id:guid}/blueprint")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(PagedViewModel<DocumentTypeBlueprintItemResponseModel>), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
public async Task<IActionResult> DocumentBlueprintByDocumentTypeKey(
|
||||
CancellationToken cancellationToken,
|
||||
Guid id,
|
||||
int skip = 0,
|
||||
int take = 100)
|
||||
{
|
||||
Attempt<PagedModel<IContent>?, ContentEditingOperationStatus> attempt = await _contentBlueprintEditingService.GetPagedByContentTypeAsync(id, skip, take);
|
||||
if (attempt.Success is false)
|
||||
{
|
||||
return ContentEditingOperationStatusResult(attempt.Status);
|
||||
}
|
||||
|
||||
List<DocumentTypeBlueprintItemResponseModel> viewModels = _umbracoMapper.MapEnumerable<IContent, DocumentTypeBlueprintItemResponseModel>(attempt.Result!.Items);
|
||||
|
||||
var pagedViewModel = new PagedViewModel<DocumentTypeBlueprintItemResponseModel>
|
||||
{
|
||||
Total = attempt.Result!.Total,
|
||||
Items = viewModels,
|
||||
};
|
||||
|
||||
return Ok(pagedViewModel);
|
||||
}
|
||||
}
|
||||
@@ -107,4 +107,15 @@ public abstract class DocumentTypeControllerBase : ManagementApiControllerBase
|
||||
.Build()),
|
||||
_ => new ObjectResult("Unknown content type structure operation status") { StatusCode = StatusCodes.Status500InternalServerError }
|
||||
});
|
||||
|
||||
protected IActionResult ContentEditingOperationStatusResult(ContentEditingOperationStatus status) =>
|
||||
OperationStatusResult(status, problemDetailsBuilder => status switch
|
||||
{
|
||||
ContentEditingOperationStatus.ContentTypeNotFound => NotFound(problemDetailsBuilder
|
||||
.WithTitle("The specified document type was not found")
|
||||
.Build()),
|
||||
_ => StatusCode(StatusCodes.Status500InternalServerError, problemDetailsBuilder
|
||||
.WithTitle("Unknown content editing operation status")
|
||||
.Build()),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ public class DocumentTypeMapDefinition : ContentTypeMapDefinition<IContentType,
|
||||
mapper.Define<ISimpleContentType, DocumentTypeCollectionReferenceResponseModel>((_, _) => new DocumentTypeCollectionReferenceResponseModel(), Map);
|
||||
mapper.Define<IContentEntitySlim, DocumentTypeReferenceResponseModel>((_, _) => new DocumentTypeReferenceResponseModel(), Map);
|
||||
mapper.Define<IDocumentEntitySlim, DocumentTypeReferenceResponseModel>((_, _) => new DocumentTypeReferenceResponseModel(), Map);
|
||||
mapper.Define<IContent, DocumentTypeBlueprintItemResponseModel>((_, _) => new DocumentTypeBlueprintItemResponseModel(), Map);
|
||||
}
|
||||
|
||||
// Umbraco.Code.MapAll
|
||||
@@ -114,4 +115,11 @@ public class DocumentTypeMapDefinition : ContentTypeMapDefinition<IContentType,
|
||||
target.Alias = source.Alias;
|
||||
target.Icon = source.Icon ?? string.Empty;
|
||||
}
|
||||
|
||||
// Umbraco.Code.MapAll
|
||||
private void Map(IContent source, DocumentTypeBlueprintItemResponseModel target, MapperContext context)
|
||||
{
|
||||
target.Id = source.Key;
|
||||
target.Name = source.Name ?? string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Item;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.ViewModels.DocumentType;
|
||||
|
||||
public class DocumentTypeBlueprintItemResponseModel : NamedItemResponseModelBase
|
||||
{
|
||||
}
|
||||
@@ -31,6 +31,25 @@ internal sealed class ContentBlueprintEditingService
|
||||
return await Task.FromResult(blueprint);
|
||||
}
|
||||
|
||||
public async Task<Attempt<PagedModel<IContent>?, ContentEditingOperationStatus>> GetPagedByContentTypeAsync(Guid contentTypeKey, int skip, int take)
|
||||
{
|
||||
IContentType? contentType = await ContentTypeService.GetAsync(contentTypeKey);
|
||||
if (contentType is null)
|
||||
{
|
||||
return Attempt.FailWithStatus<PagedModel<IContent>?, ContentEditingOperationStatus>(ContentEditingOperationStatus.ContentTypeNotFound, null);
|
||||
}
|
||||
|
||||
IContent[] blueprints = ContentService.GetBlueprintsForContentTypes([contentType.Id]).ToArray();
|
||||
|
||||
var result = new PagedModel<IContent>
|
||||
{
|
||||
Items = blueprints.Skip(skip).Take(take),
|
||||
Total = blueprints.Length,
|
||||
};
|
||||
|
||||
return Attempt.SucceedWithStatus<PagedModel<IContent>?, ContentEditingOperationStatus>(ContentEditingOperationStatus.Success, result);
|
||||
}
|
||||
|
||||
public async Task<Attempt<ContentCreateResult, ContentEditingOperationStatus>> CreateAsync(ContentBlueprintCreateModel createModel, Guid userKey)
|
||||
{
|
||||
if (await ValidateCulturesAsync(createModel) is false)
|
||||
|
||||
@@ -8,6 +8,11 @@ public interface IContentBlueprintEditingService
|
||||
{
|
||||
Task<IContent?> GetAsync(Guid key);
|
||||
|
||||
Task<Attempt<PagedModel<IContent>?, ContentEditingOperationStatus>> GetPagedByContentTypeAsync(
|
||||
Guid contentTypeKey,
|
||||
int skip,
|
||||
int take);
|
||||
|
||||
Task<Attempt<ContentCreateResult, ContentEditingOperationStatus>> CreateAsync(ContentBlueprintCreateModel createModel, Guid userKey);
|
||||
|
||||
Task<Attempt<ContentCreateResult, ContentEditingOperationStatus>> CreateFromContentAsync(Guid contentKey, string name, Guid? key, Guid userKey);
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services;
|
||||
public partial class ContentBlueprintEditingServiceTests
|
||||
{
|
||||
[TestCase(true)]
|
||||
[TestCase(true)]
|
||||
[TestCase(false)]
|
||||
public async Task Can_Get(bool variant)
|
||||
{
|
||||
var blueprint = await (variant ? CreateVariantContentBlueprint() : CreateInvariantContentBlueprint());
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services;
|
||||
|
||||
public partial class ContentBlueprintEditingServiceTests
|
||||
{
|
||||
[Test]
|
||||
public async Task Can_Get_Paged()
|
||||
{
|
||||
var contentType = CreateInvariantContentType();
|
||||
|
||||
for (var i = 1; i < 6; i++)
|
||||
{
|
||||
var createModel = new ContentBlueprintCreateModel
|
||||
{
|
||||
ContentTypeKey = contentType.Key,
|
||||
InvariantName = $"Blueprint {i}",
|
||||
};
|
||||
|
||||
await ContentBlueprintEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey);
|
||||
}
|
||||
|
||||
var result = await ContentBlueprintEditingService.GetPagedByContentTypeAsync(contentType.Key, 0, 2);
|
||||
|
||||
var pagedResult = result.Result;
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.IsTrue(result.Success);
|
||||
Assert.AreEqual(ContentEditingOperationStatus.Success, result.Status);
|
||||
Assert.IsNotNull(pagedResult);
|
||||
});
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(2, pagedResult.Items.Count());
|
||||
Assert.AreEqual(5, pagedResult.Total);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Cannot_Get_Paged_With_Non_Existing_Content_Type()
|
||||
{
|
||||
var result = await ContentBlueprintEditingService.GetPagedByContentTypeAsync(Guid.NewGuid(), 0, 10);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.IsFalse(result.Success);
|
||||
Assert.AreEqual(ContentEditingOperationStatus.ContentTypeNotFound, result.Status);
|
||||
Assert.IsNull(result.Result);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services;
|
||||
public partial class ContentEditingServiceTests
|
||||
{
|
||||
[TestCase(true)]
|
||||
[TestCase(true)]
|
||||
[TestCase(false)]
|
||||
public async Task Can_Get(bool variant)
|
||||
{
|
||||
var content = await (variant ? CreateVariantContent() : CreateInvariantContent());
|
||||
|
||||
@@ -139,6 +139,12 @@
|
||||
<Compile Update="Umbraco.Infrastructure\Services\ContentBlueprintEditingServiceTests.Get.cs">
|
||||
<DependentUpon>ContentBlueprintEditingServiceTests.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Umbraco.Infrastructure\Services\ContentBlueprintEditingServiceTests.GetPagedByContentTypeKey.cs">
|
||||
<DependentUpon>ContentBlueprintEditingServiceTests.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Umbraco.Infrastructure\Services\ContentBlueprintEditingServiceTests.Move.cs">
|
||||
<DependentUpon>ContentBlueprintEditingServiceTests.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Umbraco.Infrastructure\Services\ContentBlueprintEditingServiceTests.Update.cs">
|
||||
<DependentUpon>ContentBlueprintEditingServiceTests.cs</DependentUpon>
|
||||
</Compile>
|
||||
|
||||
Reference in New Issue
Block a user