V14: Member group controller (#15669)
* Add models & mapping * Add controller * Add create async to service * Add auth policy * Implement delete * Rename response model * Implement updateAsync * Refactor update to use own model * Implement all async counterparts for IMemberService * Add tests * Implement update member group mapping * Dont fail if updating the current user group * Return not found if not found * Add missing OperationResults to MemberGroupOperationStatusResult * Add 404 to response type * Update openapi * Update OpenApi * Update OpenApi.json
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.MemberGroup;
|
||||
using Umbraco.Cms.Core.Mapping;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.MemberGroup;
|
||||
|
||||
[ApiVersion("1.0")]
|
||||
public class AllMemberGroupController : MemberGroupControllerBase
|
||||
{
|
||||
private readonly IMemberGroupService _memberGroupService;
|
||||
private readonly IUmbracoMapper _mapper;
|
||||
|
||||
public AllMemberGroupController(IMemberGroupService memberGroupService, IUmbracoMapper mapper)
|
||||
{
|
||||
_memberGroupService = memberGroupService;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(PagedViewModel<MemberGroupResponseModel>), StatusCodes.Status200OK)]
|
||||
public async Task<ActionResult<PagedViewModel<MemberGroupResponseModel>>> All(int skip = 0, int take = 100)
|
||||
{
|
||||
IMemberGroup[] memberGroups = (await _memberGroupService.GetAllAsync()).ToArray();
|
||||
var viewModel = new PagedViewModel<MemberGroupResponseModel>
|
||||
{
|
||||
Total = memberGroups.Length,
|
||||
Items = _mapper.MapEnumerable<IMemberGroup, MemberGroupResponseModel>(memberGroups.Skip(skip).Take(take)),
|
||||
};
|
||||
|
||||
return await Task.FromResult(Ok(viewModel));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.MemberGroup;
|
||||
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;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.MemberGroup;
|
||||
|
||||
[ApiVersion("1.0")]
|
||||
public class CreateMemberGroupController : MemberGroupControllerBase
|
||||
{
|
||||
private readonly IMemberGroupService _memberGroupService;
|
||||
private readonly IUmbracoMapper _mapper;
|
||||
|
||||
public CreateMemberGroupController(IMemberGroupService memberGroupService, IUmbracoMapper mapper)
|
||||
{
|
||||
_memberGroupService = memberGroupService;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(MemberGroupResponseModel), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
public async Task<IActionResult> Create(CreateMemberGroupRequestModel model)
|
||||
{
|
||||
IMemberGroup? memberGroup = _mapper.Map<IMemberGroup>(model);
|
||||
Attempt<IMemberGroup?, MemberGroupOperationStatus> result = await _memberGroupService.CreateAsync(memberGroup!);
|
||||
return result.Success
|
||||
? Ok(_mapper.Map<MemberGroupResponseModel>(result.Result))
|
||||
: MemberGroupOperationStatusResult(result.Status);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.MemberGroup;
|
||||
|
||||
[ApiVersion("1.0")]
|
||||
public class DeleteMemberGroupController : MemberGroupControllerBase
|
||||
{
|
||||
private readonly IMemberGroupService _memberGroupService;
|
||||
|
||||
public DeleteMemberGroupController(IMemberGroupService memberGroupService) => _memberGroupService = memberGroupService;
|
||||
|
||||
[HttpDelete("{key:guid}")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public async Task<IActionResult> Delete(Guid key)
|
||||
{
|
||||
Attempt<IMemberGroup?, MemberGroupOperationStatus> result = await _memberGroupService.DeleteAsync(key);
|
||||
return result.Success
|
||||
? Ok()
|
||||
: MemberGroupOperationStatusResult(result.Status);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Common.Builders;
|
||||
using Umbraco.Cms.Api.Management.Routing;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
using Umbraco.Cms.Web.Common.Authorization;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.MemberGroup;
|
||||
|
||||
[ApiController]
|
||||
[VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.MemberGroup}")]
|
||||
[ApiExplorerSettings(GroupName = "Member Group")]
|
||||
[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessMembers)]
|
||||
public class MemberGroupControllerBase : ManagementApiControllerBase
|
||||
{
|
||||
protected IActionResult MemberGroupOperationStatusResult(MemberGroupOperationStatus status) =>
|
||||
status switch
|
||||
{
|
||||
MemberGroupOperationStatus.Success => Ok(),
|
||||
MemberGroupOperationStatus.NotFound => MemberGroupNotFound(),
|
||||
MemberGroupOperationStatus.CancelledByNotification => BadRequest(new ProblemDetailsBuilder()
|
||||
.WithTitle("Cancelled by notification")
|
||||
.WithDetail("A notification handler prevented the member group operation.")
|
||||
.Build()),
|
||||
MemberGroupOperationStatus.CannotHaveEmptyName => BadRequest(new ProblemDetailsBuilder()
|
||||
.WithTitle("Name was empty or null")
|
||||
.WithDetail("The provided member group name cannot be null or empty.")
|
||||
.Build()),
|
||||
MemberGroupOperationStatus.DuplicateName => BadRequest(new ProblemDetailsBuilder()
|
||||
.WithTitle("Duplicate name")
|
||||
.WithDetail("Another group with the same name already exists.")
|
||||
.Build()),
|
||||
MemberGroupOperationStatus.DuplicateKey => BadRequest(new ProblemDetailsBuilder()
|
||||
.WithTitle("Duplicate key")
|
||||
.WithDetail("Another group with the same key already exists.")
|
||||
.Build()),
|
||||
_ => StatusCode(StatusCodes.Status500InternalServerError, new ProblemDetailsBuilder()
|
||||
.WithTitle("Unknown member group operation status.")
|
||||
.Build()),
|
||||
};
|
||||
|
||||
protected IActionResult MemberGroupNotFound() => OperationStatusResult(MemberGroupOperationStatus.NotFound, problemDetailsBuilder
|
||||
=> NotFound(problemDetailsBuilder
|
||||
.WithTitle("The requested member group could not be found")
|
||||
.Build()));
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.MemberGroup;
|
||||
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;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.MemberGroup;
|
||||
|
||||
[ApiVersion("1.0")]
|
||||
public class UpdateMemberGroupController : MemberGroupControllerBase
|
||||
{
|
||||
private readonly IUmbracoMapper _mapper;
|
||||
private readonly IMemberGroupService _memberGroupService;
|
||||
|
||||
public UpdateMemberGroupController(IUmbracoMapper mapper, IMemberGroupService memberGroupService)
|
||||
{
|
||||
_mapper = mapper;
|
||||
_memberGroupService = memberGroupService;
|
||||
}
|
||||
|
||||
[HttpPut($"{{{nameof(id)}:guid}}")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(MemberGroupResponseModel), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
public async Task<IActionResult> Update(Guid id, UpdateMemberGroupRequestModel model)
|
||||
{
|
||||
IMemberGroup? current = await _memberGroupService.GetAsync(id);
|
||||
if (current is null)
|
||||
{
|
||||
return MemberGroupNotFound();
|
||||
}
|
||||
|
||||
IMemberGroup updated = _mapper.Map(model, current);
|
||||
|
||||
Attempt<IMemberGroup?, MemberGroupOperationStatus> result = await _memberGroupService.UpdateAsync(updated);
|
||||
return result.Success
|
||||
? Ok(_mapper.Map<MemberGroupResponseModel>(result.Result))
|
||||
: MemberGroupOperationStatusResult(result.Status);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using Umbraco.Cms.Api.Management.Mapping.MemberGroup;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Mapping;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.DependencyInjection;
|
||||
|
||||
public static class MemberGroupsBuilderExtensions
|
||||
{
|
||||
internal static IUmbracoBuilder AddMemberGroups(this IUmbracoBuilder builder)
|
||||
{
|
||||
builder.WithCollectionBuilder<MapDefinitionCollectionBuilder>()
|
||||
.Add<MemberGroupMapDefinition>();
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,7 @@ public static partial class UmbracoBuilderExtensions
|
||||
.AddDocumentTypes()
|
||||
.AddMedia()
|
||||
.AddMediaTypes()
|
||||
.AddMemberGroups()
|
||||
.AddMember()
|
||||
.AddMemberTypes()
|
||||
.AddLanguages()
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
using Umbraco.Cms.Api.Management.ViewModels.MemberGroup;
|
||||
using Umbraco.Cms.Core.Mapping;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Mapping.MemberGroup;
|
||||
|
||||
public class MemberGroupMapDefinition : IMapDefinition
|
||||
{
|
||||
public void DefineMaps(IUmbracoMapper mapper)
|
||||
{
|
||||
mapper.Define<CreateMemberGroupRequestModel, IMemberGroup>((_, _) => new Core.Models.MemberGroup(), Map);
|
||||
mapper.Define<UpdateMemberGroupRequestModel, IMemberGroup>((_, _) => new Core.Models.MemberGroup(), Map);
|
||||
mapper.Define<IMemberGroup, MemberGroupResponseModel>((_, _) => new MemberGroupResponseModel { Name = string.Empty }, Map);
|
||||
}
|
||||
|
||||
// Umbraco.Code.MapAll -Id -CreateDate -CreatorId -DeleteDate -UpdateDate
|
||||
private static void Map(CreateMemberGroupRequestModel source, IMemberGroup target, MapperContext context)
|
||||
{
|
||||
target.Name = source.Name;
|
||||
target.Key = source.Id ?? Guid.NewGuid();
|
||||
}
|
||||
|
||||
// Umbraco.Code.MapAll -Id -CreateDate -CreatorId -DeleteDate -UpdateDate -Key
|
||||
private static void Map(UpdateMemberGroupRequestModel source, IMemberGroup target, MapperContext context) => target.Name = source.Name;
|
||||
|
||||
// Umbraco.Code.MapAll
|
||||
private static void Map(IMemberGroup source, MemberGroupResponseModel target, MapperContext context)
|
||||
{
|
||||
target.Name = source.Name ?? string.Empty;
|
||||
target.Id = source.Key;
|
||||
}
|
||||
}
|
||||
@@ -15125,6 +15125,463 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/umbraco/management/api/v1/member-group": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Member Group"
|
||||
],
|
||||
"operationId": "GetMemberGroup",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "skip",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"default": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "take",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"default": 100
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/PagedMemberGroupResponseModel"
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/PagedMemberGroupResponseModel"
|
||||
}
|
||||
},
|
||||
"text/plain": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/PagedMemberGroupResponseModel"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "The resource is protected and requires an authentication token"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"Backoffice User": [ ]
|
||||
}
|
||||
]
|
||||
},
|
||||
"post": {
|
||||
"tags": [
|
||||
"Member Group"
|
||||
],
|
||||
"operationId": "PostMemberGroup",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/CreateMemberGroupRequestModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/CreateMemberGroupRequestModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"application/*+json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/CreateMemberGroupRequestModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"headers": {
|
||||
"Umb-Notifications": {
|
||||
"description": "The list of notifications produced during the request.",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NotificationHeaderModel"
|
||||
},
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/MemberGroupResponseModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/MemberGroupResponseModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"text/plain": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/MemberGroupResponseModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"headers": {
|
||||
"Umb-Notifications": {
|
||||
"description": "The list of notifications produced during the request.",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NotificationHeaderModel"
|
||||
},
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
},
|
||||
"text/plain": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "The resource is protected and requires an authentication token"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"Backoffice User": [ ]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/umbraco/management/api/v1/member-group/{id}": {
|
||||
"put": {
|
||||
"tags": [
|
||||
"Member Group"
|
||||
],
|
||||
"operationId": "PutMemberGroupById",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/UpdateMemberGroupRequestModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/UpdateMemberGroupRequestModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"application/*+json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/UpdateMemberGroupRequestModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"headers": {
|
||||
"Umb-Notifications": {
|
||||
"description": "The list of notifications produced during the request.",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NotificationHeaderModel"
|
||||
},
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/MemberGroupResponseModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/MemberGroupResponseModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"text/plain": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/MemberGroupResponseModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"headers": {
|
||||
"Umb-Notifications": {
|
||||
"description": "The list of notifications produced during the request.",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NotificationHeaderModel"
|
||||
},
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
},
|
||||
"text/plain": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"headers": {
|
||||
"Umb-Notifications": {
|
||||
"description": "The list of notifications produced during the request.",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NotificationHeaderModel"
|
||||
},
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
},
|
||||
"text/plain": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "The resource is protected and requires an authentication token"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"Backoffice User": [ ]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/umbraco/management/api/v1/member-group/{key}": {
|
||||
"delete": {
|
||||
"tags": [
|
||||
"Member Group"
|
||||
],
|
||||
"operationId": "DeleteMemberGroupByKey",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "key",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"headers": {
|
||||
"Umb-Notifications": {
|
||||
"description": "The list of notifications produced during the request.",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NotificationHeaderModel"
|
||||
},
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
},
|
||||
"text/plain": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"headers": {
|
||||
"Umb-Notifications": {
|
||||
"description": "The list of notifications produced during the request.",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NotificationHeaderModel"
|
||||
},
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
},
|
||||
"text/plain": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"headers": {
|
||||
"Umb-Notifications": {
|
||||
"description": "The list of notifications produced during the request.",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NotificationHeaderModel"
|
||||
},
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "The resource is protected and requires an authentication token"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"Backoffice User": [ ]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/umbraco/management/api/v1/tree/member-group/root": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@@ -32000,6 +32457,22 @@
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"CreateMemberGroupRequestModel": {
|
||||
"type": "object",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/MemberGroupPresentationBaseModel"
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"CreateMemberRequestModel": {
|
||||
"required": [
|
||||
"email",
|
||||
@@ -34994,6 +35467,36 @@
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"MemberGroupPresentationBaseModel": {
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"MemberGroupResponseModel": {
|
||||
"required": [
|
||||
"id"
|
||||
],
|
||||
"type": "object",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/MemberGroupPresentationBaseModel"
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"MemberItemResponseModel": {
|
||||
"required": [
|
||||
"memberType",
|
||||
@@ -36218,6 +36721,30 @@
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"PagedMemberGroupResponseModel": {
|
||||
"required": [
|
||||
"items",
|
||||
"total"
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"total": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/MemberGroupResponseModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"PagedMemberResponseModel": {
|
||||
"required": [
|
||||
"items",
|
||||
@@ -38777,6 +39304,15 @@
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"UpdateMemberGroupRequestModel": {
|
||||
"type": "object",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/MemberGroupPresentationBaseModel"
|
||||
}
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"UpdateMemberRequestModel": {
|
||||
"required": [
|
||||
"email",
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Umbraco.Cms.Api.Management.ViewModels.MemberGroup;
|
||||
|
||||
public class CreateMemberGroupRequestModel : MemberGroupPresentationBase
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Umbraco.Cms.Api.Management.ViewModels.MemberGroup;
|
||||
|
||||
public class MemberGroupPresentationBase
|
||||
{
|
||||
public required string Name { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Umbraco.Cms.Api.Management.ViewModels.MemberGroup;
|
||||
|
||||
public class MemberGroupResponseModel : MemberGroupPresentationBase
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
namespace Umbraco.Cms.Api.Management.ViewModels.MemberGroup;
|
||||
|
||||
public class UpdateMemberGroupRequestModel : MemberGroupPresentationBase
|
||||
{
|
||||
}
|
||||
@@ -1,20 +1,74 @@
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
namespace Umbraco.Cms.Core.Services;
|
||||
|
||||
public interface IMemberGroupService : IService
|
||||
{
|
||||
[Obsolete("Please use the asynchronous counterpart. Scheduled for removal in v15.")]
|
||||
IEnumerable<IMemberGroup> GetAll();
|
||||
|
||||
[Obsolete("Please use Guid instead of Int id. Scheduled for removal in v15.")]
|
||||
IMemberGroup? GetById(int id);
|
||||
|
||||
[Obsolete("Please use the asynchronous counterpart. Scheduled for removal in v15.")]
|
||||
IMemberGroup? GetById(Guid id);
|
||||
|
||||
[Obsolete("Please use the asynchronous counterpart. Scheduled for removal in v15.")]
|
||||
IEnumerable<IMemberGroup> GetByIds(IEnumerable<int> ids);
|
||||
|
||||
IMemberGroup? GetByName(string? name);
|
||||
|
||||
[Obsolete("Please use the respective CreateAsync/UpdateAsync for you save operations. Scheduled for removal in v15.")]
|
||||
void Save(IMemberGroup memberGroup);
|
||||
|
||||
[Obsolete("Please use the asynchronous counterpart. Scheduled for removal in v15.")]
|
||||
void Delete(IMemberGroup memberGroup);
|
||||
|
||||
/// <summary>
|
||||
/// Get a member group by name.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the member group to get.</param>
|
||||
/// <returns>A <see cref="IMemberGroup" /> object.</returns>
|
||||
Task<IMemberGroup?> GetByNameAsync(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Get a member group by key.
|
||||
/// </summary>
|
||||
/// <param name="key"><see cref="Guid" /> of the member group to get.</param>
|
||||
/// <returns>A <see cref="IMemberGroup" /> object.</returns>
|
||||
Task<IMemberGroup?> GetAsync(Guid key);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all member groups
|
||||
/// </summary>
|
||||
/// <returns>An enumerable list of <see cref="IMemberGroup" /> objects.</returns>
|
||||
Task<IEnumerable<IMemberGroup>> GetAllAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of member groups with the given ids.
|
||||
/// </summary>
|
||||
/// <param name="ids">An enumerable list of <see cref="int" /> ids, to get the member groups by.</param>
|
||||
/// <returns>An enumerable list of <see cref="IMemberGroup" /> objects.</returns>
|
||||
Task<IEnumerable<IMemberGroup>> GetByIdsAsync(IEnumerable<int> ids);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="IMemberGroup" /> object
|
||||
/// </summary>
|
||||
/// <param name="memberGroup"><see cref="IMemberGroup" /> to create</param>
|
||||
/// <returns>An attempt with a status of whether the operation was successful or not, and the created object if it succeeded.</returns>
|
||||
Task<Attempt<IMemberGroup?, MemberGroupOperationStatus>> CreateAsync(IMemberGroup memberGroup);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a <see cref="IMemberGroup" /> by removing it and its usages from the db
|
||||
/// </summary>
|
||||
/// <param name="key">The key of the <see cref="IMemberGroup" /> to delete</param>
|
||||
Task<Attempt<IMemberGroup?, MemberGroupOperationStatus>> DeleteAsync(Guid key);
|
||||
|
||||
/// <summary>
|
||||
/// Updates <see cref="IMemberGroup" /> object
|
||||
/// </summary>
|
||||
/// <param name="memberGroup"><see cref="IMemberGroup" /> to create</param>
|
||||
/// <returns>An attempt with a status of whether the operation was successful or not, and the object.</returns>
|
||||
Task<Attempt<IMemberGroup?, MemberGroupOperationStatus>> UpdateAsync(IMemberGroup memberGroup);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Notifications;
|
||||
using Umbraco.Cms.Core.Persistence.Repositories;
|
||||
using Umbraco.Cms.Core.Scoping;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
namespace Umbraco.Cms.Core.Services;
|
||||
|
||||
@@ -15,26 +16,9 @@ internal class MemberGroupService : RepositoryService, IMemberGroupService
|
||||
: base(provider, loggerFactory, eventMessagesFactory) =>
|
||||
_memberGroupRepository = memberGroupRepository;
|
||||
|
||||
public IEnumerable<IMemberGroup> GetAll()
|
||||
{
|
||||
using (ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true))
|
||||
{
|
||||
return _memberGroupRepository.GetMany();
|
||||
}
|
||||
}
|
||||
public IEnumerable<IMemberGroup> GetAll() => GetAllAsync().GetAwaiter().GetResult();
|
||||
|
||||
public IEnumerable<IMemberGroup> GetByIds(IEnumerable<int> ids)
|
||||
{
|
||||
if (ids == null || ids.Any() == false)
|
||||
{
|
||||
return new IMemberGroup[0];
|
||||
}
|
||||
|
||||
using (ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true))
|
||||
{
|
||||
return _memberGroupRepository.GetMany(ids.ToArray());
|
||||
}
|
||||
}
|
||||
public IEnumerable<IMemberGroup> GetByIds(IEnumerable<int> ids) => GetByIdsAsync(ids).GetAwaiter().GetResult();
|
||||
|
||||
public IMemberGroup? GetById(int id)
|
||||
{
|
||||
@@ -44,21 +28,9 @@ internal class MemberGroupService : RepositoryService, IMemberGroupService
|
||||
}
|
||||
}
|
||||
|
||||
public IMemberGroup? GetById(Guid id)
|
||||
{
|
||||
using (ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true))
|
||||
{
|
||||
return _memberGroupRepository.Get(id);
|
||||
}
|
||||
}
|
||||
public IMemberGroup? GetById(Guid id) => GetAsync(id).GetAwaiter().GetResult();
|
||||
|
||||
public IMemberGroup? GetByName(string? name)
|
||||
{
|
||||
using (ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true))
|
||||
{
|
||||
return _memberGroupRepository.GetByName(name);
|
||||
}
|
||||
}
|
||||
public IMemberGroup? GetByName(string? name) => name is null ? null : GetByNameAsync(name).GetAwaiter().GetResult();
|
||||
|
||||
public void Save(IMemberGroup memberGroup)
|
||||
{
|
||||
@@ -86,24 +58,139 @@ internal class MemberGroupService : RepositoryService, IMemberGroupService
|
||||
}
|
||||
}
|
||||
|
||||
public void Delete(IMemberGroup memberGroup)
|
||||
public void Delete(IMemberGroup memberGroup) => DeleteAsync(memberGroup.Key).GetAwaiter().GetResult();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Task<IMemberGroup?> GetByNameAsync(string name)
|
||||
{
|
||||
EventMessages evtMsgs = EventMessagesFactory.Get();
|
||||
using ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true);
|
||||
return Task.FromResult(_memberGroupRepository.GetByName(name));
|
||||
}
|
||||
|
||||
using (ICoreScope scope = ScopeProvider.CreateCoreScope())
|
||||
/// <inheritdoc/>
|
||||
public Task<IMemberGroup?> GetAsync(Guid key)
|
||||
{
|
||||
using ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true);
|
||||
return Task.FromResult(_memberGroupRepository.Get(key));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Task<IEnumerable<IMemberGroup>> GetAllAsync()
|
||||
{
|
||||
using ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true);
|
||||
return Task.FromResult(_memberGroupRepository.GetMany());
|
||||
}
|
||||
|
||||
public Task<IEnumerable<IMemberGroup>> GetByIdsAsync(IEnumerable<int> ids)
|
||||
{
|
||||
if (ids.Any() == false)
|
||||
{
|
||||
var deletingNotification = new MemberGroupDeletingNotification(memberGroup, evtMsgs);
|
||||
if (scope.Notifications.PublishCancelable(deletingNotification))
|
||||
{
|
||||
scope.Complete();
|
||||
return;
|
||||
}
|
||||
|
||||
_memberGroupRepository.Delete(memberGroup);
|
||||
scope.Complete();
|
||||
|
||||
scope.Notifications.Publish(
|
||||
new MemberGroupDeletedNotification(memberGroup, evtMsgs).WithStateFrom(deletingNotification));
|
||||
return Task.FromResult<IEnumerable<IMemberGroup>>(Array.Empty<IMemberGroup>());
|
||||
}
|
||||
|
||||
using ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true);
|
||||
return Task.FromResult(_memberGroupRepository.GetMany(ids.ToArray()));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<Attempt<IMemberGroup?, MemberGroupOperationStatus>> CreateAsync(IMemberGroup memberGroup)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(memberGroup.Name))
|
||||
{
|
||||
return Attempt.FailWithStatus<IMemberGroup?, MemberGroupOperationStatus>(MemberGroupOperationStatus.CannotHaveEmptyName, null);
|
||||
}
|
||||
|
||||
EventMessages eventMessages = EventMessagesFactory.Get();
|
||||
|
||||
using ICoreScope scope = ScopeProvider.CreateCoreScope();
|
||||
IMemberGroup? existingMemberGroup = await GetAsync(memberGroup.Key);
|
||||
if (existingMemberGroup is not null)
|
||||
{
|
||||
return Attempt.FailWithStatus<IMemberGroup?, MemberGroupOperationStatus>(MemberGroupOperationStatus.DuplicateKey, null);
|
||||
}
|
||||
|
||||
if (await NameAlreadyExistsAsync(memberGroup))
|
||||
{
|
||||
return Attempt.FailWithStatus<IMemberGroup?, MemberGroupOperationStatus>(MemberGroupOperationStatus.DuplicateName, null);
|
||||
}
|
||||
|
||||
var savingNotification = new MemberGroupSavingNotification(memberGroup, eventMessages);
|
||||
if (await scope.Notifications.PublishCancelableAsync(savingNotification))
|
||||
{
|
||||
scope.Complete();
|
||||
return Attempt.FailWithStatus<IMemberGroup?, MemberGroupOperationStatus>(MemberGroupOperationStatus.CancelledByNotification, null);
|
||||
}
|
||||
|
||||
_memberGroupRepository.Save(memberGroup);
|
||||
scope.Complete();
|
||||
|
||||
scope.Notifications.Publish(new MemberGroupSavedNotification(memberGroup, eventMessages).WithStateFrom(savingNotification));
|
||||
return Attempt.SucceedWithStatus<IMemberGroup?, MemberGroupOperationStatus>(MemberGroupOperationStatus.Success, memberGroup);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<Attempt<IMemberGroup?, MemberGroupOperationStatus>> DeleteAsync(Guid key)
|
||||
{
|
||||
EventMessages eventMessages = EventMessagesFactory.Get();
|
||||
|
||||
using ICoreScope scope = ScopeProvider.CreateCoreScope();
|
||||
IMemberGroup? memberGroup = _memberGroupRepository.Get(key);
|
||||
|
||||
if (memberGroup is null)
|
||||
{
|
||||
return Attempt.FailWithStatus<IMemberGroup?, MemberGroupOperationStatus>(MemberGroupOperationStatus.NotFound, null);
|
||||
}
|
||||
|
||||
var deletingNotification = new MemberGroupDeletingNotification(memberGroup, eventMessages);
|
||||
if (await scope.Notifications.PublishCancelableAsync(deletingNotification))
|
||||
{
|
||||
scope.Complete();
|
||||
return Attempt.FailWithStatus<IMemberGroup?, MemberGroupOperationStatus>(MemberGroupOperationStatus.CancelledByNotification, null);
|
||||
}
|
||||
|
||||
_memberGroupRepository.Delete(memberGroup);
|
||||
scope.Complete();
|
||||
|
||||
scope.Notifications.Publish(new MemberGroupDeletedNotification(memberGroup, eventMessages).WithStateFrom(deletingNotification));
|
||||
|
||||
return Attempt.SucceedWithStatus<IMemberGroup?, MemberGroupOperationStatus>(MemberGroupOperationStatus.Success, memberGroup);
|
||||
}
|
||||
|
||||
public async Task<Attempt<IMemberGroup?, MemberGroupOperationStatus>> UpdateAsync(IMemberGroup memberGroup)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(memberGroup.Name))
|
||||
{
|
||||
return Attempt.FailWithStatus<IMemberGroup?, MemberGroupOperationStatus>(MemberGroupOperationStatus.CannotHaveEmptyName, null);
|
||||
}
|
||||
|
||||
EventMessages eventMessages = EventMessagesFactory.Get();
|
||||
|
||||
using ICoreScope scope = ScopeProvider.CreateCoreScope();
|
||||
|
||||
IMemberGroup? existingMemberGroup = await GetByNameAsync(memberGroup.Name!);
|
||||
|
||||
if (existingMemberGroup is not null && existingMemberGroup.Key != memberGroup.Key)
|
||||
{
|
||||
return Attempt.FailWithStatus<IMemberGroup?, MemberGroupOperationStatus>(MemberGroupOperationStatus.DuplicateName, null);
|
||||
}
|
||||
|
||||
var savingNotification = new MemberGroupSavingNotification(memberGroup, eventMessages);
|
||||
if (await scope.Notifications.PublishCancelableAsync(savingNotification))
|
||||
{
|
||||
scope.Complete();
|
||||
return Attempt.FailWithStatus<IMemberGroup?, MemberGroupOperationStatus>(MemberGroupOperationStatus.CancelledByNotification, null);
|
||||
}
|
||||
|
||||
_memberGroupRepository.Save(memberGroup);
|
||||
scope.Complete();
|
||||
|
||||
scope.Notifications.Publish(new MemberGroupSavedNotification(memberGroup, eventMessages).WithStateFrom(savingNotification));
|
||||
return Attempt.SucceedWithStatus<IMemberGroup?, MemberGroupOperationStatus>(MemberGroupOperationStatus.Success, memberGroup);
|
||||
}
|
||||
|
||||
private async Task<bool> NameAlreadyExistsAsync(IMemberGroup memberGroup)
|
||||
{
|
||||
IMemberGroup? existingMemberGroup = await GetByNameAsync(memberGroup.Name!);
|
||||
return existingMemberGroup is not null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
public enum MemberGroupOperationStatus
|
||||
{
|
||||
Success,
|
||||
NotFound,
|
||||
CannotHaveEmptyName,
|
||||
CancelledByNotification,
|
||||
DuplicateName,
|
||||
DuplicateKey,
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
using Umbraco.Cms.Tests.Common.Testing;
|
||||
using Umbraco.Cms.Tests.Integration.Testing;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.Umbraco.Core.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Tests covering the MemberGroupService
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)]
|
||||
public class MemberGroupServiceTests : UmbracoIntegrationTest
|
||||
{
|
||||
private IMemberGroupService MemberGroupService => GetRequiredService<IMemberGroupService>();
|
||||
|
||||
[Test]
|
||||
public async Task Can_Create_MemberGroup()
|
||||
{
|
||||
var memberGroup = new MemberGroup
|
||||
{
|
||||
Name = "TestGroup",
|
||||
};
|
||||
await MemberGroupService.CreateAsync(memberGroup);
|
||||
|
||||
var fetchedGroup = await MemberGroupService.GetAsync(memberGroup.Key);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.IsNotNull(fetchedGroup);
|
||||
Assert.AreEqual(fetchedGroup, memberGroup);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Can_Create_MemberGroup_With_Key()
|
||||
{
|
||||
Guid key = Guid.NewGuid();
|
||||
var memberGroup = new MemberGroup
|
||||
{
|
||||
Name = "TestGroup",
|
||||
Key = key,
|
||||
};
|
||||
await MemberGroupService.CreateAsync(memberGroup);
|
||||
|
||||
var fetchedGroup = await MemberGroupService.GetAsync(memberGroup.Key);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.IsNotNull(fetchedGroup);
|
||||
Assert.AreEqual(key, fetchedGroup.Key);
|
||||
Assert.AreEqual(fetchedGroup, memberGroup);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Can_Update_MemberGroup()
|
||||
{
|
||||
const string updatedName = "UpdatedName";
|
||||
var memberGroup = new MemberGroup
|
||||
{
|
||||
Name = "TestGroup",
|
||||
};
|
||||
await MemberGroupService.CreateAsync(memberGroup);
|
||||
|
||||
memberGroup.Name = updatedName;
|
||||
await MemberGroupService.UpdateAsync(memberGroup);
|
||||
|
||||
var fetchedGroup = await MemberGroupService.GetAsync(memberGroup.Key);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.IsNotNull(fetchedGroup);
|
||||
Assert.AreEqual(fetchedGroup.Name, updatedName);
|
||||
Assert.AreEqual(fetchedGroup, memberGroup);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Can_Delete_MemberGroup()
|
||||
{
|
||||
var memberGroup = new MemberGroup
|
||||
{
|
||||
Name = "TestGroup",
|
||||
};
|
||||
await MemberGroupService.CreateAsync(memberGroup);
|
||||
|
||||
var fetchedGroup = await MemberGroupService.GetAsync(memberGroup.Key);
|
||||
|
||||
Assert.IsNotNull(fetchedGroup);
|
||||
|
||||
await MemberGroupService.DeleteAsync(memberGroup.Key);
|
||||
|
||||
// re-get
|
||||
fetchedGroup = await MemberGroupService.GetAsync(memberGroup.Key);
|
||||
|
||||
Assert.IsNull(fetchedGroup);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Cannot_Create_MemberGroup_With_Duplicate_Name()
|
||||
{
|
||||
const string name = "TestGroup";
|
||||
var memberGroupOne = new MemberGroup
|
||||
{
|
||||
Name = name,
|
||||
};
|
||||
var memberGroupTwo = new MemberGroup
|
||||
{
|
||||
Name = name,
|
||||
};
|
||||
var attemptOne = await MemberGroupService.CreateAsync(memberGroupOne);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.IsTrue(attemptOne.Success);
|
||||
Assert.AreEqual(MemberGroupOperationStatus.Success, attemptOne.Status);
|
||||
});
|
||||
|
||||
var attemptTwo = await MemberGroupService.CreateAsync(memberGroupTwo);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.IsFalse(attemptTwo.Success);
|
||||
Assert.AreEqual(MemberGroupOperationStatus.DuplicateName, attemptTwo.Status);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Cannot_Update_MemberGroup_With_Duplicate_Name()
|
||||
{
|
||||
const string name = "TestGroup";
|
||||
var memberGroupOne = new MemberGroup
|
||||
{
|
||||
Name = name,
|
||||
};
|
||||
var memberGroupTwo = new MemberGroup
|
||||
{
|
||||
Name = "TestGroupTwo",
|
||||
};
|
||||
var attemptOne = await MemberGroupService.CreateAsync(memberGroupOne);
|
||||
var attemptTwo = await MemberGroupService.CreateAsync(memberGroupTwo);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.IsTrue(attemptOne.Success);
|
||||
Assert.AreEqual(MemberGroupOperationStatus.Success, attemptOne.Status);
|
||||
Assert.IsTrue(attemptTwo.Success);
|
||||
Assert.AreEqual(MemberGroupOperationStatus.Success, attemptTwo.Status);
|
||||
});
|
||||
|
||||
// Update to already existing name.
|
||||
memberGroupTwo.Name = name;
|
||||
var updateAttempt = await MemberGroupService.UpdateAsync(memberGroupTwo);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.IsFalse(updateAttempt.Success);
|
||||
Assert.AreEqual(MemberGroupOperationStatus.DuplicateName, updateAttempt.Status);
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user