diff --git a/src/Umbraco.Cms.Api.Management/Factories/IndexPresentationFactory.cs b/src/Umbraco.Cms.Api.Management/Factories/IndexPresentationFactory.cs index c4cd3bad9f..0fae77078b 100644 --- a/src/Umbraco.Cms.Api.Management/Factories/IndexPresentationFactory.cs +++ b/src/Umbraco.Cms.Api.Management/Factories/IndexPresentationFactory.cs @@ -26,7 +26,10 @@ public class IndexPresentationFactory : IIndexPresentationFactory return new IndexResponseModel { Name = index.Name, - HealthStatus = HealthStatus.Rebuilding, + HealthStatus = new HealthStatusResponseModel + { + Status = HealthStatus.Rebuilding, + }, SearcherName = index.Searcher.Name, DocumentCount = 0, FieldCount = 0, @@ -35,7 +38,7 @@ public class IndexPresentationFactory : IIndexPresentationFactory IIndexDiagnostics indexDiag = _indexDiagnosticsFactory.Create(index); - Attempt isHealthy = indexDiag.IsHealthy(); + Attempt isHealthyAttempt = indexDiag.IsHealthy(); var properties = new Dictionary(); @@ -55,7 +58,11 @@ public class IndexPresentationFactory : IIndexPresentationFactory var indexerModel = new IndexResponseModel { Name = index.Name, - HealthStatus = isHealthy.Success ? HealthStatus.Healthy : HealthStatus.Unhealthy, + HealthStatus = new HealthStatusResponseModel + { + Status = isHealthyAttempt.Success ? HealthStatus.Healthy : HealthStatus.Unhealthy, + Message = isHealthyAttempt.Result, + }, CanRebuild = _indexRebuilder.CanRebuild(index.Name), SearcherName = index.Searcher.Name, DocumentCount = indexDiag.GetDocumentCount(), diff --git a/src/Umbraco.Cms.Api.Management/OpenApi.json b/src/Umbraco.Cms.Api.Management/OpenApi.json index f25b163e73..42e9aeb4d1 100644 --- a/src/Umbraco.Cms.Api.Management/OpenApi.json +++ b/src/Umbraco.Cms.Api.Management/OpenApi.json @@ -32107,6 +32107,115 @@ } ] }, + "delete": { + "tags": [ + "Webhook" + ], + "operationId": "DeleteWebhookById", + "parameters": [ + { + "name": "id", + "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": { + "oneOf": [ + { + "$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": { + "oneOf": [ + { + "$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" + }, + "403": { + "description": "The authenticated user do not have access to this resource", + "headers": { + "Umb-Notifications": { + "description": "The list of notifications produced during the request.", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NotificationHeaderModel" + }, + "nullable": true + } + } + } + } + }, + "security": [ + { + "Backoffice User": [ ] + } + ] + }, "put": { "tags": [ "Webhook" @@ -32246,115 +32355,6 @@ "Backoffice User": [ ] } ] - }, - "delete": { - "tags": [ - "Webhook" - ], - "operationId": "DeleteWebhookById", - "parameters": [ - { - "name": "id", - "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": { - "oneOf": [ - { - "$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": { - "oneOf": [ - { - "$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" - }, - "403": { - "description": "The authenticated user do not have access to this resource", - "headers": { - "Umb-Notifications": { - "description": "The list of notifications produced during the request.", - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/NotificationHeaderModel" - }, - "nullable": true - } - } - } - } - }, - "security": [ - { - "Backoffice User": [ ] - } - ] } }, "/umbraco/management/api/v1/webhook/events": { @@ -36671,6 +36671,22 @@ ], "type": "string" }, + "HealthStatusResponseModel": { + "required": [ + "status" + ], + "type": "object", + "properties": { + "status": { + "$ref": "#/components/schemas/HealthStatusModel" + }, + "message": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, "HelpPageResponseModel": { "type": "object", "properties": { @@ -36733,7 +36749,11 @@ "type": "string" }, "healthStatus": { - "$ref": "#/components/schemas/HealthStatusModel" + "oneOf": [ + { + "$ref": "#/components/schemas/HealthStatusResponseModel" + } + ] }, "canRebuild": { "type": "boolean" @@ -43456,11 +43476,12 @@ "UserGroupResponseModel": { "required": [ "alias", + "aliasCanBeChanged", "documentRootAccess", "fallbackPermissions", "hasAccessToAllLanguages", "id", - "isSystemGroup", + "isDeletable", "languages", "mediaRootAccess", "name", @@ -43541,7 +43562,10 @@ "type": "string", "format": "uuid" }, - "isSystemGroup": { + "isDeletable": { + "type": "boolean" + }, + "aliasCanBeChanged": { "type": "boolean" } }, @@ -44041,4 +44065,4 @@ } } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/Indexer/HealthStatusResponseModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/Indexer/HealthStatusResponseModel.cs new file mode 100644 index 0000000000..5df7f64c70 --- /dev/null +++ b/src/Umbraco.Cms.Api.Management/ViewModels/Indexer/HealthStatusResponseModel.cs @@ -0,0 +1,8 @@ +namespace Umbraco.Cms.Api.Management.ViewModels.Indexer; + +public class HealthStatusResponseModel +{ + public HealthStatus Status { get; init; } + + public string? Message { get; init; } +} diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/Indexer/IndexResponseModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/Indexer/IndexResponseModel.cs index 4cacfead6d..9717daca32 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/Indexer/IndexResponseModel.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/Indexer/IndexResponseModel.cs @@ -7,7 +7,7 @@ public class IndexResponseModel [Required] public string Name { get; init; } = null!; - public HealthStatus HealthStatus { get; init; } + public HealthStatusResponseModel HealthStatus { get; set; } = new(); [Required] public bool CanRebuild { get; init; } diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Cms.Api.Management/Factories/IndexPresentationFactoryTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Cms.Api.Management/Factories/IndexPresentationFactoryTests.cs new file mode 100644 index 0000000000..e9c88b28df --- /dev/null +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Cms.Api.Management/Factories/IndexPresentationFactoryTests.cs @@ -0,0 +1,63 @@ +using System.Collections.ObjectModel; +using Examine; +using Moq; +using NUnit.Framework; +using Umbraco.Cms.Api.Management.Factories; +using Umbraco.Cms.Core; +using Umbraco.Cms.Infrastructure.Examine; +using Umbraco.Cms.Infrastructure.Services; + +namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Cms.Api.Management.Factories; + +[TestFixture] +public class IndexPresentationFactoryTests +{ + [Test] + public void Create_Should_Set_HealthStatusMessage_On_Diagnostics_Failure() + { + var indexDiagnosticsFailureMessage = "something is wrong"; + // arrange + var indexMock = new Mock(); + indexMock + .SetupGet(index => index.Name) + .Returns("testIndex"); + indexMock + .SetupGet(index => index.Searcher) + .Returns(Mock.Of()); + + var indexDiagnosticsMock = new Mock(); + indexDiagnosticsMock + .Setup(diagnostic => diagnostic.IsHealthy()) + .Returns(Attempt.Fail(indexDiagnosticsFailureMessage)); + indexDiagnosticsMock + .SetupGet(diagnostic => diagnostic.Metadata) + .Returns(ReadOnlyDictionary.Empty); + indexDiagnosticsMock + .Setup(diagnostic => diagnostic.GetFieldNames()) + .Returns(Enumerable.Empty()); + + var indexDiagnosticsFactoryMock = new Mock(); + indexDiagnosticsFactoryMock + .Setup(f => f.Create(It.IsAny())) + .Returns(indexDiagnosticsMock.Object); + + var indexRebuilderMock = new Mock(); + + var indexRebuilderServiceMock = new Mock(); + indexRebuilderServiceMock + .Setup(rebuilder => rebuilder.IsRebuilding(It.IsAny())) + .Returns(false); + + var factory = new IndexPresentationFactory( + indexDiagnosticsFactoryMock.Object, + indexRebuilderMock.Object, + indexRebuilderServiceMock.Object); + + + // act + var responseModel = factory.Create(indexMock.Object); + + // assert + Assert.AreEqual(indexDiagnosticsFailureMessage, responseModel.HealthStatus.Message); + } +}