New Backoffice - Exposing hardcoded Open API contract (#12953)
* Only expose swagger ui when in development
* Only expose swagger ui when in development + Test confirming the contract is respected + contract
* Rollback test code
* Fix up formatting
* Add reference to managementapi in integration tests.
* Revert "Add reference to managementapi in integration tests."
This reverts commit 67e2bf827758767e9031d40d146d6f27fd6c031e.
* Fix integration tests
* Add reference to management api in integration tests
* Fix up schema
* Fixed tests
* Fix test.. do not execute that composer twice
* Revert "Updated dependencies and fixed new NRT issues"
This reverts commit b2b2903a6e.
* Added debug info to test, to debug on azure pipeline
* Try and fix OpenApi test
* Only run test in release
* Try fixing OpenApi.json
Co-authored-by: Nikolaj <nikolajlauridsen@protonmail.ch>
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.New.Cms.Web.Common.Routing;
|
||||
|
||||
namespace Umbraco.Cms.ManagementApi.Configuration;
|
||||
|
||||
public class ConfigureMvcOptions : IConfigureOptions<MvcOptions>
|
||||
{
|
||||
private readonly IOptions<GlobalSettings> _globalSettings;
|
||||
|
||||
public ConfigureMvcOptions(IOptions<GlobalSettings> globalSettings)
|
||||
{
|
||||
_globalSettings = globalSettings;
|
||||
}
|
||||
|
||||
public void Configure(MvcOptions options)
|
||||
{
|
||||
// Replace the BackOfficeToken in routes.
|
||||
|
||||
var backofficePath = _globalSettings.Value.UmbracoPath.TrimStart(Constants.CharArrays.TildeForwardSlash);
|
||||
options.Conventions.Add(new UmbracoBackofficeToken(Constants.Web.AttributeRouting.BackOfficeToken, backofficePath));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,22 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Diagnostics;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Versioning;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.FileProviders;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NSwag.AspNetCore;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Composing;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Hosting;
|
||||
using Umbraco.Cms.ManagementApi.Configuration;
|
||||
using Umbraco.Cms.ManagementApi.DependencyInjection;
|
||||
using Umbraco.Cms.Web.Common.ApplicationBuilder;
|
||||
using Umbraco.Extensions;
|
||||
using Umbraco.New.Cms.Web.Common.Routing;
|
||||
using IHostingEnvironment = Umbraco.Cms.Core.Hosting.IHostingEnvironment;
|
||||
|
||||
namespace Umbraco.Cms.ManagementApi;
|
||||
|
||||
@@ -28,6 +29,8 @@ public class ManagementApiComposer : IComposer
|
||||
|
||||
public void Compose(IUmbracoBuilder builder)
|
||||
{
|
||||
// TODO Should just call a single extension method that can be called fromUmbracoTestServerTestBase too, instead of calling this method
|
||||
|
||||
IServiceCollection services = builder.Services;
|
||||
|
||||
builder
|
||||
@@ -59,17 +62,8 @@ public class ManagementApiComposer : IComposer
|
||||
options.AddApiVersionParametersWhenVersionNeutral = true;
|
||||
options.AssumeDefaultVersionWhenUnspecified = true;
|
||||
});
|
||||
|
||||
// Not super happy with this, but we need to know the UmbracoPath when registering the controller
|
||||
// To be able to replace the route template token
|
||||
GlobalSettings? globalSettings =
|
||||
builder.Config.GetSection(Constants.Configuration.ConfigGlobal).Get<GlobalSettings>();
|
||||
var backofficePath = globalSettings.UmbracoPath.TrimStart(Constants.CharArrays.TildeForwardSlash);
|
||||
|
||||
services.AddControllers(options =>
|
||||
{
|
||||
options.Conventions.Add(new UmbracoBackofficeToken(Constants.Web.AttributeRouting.BackOfficeToken, backofficePath));
|
||||
});
|
||||
services.AddControllers();
|
||||
builder.Services.ConfigureOptions<ConfigureMvcOptions>();
|
||||
|
||||
builder.Services.Configure<UmbracoPipelineOptions>(options =>
|
||||
{
|
||||
@@ -99,31 +93,46 @@ public class ManagementApiComposer : IComposer
|
||||
applicationBuilder =>
|
||||
{
|
||||
IServiceProvider provider = applicationBuilder.ApplicationServices;
|
||||
GlobalSettings? settings = provider.GetRequiredService<IOptions<GlobalSettings>>().Value;
|
||||
IHostingEnvironment hostingEnvironment = provider.GetRequiredService<IHostingEnvironment>();
|
||||
var officePath = settings.GetBackOfficePath(hostingEnvironment);
|
||||
IWebHostEnvironment webHostEnvironment = provider.GetRequiredService<IWebHostEnvironment>();
|
||||
|
||||
// serve documents (same as app.UseSwagger())
|
||||
applicationBuilder.UseOpenApi(config =>
|
||||
if (!webHostEnvironment.IsProduction())
|
||||
{
|
||||
config.Path = $"{officePath}/swagger/{{documentName}}/swagger.json";
|
||||
});
|
||||
GlobalSettings? settings = provider.GetRequiredService<IOptions<GlobalSettings>>().Value;
|
||||
IHostingEnvironment hostingEnvironment = provider.GetRequiredService<IHostingEnvironment>();
|
||||
var officePath = settings.GetBackOfficePath(hostingEnvironment);
|
||||
// serve documents (same as app.UseSwagger())
|
||||
applicationBuilder.UseOpenApi(config =>
|
||||
{
|
||||
config.Path = $"{officePath}/swagger/{{documentName}}/swagger.json";
|
||||
});
|
||||
|
||||
// Serve Swagger UI
|
||||
applicationBuilder.UseSwaggerUi3(config =>
|
||||
{
|
||||
config.Path = officePath + "/swagger";
|
||||
config.SwaggerRoutes.Clear();
|
||||
var swaggerPath = $"{officePath}/swagger/{ApiAllName}/swagger.json";
|
||||
config.SwaggerRoutes.Add(new SwaggerUi3Route(ApiAllName, swaggerPath));
|
||||
});
|
||||
// Serve Swagger UI
|
||||
applicationBuilder.UseSwaggerUi3(config =>
|
||||
{
|
||||
config.Path = officePath + "/swagger";
|
||||
config.SwaggerRoutes.Clear();
|
||||
var swaggerPath = $"{officePath}/swagger/{ApiAllName}/swagger.json";
|
||||
config.SwaggerRoutes.Add(new SwaggerUi3Route(ApiAllName, swaggerPath));
|
||||
});
|
||||
}
|
||||
},
|
||||
applicationBuilder =>
|
||||
{
|
||||
IServiceProvider provider = applicationBuilder.ApplicationServices;
|
||||
|
||||
applicationBuilder.UseEndpoints(endpoints =>
|
||||
{
|
||||
GlobalSettings? settings = provider.GetRequiredService<IOptions<GlobalSettings>>().Value;
|
||||
IHostingEnvironment hostingEnvironment = provider.GetRequiredService<IHostingEnvironment>();
|
||||
var officePath = settings.GetBackOfficePath(hostingEnvironment);
|
||||
// Maps attribute routed controllers.
|
||||
endpoints.MapControllers();
|
||||
|
||||
// Serve contract
|
||||
endpoints.MapGet($"{officePath}/api/openapi.json",async context =>
|
||||
{
|
||||
await context.Response.SendFileAsync(new EmbeddedFileProvider(this.GetType().Assembly).GetFileInfo("OpenApi.json"));
|
||||
});
|
||||
});
|
||||
}
|
||||
));
|
||||
|
||||
552
src/Umbraco.Cms.ManagementApi/OpenApi.json
Normal file
552
src/Umbraco.Cms.ManagementApi/OpenApi.json
Normal file
@@ -0,0 +1,552 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Umbraco Backoffice API",
|
||||
"description": "This shows all APIs available in this version of Umbraco - Including all the legacy apis that is available for backward compatibility",
|
||||
"version": "All"
|
||||
},
|
||||
"servers": [
|
||||
{
|
||||
"url": "https://localhost:44331"
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"/umbraco/api/v1/install/settings": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Install"
|
||||
],
|
||||
"operationId": "SettingsInstall_Settings",
|
||||
"responses": {
|
||||
"400": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"428": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"200": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/InstallSettingsViewModel"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/umbraco/api/v1/install/setup": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"Install"
|
||||
],
|
||||
"operationId": "SetupInstall_Setup",
|
||||
"requestBody": {
|
||||
"x-name": "installData",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/InstallViewModel"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true,
|
||||
"x-position": 1
|
||||
},
|
||||
"responses": {
|
||||
"400": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"428": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"200": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/umbraco/api/v1/install/validateDatabase": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"Install"
|
||||
],
|
||||
"operationId": "ValidateDatabaseInstall_ValidateDatabase",
|
||||
"requestBody": {
|
||||
"x-name": "viewModel",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/DatabaseInstallViewModel"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true,
|
||||
"x-position": 1
|
||||
},
|
||||
"responses": {
|
||||
"400": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"200": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/umbraco/api/v1/upgrade/authorize": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"Upgrade"
|
||||
],
|
||||
"operationId": "AuthorizeUpgrade_Authorize",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": ""
|
||||
},
|
||||
"428": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/umbraco/api/v1/upgrade/settings": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Upgrade"
|
||||
],
|
||||
"operationId": "SettingsUpgrade_Settings",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UpgradeSettingsViewModel"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"428": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/umbraco/api/v1/server/status": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Server"
|
||||
],
|
||||
"operationId": "StatusServer_Get",
|
||||
"responses": {
|
||||
"400": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"200": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ServerStatusViewModel"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/umbraco/api/v1/server/version": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Server"
|
||||
],
|
||||
"operationId": "VersionServer_Get",
|
||||
"responses": {
|
||||
"400": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"200": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/VersionViewModel"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"ProblemDetails": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"nullable": true
|
||||
},
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"title": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"status": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"nullable": true
|
||||
},
|
||||
"detail": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"instance": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"InstallSettingsViewModel": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"user": {
|
||||
"$ref": "#/components/schemas/UserSettingsViewModel"
|
||||
},
|
||||
"databases": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/DatabaseSettingsViewModel"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"UserSettingsViewModel": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"minCharLength": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"minNonAlphaNumericLength": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"consentLevels": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ConsentLevelViewModel"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ConsentLevelViewModel": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"level": {
|
||||
"$ref": "#/components/schemas/TelemetryLevel"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"TelemetryLevel": {
|
||||
"type": "string",
|
||||
"description": "",
|
||||
"x-enumNames": [
|
||||
"Minimal",
|
||||
"Basic",
|
||||
"Detailed"
|
||||
],
|
||||
"enum": [
|
||||
"Minimal",
|
||||
"Basic",
|
||||
"Detailed"
|
||||
]
|
||||
},
|
||||
"DatabaseSettingsViewModel": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"format": "guid"
|
||||
},
|
||||
"sortOrder": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"displayName": {
|
||||
"type": "string"
|
||||
},
|
||||
"defaultDatabaseName": {
|
||||
"type": "string"
|
||||
},
|
||||
"providerName": {
|
||||
"type": "string"
|
||||
},
|
||||
"isConfigured": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"requiresServer": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"serverPlaceholder": {
|
||||
"type": "string"
|
||||
},
|
||||
"requiresCredentials": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"supportsIntegratedAuthentication": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"requiresConnectionTest": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"InstallViewModel": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"user",
|
||||
"database"
|
||||
],
|
||||
"properties": {
|
||||
"user": {
|
||||
"$ref": "#/components/schemas/UserInstallViewModel"
|
||||
},
|
||||
"database": {
|
||||
"$ref": "#/components/schemas/DatabaseInstallViewModel"
|
||||
},
|
||||
"telemetryLevel": {
|
||||
"$ref": "#/components/schemas/TelemetryLevel"
|
||||
}
|
||||
}
|
||||
},
|
||||
"UserInstallViewModel": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"name",
|
||||
"email",
|
||||
"password"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"maxLength": 255,
|
||||
"minLength": 0
|
||||
},
|
||||
"email": {
|
||||
"type": "string",
|
||||
"format": "email",
|
||||
"minLength": 1
|
||||
},
|
||||
"password": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"subscribeToNewsletter": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"DatabaseInstallViewModel": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"id",
|
||||
"providerName"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"format": "guid",
|
||||
"minLength": 1
|
||||
},
|
||||
"providerName": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"server": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"username": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"password": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"useIntegratedAuthentication": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"connectionString": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"UpgradeSettingsViewModel": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"currentState": {
|
||||
"type": "string"
|
||||
},
|
||||
"newState": {
|
||||
"type": "string"
|
||||
},
|
||||
"newVersion": {
|
||||
"type": "string"
|
||||
},
|
||||
"oldVersion": {
|
||||
"type": "string"
|
||||
},
|
||||
"reportUrl": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ServerStatusViewModel": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"serverStatus": {
|
||||
"$ref": "#/components/schemas/RuntimeLevel"
|
||||
}
|
||||
}
|
||||
},
|
||||
"RuntimeLevel": {
|
||||
"type": "string",
|
||||
"description": "Describes the levels in which the runtime can run.\n ",
|
||||
"x-enumNames": [
|
||||
"Unknown",
|
||||
"Boot",
|
||||
"Install",
|
||||
"Upgrade",
|
||||
"Run",
|
||||
"BootFailed"
|
||||
],
|
||||
"enum": [
|
||||
"Unknown",
|
||||
"Boot",
|
||||
"Install",
|
||||
"Upgrade",
|
||||
"Run",
|
||||
"BootFailed"
|
||||
]
|
||||
},
|
||||
"VersionViewModel": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"version": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
{
|
||||
"name": "Upgrade"
|
||||
},
|
||||
{
|
||||
"name": "Server"
|
||||
},
|
||||
{
|
||||
"name": "Install"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -26,4 +26,9 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="OpenApi.json" />
|
||||
<EmbeddedResource Include="OpenApi.json" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Hosting;
|
||||
using Umbraco.Cms.Tests.Integration.TestServerTest;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.NewBackoffice;
|
||||
|
||||
// We only run this test in release because the schema looks different depending if it's built against release or debug.
|
||||
// XML summaries is included in the description of a response model in release, but not debug mode.
|
||||
#if DEBUG
|
||||
[Ignore("This test runs only in release")]
|
||||
#endif
|
||||
[TestFixture]
|
||||
public class OpenAPIContractTest : UmbracoTestServerTestBase
|
||||
{
|
||||
|
||||
private GlobalSettings GlobalSettings => GetRequiredService<IOptions<GlobalSettings>>().Value;
|
||||
|
||||
private IHostingEnvironment HostingEnvironment => GetRequiredService<IHostingEnvironment>();
|
||||
|
||||
[Test]
|
||||
public async Task Validate_OpenApi_Contract_is_implemented()
|
||||
{
|
||||
string[] keysToIgnore = { "servers" };
|
||||
|
||||
var officePath = GlobalSettings.GetBackOfficePath(HostingEnvironment);
|
||||
|
||||
var urlToContract = $"{officePath}/api/openapi.json";
|
||||
var swaggerPath = $"{officePath}/swagger/All/swagger.json";
|
||||
var apiContract = JObject.Parse(await Client.GetStringAsync(urlToContract));
|
||||
|
||||
var generatedJsonString = await Client.GetStringAsync(swaggerPath);
|
||||
var mergedContract = JObject.Parse(generatedJsonString);
|
||||
var originalGeneratedContract = JObject.Parse(generatedJsonString);
|
||||
|
||||
|
||||
mergedContract.Merge(apiContract, new JsonMergeSettings
|
||||
{
|
||||
MergeArrayHandling = MergeArrayHandling.Merge
|
||||
});
|
||||
|
||||
foreach (var key in keysToIgnore)
|
||||
{
|
||||
originalGeneratedContract.Remove(key);
|
||||
mergedContract.Remove(key);
|
||||
}
|
||||
|
||||
Assert.AreEqual(originalGeneratedContract, mergedContract, $"Generated API do not respect the contract:{Environment.NewLine}Expected:{Environment.NewLine}{originalGeneratedContract.ToString(Formatting.Indented)}{Environment.NewLine}{Environment.NewLine}Actual:{Environment.NewLine}{mergedContract.ToString(Formatting.Indented)}");
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,9 @@ using Umbraco.Cms.Core.Composing;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
using Umbraco.Cms.ManagementApi;
|
||||
using Umbraco.Cms.ManagementApi.Configuration;
|
||||
using Umbraco.Cms.ManagementApi.Controllers.Install;
|
||||
using Umbraco.Cms.Persistence.Sqlite;
|
||||
using Umbraco.Cms.Persistence.SqlServer;
|
||||
using Umbraco.Cms.Tests.Common.Testing;
|
||||
@@ -26,7 +29,6 @@ using Umbraco.Cms.Tests.Integration.DependencyInjection;
|
||||
using Umbraco.Cms.Tests.Integration.Testing;
|
||||
using Umbraco.Cms.Web.BackOffice.Controllers;
|
||||
using Umbraco.Cms.Web.Common.Controllers;
|
||||
using Umbraco.Cms.Web.Common.Hosting;
|
||||
using Umbraco.Cms.Web.Website.Controllers;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
@@ -238,6 +240,9 @@ namespace Umbraco.Cms.Tests.Integration.TestServerTest
|
||||
|
||||
// Adds Umbraco.Tests.Integration
|
||||
mvcBuilder.AddApplicationPart(typeof(UmbracoTestServerTestBase).Assembly);
|
||||
|
||||
// Adds Umbraco.Tests.Integration
|
||||
mvcBuilder.AddApplicationPart(typeof(InstallControllerBase).Assembly);
|
||||
})
|
||||
.AddWebServer()
|
||||
.AddWebsite()
|
||||
@@ -245,6 +250,8 @@ namespace Umbraco.Cms.Tests.Integration.TestServerTest
|
||||
.AddUmbracoSqliteSupport()
|
||||
.AddTestServices(TestHelper); // This is the important one!
|
||||
|
||||
new ManagementApiComposer().Compose(builder);
|
||||
|
||||
CustomTestSetup(builder);
|
||||
builder.Build();
|
||||
}
|
||||
@@ -254,6 +261,7 @@ namespace Umbraco.Cms.Tests.Integration.TestServerTest
|
||||
/// </summary>
|
||||
protected virtual void ConfigureTestServices(IServiceCollection services)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected void Configure(IApplicationBuilder app)
|
||||
|
||||
@@ -105,6 +105,7 @@
|
||||
<ProjectReference Include="..\..\src\Umbraco.Cms.Persistence.SqlServer\Umbraco.Cms.Persistence.SqlServer.csproj" />
|
||||
<ProjectReference Include="..\..\src\Umbraco.Core\Umbraco.Core.csproj" />
|
||||
<ProjectReference Include="..\..\src\Umbraco.Infrastructure\Umbraco.Infrastructure.csproj" />
|
||||
<ProjectReference Include="..\..\src\Umbraco.Cms.ManagementApi\Umbraco.Cms.ManagementApi.csproj" />
|
||||
<ProjectReference Include="..\..\src\Umbraco.PublishedCache.NuCache\Umbraco.PublishedCache.NuCache.csproj" />
|
||||
<ProjectReference Include="..\Umbraco.Tests.Common\Umbraco.Tests.Common.csproj" />
|
||||
<ProjectReference Include="..\..\src\Umbraco.Web.BackOffice\Umbraco.Web.BackOffice.csproj" />
|
||||
|
||||
@@ -81,7 +81,8 @@ public class InstallAreaRoutesTests
|
||||
var route = endpoints.DataSources.First();
|
||||
Assert.AreEqual(1, route.Endpoints.Count);
|
||||
|
||||
Assert.AreEqual("install/{controller?}/{action?} HTTP: GET", route.Endpoints[0].ToString());
|
||||
var routeEndpoint = (RouteEndpoint)route.Endpoints[0];
|
||||
Assert.AreEqual("install/{controller?}/{action?}", routeEndpoint.RoutePattern.RawText);
|
||||
}
|
||||
|
||||
private InstallAreaRoutes GetInstallAreaRoutes(RuntimeLevel level) =>
|
||||
|
||||
Reference in New Issue
Block a user