mirror of https://github.com/Squidex/squidex.git
committed by
GitHub
17 changed files with 1187 additions and 2 deletions
@ -0,0 +1,86 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschränkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using FakeItEasy; |
|||
using Microsoft.AspNetCore.Http; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.AspNetCore.Mvc.Abstractions; |
|||
using Microsoft.AspNetCore.Mvc.Infrastructure; |
|||
using Microsoft.AspNetCore.Routing; |
|||
using Moq; |
|||
using Squidex.Infrastructure.Log; |
|||
using Squidex.Pipeline; |
|||
using Xunit; |
|||
|
|||
namespace Squidex.Tests.Pipeline |
|||
{ |
|||
public class ActionContextLogAppenderTests |
|||
{ |
|||
private readonly Mock<IActionContextAccessor> actionContextAccessor = new Mock<IActionContextAccessor>(); |
|||
private readonly Mock<HttpContext> httpContextMock = new Mock<HttpContext>(); |
|||
private readonly ActionDescriptor actionDescriptor = new ActionDescriptor(); |
|||
private readonly RouteData routeData = new RouteData(); |
|||
private readonly Guid requestId = Guid.NewGuid(); |
|||
private readonly IDictionary<object, object> items = new Dictionary<object, object>(); |
|||
private readonly IObjectWriter writer = A.Fake<IObjectWriter>(); |
|||
private readonly HttpRequest request = A.Fake<HttpRequest>(); |
|||
private ActionContextLogAppender sut; |
|||
private ActionContext actionContext; |
|||
|
|||
[Fact] |
|||
public void Append_should_get_requestId() |
|||
{ |
|||
items.Add(nameof(requestId), requestId); |
|||
SetupTest(); |
|||
|
|||
A.CallTo(() => writer.WriteObject(It.IsAny<string>(), It.IsAny<Action<IObjectWriter>>())).Returns(writer); |
|||
sut.Append(writer); |
|||
|
|||
Assert.NotNull(writer); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Append_should_put_requestId() |
|||
{ |
|||
SetupTest(); |
|||
|
|||
sut.Append(writer); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Append_should_return_if_no_actionContext() |
|||
{ |
|||
sut = new ActionContextLogAppender(actionContextAccessor.Object); |
|||
|
|||
sut.Append(writer); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Append_should_return_if_no_httpContext_method() |
|||
{ |
|||
A.CallTo(() => request.Method).Returns(string.Empty); |
|||
httpContextMock.Setup(x => x.Request).Returns(request); |
|||
actionContext = new ActionContext(httpContextMock.Object, routeData, actionDescriptor); |
|||
actionContextAccessor.Setup(x => x.ActionContext).Returns(actionContext); |
|||
sut = new ActionContextLogAppender(actionContextAccessor.Object); |
|||
|
|||
sut.Append(writer); |
|||
} |
|||
|
|||
private void SetupTest() |
|||
{ |
|||
A.CallTo(() => request.Method).Returns("Get"); |
|||
httpContextMock.Setup(x => x.Items).Returns(items); |
|||
httpContextMock.Setup(x => x.Request).Returns(request); |
|||
actionContext = new ActionContext(httpContextMock.Object, routeData, actionDescriptor); |
|||
actionContextAccessor.Setup(x => x.ActionContext).Returns(actionContext); |
|||
sut = new ActionContextLogAppender(actionContextAccessor.Object); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,32 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschränkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using IdentityServer4.AccessTokenValidation; |
|||
using Squidex.Pipeline; |
|||
using Squidex.Shared.Identity; |
|||
using Xunit; |
|||
|
|||
namespace Squidex.Tests.Pipeline |
|||
{ |
|||
public class ApiAuthorizeAttributeTests |
|||
{ |
|||
private ApiAuthorizeAttribute sut = new ApiAuthorizeAttribute(); |
|||
|
|||
[Fact] |
|||
public void AuthenticationSchemes_should_be_default() |
|||
{ |
|||
Assert.Equal(IdentityServerAuthenticationDefaults.AuthenticationScheme, sut.AuthenticationSchemes); |
|||
} |
|||
|
|||
[Fact] |
|||
public void MustBeAdmin_Test() |
|||
{ |
|||
sut = new MustBeAdministratorAttribute(); |
|||
Assert.Equal(SquidexRoles.Administrator, sut.Roles); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,104 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschränkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using FakeItEasy; |
|||
using Microsoft.AspNetCore.Http; |
|||
using Microsoft.AspNetCore.Http.Features; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.AspNetCore.Mvc.Abstractions; |
|||
using Microsoft.AspNetCore.Mvc.Filters; |
|||
using Microsoft.AspNetCore.Mvc.Infrastructure; |
|||
using Microsoft.AspNetCore.Routing; |
|||
using Moq; |
|||
using Squidex.Domain.Apps.Entities.Apps; |
|||
using Squidex.Domain.Apps.Entities.Apps.Services; |
|||
using Squidex.Infrastructure.UsageTracking; |
|||
using Squidex.Pipeline; |
|||
using Xunit; |
|||
using static Squidex.Pipeline.AppApiFilter; |
|||
|
|||
namespace Squidex.Tests.Pipeline |
|||
{ |
|||
public class ApiCostTests |
|||
{ |
|||
private readonly Mock<IActionContextAccessor> actionContextAccessor = new Mock<IActionContextAccessor>(); |
|||
private readonly RouteData routeData = new RouteData(); |
|||
private readonly ActionDescriptor actionDescriptor = new ActionDescriptor(); |
|||
private readonly IAppPlansProvider appPlanProvider = A.Fake<IAppPlansProvider>(); |
|||
private readonly IUsageTracker usageTracker = A.Fake<IUsageTracker>(); |
|||
private readonly long usage = 1; |
|||
private readonly Mock<HttpContext> httpContextMock = new Mock<HttpContext>(); |
|||
private readonly IFeatureCollection features = new FeatureCollection(); |
|||
private readonly IAppEntity appEntity = A.Fake<IAppEntity>(); |
|||
private readonly IAppFeature appFeature = A.Fake<IAppFeature>(); |
|||
private readonly IAppLimitsPlan appPlan = A.Fake<IAppLimitsPlan>(); |
|||
private readonly Guid appId = Guid.NewGuid(); |
|||
private ActionExecutingContext context; |
|||
private ActionExecutionDelegate next; |
|||
private ApiCostsFilter sut; |
|||
|
|||
public ApiCostTests() |
|||
{ |
|||
var actionContext = new ActionContext(httpContextMock.Object, routeData, actionDescriptor); |
|||
actionContextAccessor.Setup(x => x.ActionContext).Returns(actionContext); |
|||
context = new ActionExecutingContext(actionContext, new List<IFilterMetadata>(), new Dictionary<string, object>(), null); |
|||
context.Filters.Add(new ServiceFilterAttribute(typeof(ApiCostsFilter))); |
|||
|
|||
A.CallTo(() => appEntity.Id).Returns(appId); |
|||
A.CallTo(() => appFeature.App).Returns(appEntity); |
|||
|
|||
features.Set<IAppFeature>(new AppFeature(appEntity)); |
|||
httpContextMock.Setup(x => x.Features).Returns(features); |
|||
A.CallTo(() => usageTracker.GetMonthlyCalls(appId.ToString(), DateTime.Today)) |
|||
.Returns(usage); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_return_429_status_code_if_max_calls_over_limit() |
|||
{ |
|||
SetupSystem(2, 1); |
|||
|
|||
next = new ActionExecutionDelegate(async () => |
|||
{ |
|||
return null; |
|||
}); |
|||
await sut.OnActionExecutionAsync(context, next); |
|||
|
|||
Assert.Equal(new StatusCodeResult(429).StatusCode, (context.Result as StatusCodeResult).StatusCode); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_call_next_if_weight_is_0() |
|||
{ |
|||
SetupSystem(0, 1); |
|||
|
|||
var result = 0; |
|||
next = new ActionExecutionDelegate(async () => |
|||
{ |
|||
result = 1; |
|||
return null; |
|||
}); |
|||
await sut.OnActionExecutionAsync(context, next); |
|||
|
|||
Assert.Equal(1, result); |
|||
} |
|||
|
|||
private ApiCostsFilter SetupSystem(double weight, long maxCalls) |
|||
{ |
|||
A.CallTo(() => appPlan.MaxApiCalls).Returns(maxCalls); |
|||
A.CallTo(() => appPlanProvider.GetPlanForApp(appFeature.App)).Returns(appPlan); |
|||
|
|||
sut = new ApiCostsFilter(appPlanProvider, usageTracker); |
|||
sut.FilterDefinition = new ApiCostsAttribute(weight); |
|||
|
|||
return sut; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,101 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschränkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using System.Collections.Generic; |
|||
using Microsoft.AspNetCore.Http; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.AspNetCore.Mvc.Abstractions; |
|||
using Microsoft.AspNetCore.Mvc.Filters; |
|||
using Microsoft.AspNetCore.Routing; |
|||
using Moq; |
|||
using Squidex.Domain.Apps.Entities.Apps; |
|||
using Squidex.Infrastructure; |
|||
using Squidex.Pipeline; |
|||
using Xunit; |
|||
|
|||
namespace Squidex.Tests.Pipeline |
|||
{ |
|||
public class ApiExceptionFilterAttributeTests |
|||
{ |
|||
private readonly Mock<HttpContext> httpContextMock = new Mock<HttpContext>(); |
|||
private readonly ActionDescriptor actionDescriptor = new ActionDescriptor(); |
|||
private readonly RouteData routeData = new RouteData(); |
|||
private readonly ApiExceptionFilterAttribute sut = new ApiExceptionFilterAttribute(); |
|||
private readonly ExceptionContext context; |
|||
private ActionContext actionContext; |
|||
|
|||
public ApiExceptionFilterAttributeTests() |
|||
{ |
|||
actionContext = new ActionContext(httpContextMock.Object, routeData, actionDescriptor); |
|||
context = new ExceptionContext(actionContext, new List<IFilterMetadata>()); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Domain_Object_Not_Found_Exception_should_be_caught() |
|||
{ |
|||
context.Exception = new DomainObjectNotFoundException("id", typeof(IAppEntity)); |
|||
|
|||
sut.OnException(context); |
|||
|
|||
Assert.Equal(new NotFoundResult().StatusCode, (context.Result as NotFoundResult).StatusCode); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Domain_Object_Version_Exception_should_be_caught() |
|||
{ |
|||
context.Exception = new DomainObjectVersionException("id", typeof(IAppEntity), 0, 1); |
|||
|
|||
sut.OnException(context); |
|||
var exptectedResult = BuildErrorResult(412, new ErrorDto { Message = context.Exception.Message }); |
|||
|
|||
Assert.Equal(exptectedResult.StatusCode, (context.Result as ObjectResult).StatusCode); |
|||
Assert.StartsWith("Requested version", ((context.Result as ObjectResult).Value as ErrorDto).Message); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Domain_Exception_should_be_caught() |
|||
{ |
|||
context.Exception = new DomainException("Domain exception caught."); |
|||
|
|||
sut.OnException(context); |
|||
var exptectedResult = BuildErrorResult(400, new ErrorDto { Message = context.Exception.Message }); |
|||
|
|||
Assert.Equal(exptectedResult.StatusCode, (context.Result as ObjectResult).StatusCode); |
|||
Assert.Equal("Domain exception caught.", ((context.Result as ObjectResult).Value as ErrorDto).Message); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Domain_Forbidden_Exception_should_be_caught() |
|||
{ |
|||
context.Exception = new DomainForbiddenException("Domain forbidden exception caught."); |
|||
|
|||
sut.OnException(context); |
|||
var exptectedResult = BuildErrorResult(403, new ErrorDto { Message = context.Exception.Message }); |
|||
|
|||
Assert.Equal(exptectedResult.StatusCode, (context.Result as ObjectResult).StatusCode); |
|||
Assert.Equal("Domain forbidden exception caught.", ((context.Result as ObjectResult).Value as ErrorDto).Message); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validation_Exception_should_be_caught() |
|||
{ |
|||
var errors = new ValidationError("Validation error 1", new string[] { "prop1" }); |
|||
context.Exception = new ValidationException("Validation exception caught.", errors); |
|||
|
|||
sut.OnException(context); |
|||
var exptectedResult = BuildErrorResult(400, new ErrorDto { Message = context.Exception.Message }); |
|||
|
|||
Assert.Equal(exptectedResult.StatusCode, (context.Result as ObjectResult).StatusCode); |
|||
Assert.Equal("Validation exception caught: Validation error 1.", ((context.Result as ObjectResult).Value as ErrorDto).Message); |
|||
} |
|||
|
|||
private ObjectResult BuildErrorResult(int code, ErrorDto error) |
|||
{ |
|||
return new ObjectResult(error) { StatusCode = code }; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,90 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschränkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Net; |
|||
using System.Threading.Tasks; |
|||
using FakeItEasy; |
|||
using Microsoft.AspNetCore.Http; |
|||
using Microsoft.AspNetCore.Http.Features; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.AspNetCore.Mvc.Abstractions; |
|||
using Microsoft.AspNetCore.Mvc.Filters; |
|||
using Microsoft.AspNetCore.Mvc.Infrastructure; |
|||
using Microsoft.AspNetCore.Routing; |
|||
using Moq; |
|||
using Squidex.Domain.Apps.Entities; |
|||
using Squidex.Domain.Apps.Entities.Apps; |
|||
using Squidex.Domain.Apps.Entities.Apps.Services; |
|||
using Squidex.Infrastructure.UsageTracking; |
|||
using Squidex.Pipeline; |
|||
using Xunit; |
|||
|
|||
namespace Squidex.Tests.Pipeline |
|||
{ |
|||
public class AppApiTests |
|||
{ |
|||
private readonly Mock<IActionContextAccessor> actionContextAccessor = new Mock<IActionContextAccessor>(); |
|||
private readonly RouteData routeData = new RouteData(); |
|||
private readonly ActionDescriptor actionDescriptor = new ActionDescriptor(); |
|||
private readonly IAppPlansProvider appPlanProvider = A.Fake<IAppPlansProvider>(); |
|||
private readonly IUsageTracker usageTracker = A.Fake<IUsageTracker>(); |
|||
private readonly long usage = 1; |
|||
private readonly Mock<HttpContext> httpContextMock = new Mock<HttpContext>(); |
|||
private readonly IFeatureCollection features = new FeatureCollection(); |
|||
private readonly IAppEntity appEntity = A.Fake<IAppEntity>(); |
|||
private readonly IAppFeature appFeature = A.Fake<IAppFeature>(); |
|||
private readonly IAppProvider appProvider = A.Fake<IAppProvider>(); |
|||
private readonly Guid appId = Guid.NewGuid(); |
|||
private readonly ActionExecutingContext context; |
|||
private readonly AppApiFilter sut; |
|||
private ActionExecutionDelegate next; |
|||
|
|||
public AppApiTests() |
|||
{ |
|||
var actionContext = new ActionContext(httpContextMock.Object, routeData, actionDescriptor); |
|||
actionContextAccessor.Setup(x => x.ActionContext).Returns(actionContext); |
|||
context = new ActionExecutingContext(actionContext, new List<IFilterMetadata>(), new Dictionary<string, object>(), null); |
|||
context.Filters.Add(new AppApiAttribute()); |
|||
context.RouteData.Values.Add("app", "appName"); |
|||
|
|||
httpContextMock.Setup(x => x.Features).Returns(features); |
|||
A.CallTo(() => appProvider.GetAppAsync("appName")).Returns(appEntity); |
|||
|
|||
sut = new AppApiFilter(appProvider); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_set_features_if_app_found() |
|||
{ |
|||
next = new ActionExecutionDelegate(async () => |
|||
{ |
|||
return null; |
|||
}); |
|||
await sut.OnActionExecutionAsync(context, next); |
|||
|
|||
Assert.NotEmpty(context.HttpContext.Features); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_return_not_found_result_if_app_not_found() |
|||
{ |
|||
next = new ActionExecutionDelegate(async () => |
|||
{ |
|||
return null; |
|||
}); |
|||
|
|||
A.CallTo(() => appProvider.GetAppAsync("appName")).Returns((IAppEntity)null); |
|||
await sut.OnActionExecutionAsync(context, next); |
|||
|
|||
var result = context.Result as NotFoundResult; |
|||
Assert.NotNull(result); |
|||
Assert.Equal((int)HttpStatusCode.NotFound, result.StatusCode); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,130 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschränkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Collections.Immutable; |
|||
using System.Linq; |
|||
using System.Net; |
|||
using System.Security.Claims; |
|||
using FakeItEasy; |
|||
using Microsoft.AspNetCore.Http; |
|||
using Microsoft.AspNetCore.Http.Features; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.AspNetCore.Mvc.Abstractions; |
|||
using Microsoft.AspNetCore.Mvc.Filters; |
|||
using Microsoft.AspNetCore.Mvc.Infrastructure; |
|||
using Microsoft.AspNetCore.Routing; |
|||
using Moq; |
|||
using Squidex.Domain.Apps.Core.Apps; |
|||
using Squidex.Domain.Apps.Entities.Apps; |
|||
using Squidex.Infrastructure.Security; |
|||
using Squidex.Pipeline; |
|||
using Xunit; |
|||
|
|||
namespace Squidex.Tests.Pipeline |
|||
{ |
|||
public class AppPermissionAttributeTests |
|||
{ |
|||
private readonly Mock<HttpContext> httpContextMock = new Mock<HttpContext>(); |
|||
private readonly Mock<ClaimsPrincipal> mockUser = new Mock<ClaimsPrincipal>(); |
|||
private readonly ActionDescriptor actionDescriptor = new ActionDescriptor(); |
|||
private readonly Mock<IActionContextAccessor> actionContextAccessor = new Mock<IActionContextAccessor>(); |
|||
private readonly IAppEntity appEntity = A.Fake<IAppEntity>(); |
|||
private readonly ClaimsIdentity identity = new ClaimsIdentity(); |
|||
private readonly AppClient client = new AppClient("clientId", "secret", AppClientPermission.Reader); |
|||
private readonly IAppFeature appFeature = A.Fake<IAppFeature>(); |
|||
private readonly IFeatureCollection features = new FeatureCollection(); |
|||
private readonly RouteData routeData = new RouteData(); |
|||
private readonly ActionExecutingContext context; |
|||
private ActionContext actionContext; |
|||
private Claim clientClaim; |
|||
private Claim subjectClaim; |
|||
private AppPermissionAttribute sut = new MustBeAppReaderAttribute(); |
|||
|
|||
public AppPermissionAttributeTests() |
|||
{ |
|||
actionContext = new ActionContext(httpContextMock.Object, routeData, actionDescriptor); |
|||
actionContextAccessor.Setup(x => x.ActionContext).Returns(actionContext); |
|||
clientClaim = new Claim("client_id", $"test:clientId"); |
|||
subjectClaim = new Claim("sub", "user"); |
|||
|
|||
var clients = ImmutableDictionary.CreateBuilder<string, AppClient>(); |
|||
clients.Add("clientId", client); |
|||
var contributors = ImmutableDictionary.CreateBuilder<string, AppContributorPermission>(); |
|||
contributors.Add("user", AppContributorPermission.Owner); |
|||
|
|||
A.CallTo(() => appFeature.App).Returns(appEntity); |
|||
A.CallTo(() => appEntity.Clients).Returns(new AppClients(clients.ToImmutable())); |
|||
A.CallTo(() => appEntity.Contributors).Returns(new AppContributors(contributors.ToImmutable())); |
|||
features.Set<IAppFeature>(appFeature); |
|||
mockUser.Setup(x => x.Identities).Returns(new List<ClaimsIdentity> { identity }); |
|||
|
|||
httpContextMock.Setup(x => x.Features).Returns(features); |
|||
httpContextMock.Setup(x => x.User).Returns(mockUser.Object); |
|||
|
|||
context = new ActionExecutingContext(actionContext, new List<IFilterMetadata>(), new Dictionary<string, object>(), null); |
|||
context.Filters.Clear(); |
|||
sut = new MustBeAppDeveloperAttribute(); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Null_Permission_Returns_Not_Found() |
|||
{ |
|||
// Arrange
|
|||
sut = new MustBeAppReaderAttribute(); |
|||
context.Filters.Add(sut); |
|||
mockUser.Setup(x => x.FindFirst(OpenIdClaims.Subject)).Returns((Claim)null); |
|||
clientClaim = new Claim("client_id", "test"); |
|||
mockUser.Setup(x => x.FindFirst(OpenIdClaims.ClientId)).Returns(clientClaim); |
|||
|
|||
// Act
|
|||
sut.OnActionExecuting(context); |
|||
|
|||
// Assert
|
|||
var result = context.Result as NotFoundResult; |
|||
Assert.NotNull(result); |
|||
Assert.Equal((int)HttpStatusCode.NotFound, result.StatusCode); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Lower_Permission_Returns_Forbidden() |
|||
{ |
|||
// Arrange
|
|||
sut = new MustBeAppEditorAttribute(); |
|||
context.Filters.Add(sut); |
|||
mockUser.Setup(x => x.FindFirst(OpenIdClaims.Subject)).Returns((Claim)null); |
|||
mockUser.Setup(x => x.FindFirst(OpenIdClaims.ClientId)).Returns(clientClaim); |
|||
|
|||
// Act
|
|||
sut.OnActionExecuting(context); |
|||
|
|||
// Assert
|
|||
var result = context.Result as StatusCodeResult; |
|||
Assert.NotNull(result); |
|||
Assert.Equal((int)HttpStatusCode.Forbidden, result.StatusCode); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Higher_Permission_Should_Get_All_Lesser_Permissions() |
|||
{ |
|||
// Arrange
|
|||
sut = new MustBeAppOwnerAttribute(); |
|||
context.Filters.Add(sut); |
|||
mockUser.Setup(x => x.FindFirst(OpenIdClaims.Subject)).Returns(subjectClaim); |
|||
|
|||
// Act
|
|||
sut.OnActionExecuting(context); |
|||
|
|||
// Assert
|
|||
var result = context.HttpContext.User.Identities.First()?.Claims; |
|||
Assert.NotNull(result); |
|||
Assert.NotEmpty(result); |
|||
Assert.Equal(Enum.GetNames(typeof(AppPermission)).Length, result.Count()); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,46 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschränkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using System.Threading.Tasks; |
|||
using FakeItEasy; |
|||
using Microsoft.AspNetCore.Http; |
|||
using Microsoft.Extensions.Primitives; |
|||
using Squidex.Domain.Apps.Entities.Assets.Commands; |
|||
using Squidex.Infrastructure.Commands; |
|||
using Squidex.Pipeline.CommandMiddlewares; |
|||
using Xunit; |
|||
|
|||
namespace Squidex.Tests.Pipeline.CommandMiddlewares |
|||
{ |
|||
public class ETagCommandMiddlewareTests |
|||
{ |
|||
private readonly IHttpContextAccessor httpContextAccessor = A.Fake<IHttpContextAccessor>(); |
|||
private readonly ICommandBus commandBus = A.Fake<ICommandBus>(); |
|||
private readonly IHeaderDictionary headers = new HeaderDictionary { { "If-Match", "1" } }; |
|||
private readonly UpdateAsset command = new UpdateAsset(); |
|||
private readonly EntitySavedResult entitySavedResult = new EntitySavedResult(1); |
|||
private readonly ETagCommandMiddleware sut; |
|||
|
|||
public ETagCommandMiddlewareTests() |
|||
{ |
|||
A.CallTo(() => httpContextAccessor.HttpContext.Request.Headers).Returns(headers); |
|||
sut = new ETagCommandMiddleware(httpContextAccessor); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_add_etag_header_and_expected_version() |
|||
{ |
|||
var context = new CommandContext(command, commandBus); |
|||
context.Complete(entitySavedResult); |
|||
|
|||
await sut.HandleAsync(context); |
|||
|
|||
Assert.Equal(1, context.Command.ExpectedVersion); |
|||
Assert.Equal(new StringValues("1"), httpContextAccessor.HttpContext.Response.Headers["ETag"]); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,85 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschränkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.Security; |
|||
using System.Security.Claims; |
|||
using System.Threading.Tasks; |
|||
using FakeItEasy; |
|||
using Microsoft.AspNetCore.Http; |
|||
using Squidex.Domain.Apps.Entities.Contents.Commands; |
|||
using Squidex.Infrastructure.Commands; |
|||
using Squidex.Infrastructure.Security; |
|||
using Squidex.Pipeline.CommandMiddlewares; |
|||
using Xunit; |
|||
|
|||
namespace Squidex.Tests.Pipeline.CommandMiddlewares |
|||
{ |
|||
public class EnrichWithActorCommandMiddlewareTests |
|||
{ |
|||
private readonly IHttpContextAccessor httpContextAccessor = A.Fake<IHttpContextAccessor>(); |
|||
private readonly ICommandBus commandBus = A.Fake<ICommandBus>(); |
|||
private readonly CreateContent command = new CreateContent { Actor = null }; |
|||
|
|||
[Fact] |
|||
public async Task HandleAsync_should_throw_security_exception() |
|||
{ |
|||
var context = new CommandContext(command, commandBus); |
|||
var sut = SetupSystem(null, out string claimValue); |
|||
|
|||
await Assert.ThrowsAsync<SecurityException>(() => |
|||
{ |
|||
return sut.HandleAsync(context); |
|||
}); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task HandleAsync_should_find_actor_from_subject() |
|||
{ |
|||
var context = new CommandContext(command, commandBus); |
|||
var sut = SetupSystem("subject", out string claimValue); |
|||
|
|||
await sut.HandleAsync(context); |
|||
|
|||
Assert.Equal(claimValue, command.Actor.Identifier); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task HandleAsync_should_find_actor_from_client() |
|||
{ |
|||
var context = new CommandContext(command, commandBus); |
|||
var sut = SetupSystem("client", out string claimValue); |
|||
|
|||
await sut.HandleAsync(context); |
|||
|
|||
Assert.Equal(claimValue, command.Actor.Identifier); |
|||
} |
|||
|
|||
private EnrichWithActorCommandMiddleware SetupSystem(string refTokenType, out string claimValue) |
|||
{ |
|||
Claim actorClaim; |
|||
claimValue = Guid.NewGuid().ToString(); |
|||
var user = new ClaimsPrincipal(); |
|||
var claimsIdentity = new ClaimsIdentity(); |
|||
switch (refTokenType) |
|||
{ |
|||
case "subject": |
|||
actorClaim = new Claim(OpenIdClaims.Subject, claimValue); |
|||
claimsIdentity.AddClaim(actorClaim); |
|||
break; |
|||
case "client": |
|||
actorClaim = new Claim(OpenIdClaims.ClientId, claimValue); |
|||
claimsIdentity.AddClaim(actorClaim); |
|||
break; |
|||
} |
|||
|
|||
user.AddIdentity(claimsIdentity); |
|||
A.CallTo(() => httpContextAccessor.HttpContext.User).Returns(user); |
|||
return new EnrichWithActorCommandMiddleware(httpContextAccessor); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,65 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschränkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using FakeItEasy; |
|||
using Microsoft.AspNetCore.Http; |
|||
using Squidex.Domain.Apps.Entities.Apps; |
|||
using Squidex.Domain.Apps.Entities.Apps.State; |
|||
using Squidex.Domain.Apps.Entities.Contents.Commands; |
|||
using Squidex.Infrastructure; |
|||
using Squidex.Infrastructure.Commands; |
|||
using Squidex.Pipeline; |
|||
using Squidex.Pipeline.CommandMiddlewares; |
|||
using Xunit; |
|||
using static Squidex.Pipeline.AppApiFilter; |
|||
|
|||
namespace Squidex.Tests.Pipeline.CommandMiddlewares |
|||
{ |
|||
public class EnrichWithAppIdCommandMiddlewareTests |
|||
{ |
|||
private readonly IHttpContextAccessor httpContextAccessor = A.Fake<IHttpContextAccessor>(); |
|||
private readonly ICommandBus commandBus = A.Fake<ICommandBus>(); |
|||
private readonly CreateContent command = new CreateContent { AppId = null }; |
|||
|
|||
[Fact] |
|||
public async Task HandleAsync_should_throw_exception_if_app_id_not_found() |
|||
{ |
|||
var context = new CommandContext(command, commandBus); |
|||
var sut = SetupSystem(null); |
|||
|
|||
await Assert.ThrowsAsync<InvalidOperationException>(() => |
|||
{ |
|||
return sut.HandleAsync(context); |
|||
}); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task HandleAsync_should_find_app_id_from_features() |
|||
{ |
|||
var context = new CommandContext(command, commandBus); |
|||
var app = new AppState |
|||
{ |
|||
Name = "app", |
|||
Id = Guid.NewGuid() |
|||
}; |
|||
var sut = SetupSystem(app); |
|||
|
|||
await sut.HandleAsync(context); |
|||
|
|||
Assert.Equal(new NamedId<Guid>(app.Id, app.Name), command.AppId); |
|||
} |
|||
|
|||
private EnrichWithAppIdCommandMiddleware SetupSystem(IAppEntity app) |
|||
{ |
|||
var appFeature = app == null ? null : new AppFeature(app); |
|||
A.CallTo(() => httpContextAccessor.HttpContext.Features.Get<IAppFeature>()).Returns(appFeature); |
|||
|
|||
return new EnrichWithAppIdCommandMiddleware(httpContextAccessor); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,122 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschränkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using FakeItEasy; |
|||
using Microsoft.AspNetCore.Http; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.AspNetCore.Mvc.Abstractions; |
|||
using Microsoft.AspNetCore.Mvc.Infrastructure; |
|||
using Microsoft.AspNetCore.Routing; |
|||
using Moq; |
|||
using Squidex.Domain.Apps.Core; |
|||
using Squidex.Domain.Apps.Core.Schemas; |
|||
using Squidex.Domain.Apps.Entities; |
|||
using Squidex.Domain.Apps.Entities.Contents.Commands; |
|||
using Squidex.Domain.Apps.Entities.Schemas; |
|||
using Squidex.Domain.Apps.Entities.Schemas.State; |
|||
using Squidex.Infrastructure; |
|||
using Squidex.Infrastructure.Commands; |
|||
using Squidex.Pipeline.CommandMiddlewares; |
|||
using Xunit; |
|||
|
|||
namespace Squidex.Tests.Pipeline.CommandMiddlewares |
|||
{ |
|||
public class EnrichWithSchemaIdCommandMiddlewareTests |
|||
{ |
|||
private readonly Mock<IActionContextAccessor> actionContextAccessor = new Mock<IActionContextAccessor>(); |
|||
private readonly ICommandBus commandBus = A.Fake<ICommandBus>(); |
|||
private readonly Mock<HttpContext> httpContextMock = new Mock<HttpContext>(); |
|||
private readonly ActionDescriptor actionDescriptor = new ActionDescriptor(); |
|||
private readonly IAppProvider appProvider = A.Fake<IAppProvider>(); |
|||
private readonly Guid appId = Guid.NewGuid(); |
|||
private readonly string appName = "app"; |
|||
private readonly Guid schemaId = Guid.NewGuid(); |
|||
private readonly string schemaName = "schema"; |
|||
private readonly CreateContent command = new CreateContent(); |
|||
private readonly RouteData routeData = new RouteData(); |
|||
private ISchemaEntity schema; |
|||
|
|||
[Fact] |
|||
public async Task HandleAsync_should_throw_exception_if_schema_not_found() |
|||
{ |
|||
var context = new CommandContext(command, commandBus); |
|||
var sut = SetupSchemaCommand(false); |
|||
|
|||
await Assert.ThrowsAsync<DomainObjectNotFoundException>(() => |
|||
{ |
|||
return sut.HandleAsync(context); |
|||
}); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task HandleAsync_should_find_schema_id_by_name() |
|||
{ |
|||
var context = new CommandContext(command, commandBus); |
|||
SetupSchema(); |
|||
|
|||
var sut = SetupSchemaCommand(false); |
|||
|
|||
await sut.HandleAsync(context); |
|||
|
|||
Assert.Equal(new NamedId<Guid>(schemaId, schemaName), command.SchemaId); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task HandleAsync_should_find_schema_id_by_id() |
|||
{ |
|||
var context = new CommandContext(command, commandBus); |
|||
SetupSchema(); |
|||
|
|||
var sut = SetupSchemaCommand(true); |
|||
|
|||
await sut.HandleAsync(context); |
|||
|
|||
Assert.Equal(new NamedId<Guid>(schemaId, schemaName), command.SchemaId); |
|||
} |
|||
|
|||
private void SetupSchema() |
|||
{ |
|||
var schemaDef = new Schema(schemaName); |
|||
var stringValidatorProperties = new StringFieldProperties |
|||
{ |
|||
Pattern = "A-Z" |
|||
}; |
|||
var stringFieldWithValidator = new StringField(1, "validator", Partitioning.Invariant, stringValidatorProperties); |
|||
|
|||
schemaDef = schemaDef.AddField(stringFieldWithValidator); |
|||
|
|||
schema = new SchemaState |
|||
{ |
|||
Name = schemaName, |
|||
Id = schemaId, |
|||
AppId = new NamedId<Guid>(appId, appName), |
|||
SchemaDef = schemaDef |
|||
}; |
|||
} |
|||
|
|||
private EnrichWithSchemaIdCommandMiddleware SetupSchemaCommand(bool byId) |
|||
{ |
|||
command.AppId = new NamedId<Guid>(appId, appName); |
|||
|
|||
if (byId) |
|||
{ |
|||
routeData.Values.Add("name", schemaId.ToString()); |
|||
A.CallTo(() => appProvider.GetSchemaAsync(appId, schemaId, false)).Returns(schema); |
|||
} |
|||
else |
|||
{ |
|||
routeData.Values.Add("name", "schema"); |
|||
A.CallTo(() => appProvider.GetSchemaAsync(appId, schemaName)).Returns(schema); |
|||
} |
|||
|
|||
var actionContext = new ActionContext(httpContextMock.Object, routeData, actionDescriptor); |
|||
actionContextAccessor.Setup(x => x.ActionContext).Returns(actionContext); |
|||
return new EnrichWithSchemaIdCommandMiddleware(appProvider, actionContextAccessor.Object); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,77 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschränkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Http; |
|||
using Microsoft.Extensions.Options; |
|||
using Moq; |
|||
using Squidex.Config; |
|||
using Squidex.Pipeline; |
|||
using Xunit; |
|||
|
|||
namespace Squidex.Tests.Pipeline |
|||
{ |
|||
public class EnforceHttpsMiddlewareTests |
|||
{ |
|||
private readonly Mock<RequestDelegate> next = new Mock<RequestDelegate>(); |
|||
private readonly Mock<HttpContext> httpContextMock = new Mock<HttpContext>(); |
|||
private readonly Mock<HttpRequest> requestMock = new Mock<HttpRequest>(); |
|||
private readonly Mock<HttpResponse> responseMock = new Mock<HttpResponse>(); |
|||
private IOptions<MyUrlsOptions> urls; |
|||
private EnforceHttpsMiddleware sut; |
|||
|
|||
public EnforceHttpsMiddlewareTests() |
|||
{ |
|||
requestMock.Setup(x => x.Host).Returns(new HostString("test.squidex.com")); |
|||
requestMock.Setup(x => x.Scheme).Returns("https"); |
|||
httpContextMock.Setup(x => x.Request).Returns(requestMock.Object); |
|||
httpContextMock.Setup(x => x.Response).Returns(responseMock.Object); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_Continue_EnforceHTTPS_Is_False_Then_Return() |
|||
{ |
|||
urls = new OptionsManager<MyUrlsOptions>(new OptionsFactory<MyUrlsOptions>( |
|||
new List<IConfigureOptions<MyUrlsOptions>>(), new List<IPostConfigureOptions<MyUrlsOptions>>())); |
|||
urls.Value.EnforceHTTPS = false; |
|||
|
|||
sut = new EnforceHttpsMiddleware(next.Object, urls); |
|||
await sut.Invoke(httpContextMock.Object); |
|||
|
|||
next.Verify(x => x(It.IsAny<HttpContext>()), Times.Once); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_Call_Next_If_EnforceHTTPS_Is_True_And_Request_Scheme_Is_Https() |
|||
{ |
|||
urls = new OptionsManager<MyUrlsOptions>(new OptionsFactory<MyUrlsOptions>( |
|||
new List<IConfigureOptions<MyUrlsOptions>>(), new List<IPostConfigureOptions<MyUrlsOptions>>())); |
|||
urls.Value.EnforceHTTPS = true; |
|||
|
|||
sut = new EnforceHttpsMiddleware(next.Object, urls); |
|||
await sut.Invoke(httpContextMock.Object); |
|||
|
|||
next.Verify(x => x(It.IsAny<HttpContext>()), Times.Once); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_Call_Next_If_EnforceHTTPS_Is_False_Then_Return() |
|||
{ |
|||
urls = new OptionsManager<MyUrlsOptions>(new OptionsFactory<MyUrlsOptions>( |
|||
new List<IConfigureOptions<MyUrlsOptions>>(), new List<IPostConfigureOptions<MyUrlsOptions>>())); |
|||
urls.Value.EnforceHTTPS = true; |
|||
|
|||
requestMock.Setup(x => x.Scheme).Returns("http"); |
|||
sut = new EnforceHttpsMiddleware(next.Object, urls); |
|||
await sut.Invoke(httpContextMock.Object); |
|||
|
|||
next.Verify(x => x(It.IsAny<HttpContext>()), Times.Never); |
|||
responseMock.Verify(x => x.Redirect(It.IsAny<string>(), true), Times.Once); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,70 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschränkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.IO; |
|||
using System.Threading.Tasks; |
|||
using FakeItEasy; |
|||
using Microsoft.AspNetCore.Http; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.AspNetCore.Mvc.Abstractions; |
|||
using Microsoft.AspNetCore.Routing; |
|||
using Microsoft.Extensions.Logging; |
|||
using Moq; |
|||
using Squidex.Pipeline; |
|||
using Xunit; |
|||
|
|||
namespace Squidex.Tests.Pipeline |
|||
{ |
|||
public class FileCallbackResultTests |
|||
{ |
|||
private readonly ILoggerFactory loggerFactory = A.Fake<ILoggerFactory>(); |
|||
private readonly ActionContext context; |
|||
private readonly ActionDescriptor actionDescriptor = new ActionDescriptor(); |
|||
private readonly Mock<HttpContext> httpContext = new Mock<HttpContext>(); |
|||
private readonly Mock<HttpRequest> requestMock = new Mock<HttpRequest>(); |
|||
private readonly Mock<HttpResponse> responseMock = new Mock<HttpResponse>(); |
|||
private readonly Mock<IServiceProvider> serviceProvider = new Mock<IServiceProvider>(); |
|||
private readonly Func<Stream, Task> callback; |
|||
private readonly FileCallbackResult sut; |
|||
private readonly FileCallbackResultExecutor callbackExecutor; |
|||
private bool callbackWasCalled; |
|||
|
|||
public FileCallbackResultTests() |
|||
{ |
|||
requestMock.Setup(x => x.Headers).Returns(new HeaderDictionary()); |
|||
responseMock.Setup(x => x.Headers).Returns(new HeaderDictionary()); |
|||
httpContext.Setup(x => x.RequestServices).Returns(serviceProvider.Object); |
|||
httpContext.Setup(x => x.Request).Returns(requestMock.Object); |
|||
httpContext.Setup(x => x.Response).Returns(responseMock.Object); |
|||
|
|||
context = new ActionContext(httpContext.Object, new RouteData(), actionDescriptor); |
|||
callback = async bodyStream => { callbackWasCalled = true; }; |
|||
callbackExecutor = new FileCallbackResultExecutor(loggerFactory); |
|||
sut = new FileCallbackResult("text/plain", "test.txt", callback); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_Execute_Callback_Function() |
|||
{ |
|||
serviceProvider.Setup(x => x.GetService(It.IsAny<Type>())).Returns(callbackExecutor); |
|||
await sut.ExecuteResultAsync(context); |
|||
|
|||
Assert.True(callbackWasCalled); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_Not_Call_Callback_If_Exception_Thrown_While_Logging() |
|||
{ |
|||
httpContext.Setup(x => x.Request).Returns((HttpRequest)null); |
|||
serviceProvider.Setup(x => x.GetService(It.IsAny<Type>())).Returns(callbackExecutor); |
|||
await sut.ExecuteResultAsync(context); |
|||
|
|||
Assert.False(callbackWasCalled); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,120 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschränkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using System.Threading.Tasks; |
|||
using FakeItEasy; |
|||
using Microsoft.AspNetCore.Http; |
|||
using NJsonSchema; |
|||
using NSwag; |
|||
using NSwag.AspNetCore; |
|||
using NSwag.SwaggerGeneration; |
|||
using Squidex.Config; |
|||
using Squidex.Infrastructure; |
|||
using Squidex.Pipeline.Swagger; |
|||
using Xunit; |
|||
|
|||
namespace Squidex.Tests.Pipeline.Swagger |
|||
{ |
|||
public class SwaggerHelperTests |
|||
{ |
|||
private readonly IHttpContextAccessor contextAccessor = A.Fake<IHttpContextAccessor>(); |
|||
private readonly string appName = "app"; |
|||
private readonly string host = "kraken"; |
|||
private readonly MyUrlsOptions myUrlsOptions = new MyUrlsOptions { BaseUrl = "www.test.com" }; |
|||
private readonly SwaggerOperation operation = new SwaggerOperation(); |
|||
|
|||
[Fact] |
|||
public void Should_load_docs() |
|||
{ |
|||
var doc = SwaggerHelper.LoadDocs("security"); |
|||
Assert.StartsWith("Squidex", doc); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_throw_exception_when_base_url_is_empty() |
|||
{ |
|||
var testUrlOptions = new MyUrlsOptions(); |
|||
Assert.Throws<ConfigurationException>(() => testUrlOptions.BuildUrl("/api")); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_create_swagger_document() |
|||
{ |
|||
var swaggerDoc = CreateSwaggerDocument(); |
|||
|
|||
Assert.NotNull(swaggerDoc.Tags); |
|||
Assert.Contains("application/json", swaggerDoc.Consumes); |
|||
Assert.Contains("application/json", swaggerDoc.Produces); |
|||
Assert.NotNull(swaggerDoc.Info.ExtensionData["x-logo"]); |
|||
Assert.Equal($"Squidex API for {appName} App", swaggerDoc.Info.Title); |
|||
Assert.Equal("/api", swaggerDoc.BasePath); |
|||
Assert.Equal(host, swaggerDoc.Host); |
|||
Assert.NotEmpty(swaggerDoc.SecurityDefinitions); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_create_OAuth_schema() |
|||
{ |
|||
var oauthSchema = SwaggerHelper.CreateOAuthSchema(myUrlsOptions); |
|||
|
|||
Assert.Equal(myUrlsOptions.BuildUrl($"{Constants.IdentityServerPrefix}/connect/token"), oauthSchema.TokenUrl); |
|||
Assert.Equal(SwaggerSecuritySchemeType.OAuth2, oauthSchema.Type); |
|||
Assert.Equal(SwaggerOAuth2Flow.Application, oauthSchema.Flow); |
|||
Assert.NotEmpty(oauthSchema.Scopes); |
|||
Assert.Contains(myUrlsOptions.BuildUrl($"{Constants.IdentityServerPrefix}/connect/token"), |
|||
oauthSchema.Description); |
|||
Assert.DoesNotContain("<TOKEN_URL>", oauthSchema.Description); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_get_error_dto_schema() |
|||
{ |
|||
var swaggerDoc = CreateSwaggerDocument(); |
|||
|
|||
var schemaGenerator = new SwaggerJsonSchemaGenerator(new SwaggerSettings()); |
|||
var schemaResolver = new SwaggerSchemaResolver(swaggerDoc, new SwaggerSettings()); |
|||
var errorDto = await schemaGenerator.GetErrorDtoSchemaAsync(schemaResolver); |
|||
|
|||
Assert.NotNull(errorDto); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_add_query_parameter() |
|||
{ |
|||
operation.AddQueryParameter("test", JsonObjectType.String, "Test parameter"); |
|||
Assert.Contains(operation.Parameters, p => p.Kind == SwaggerParameterKind.Query); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_add_path_parameter() |
|||
{ |
|||
operation.AddPathParameter("test", JsonObjectType.String, "Test parameter"); |
|||
Assert.Contains(operation.Parameters, p => p.Kind == SwaggerParameterKind.Path); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_add_body_parameter() |
|||
{ |
|||
operation.AddBodyParameter("test", null, "Test parameter"); |
|||
Assert.Contains(operation.Parameters, p => p.Kind == SwaggerParameterKind.Body); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_add_response_parameter() |
|||
{ |
|||
operation.AddResponse("200", "Test is ok"); |
|||
Assert.Contains(operation.Responses, r => r.Key == "200"); |
|||
} |
|||
|
|||
private SwaggerDocument CreateSwaggerDocument() |
|||
{ |
|||
A.CallTo(() => contextAccessor.HttpContext.Request.Scheme).Returns("http"); |
|||
A.CallTo(() => contextAccessor.HttpContext.Request.Host).Returns(new HostString(host)); |
|||
return SwaggerHelper.CreateApiDocument(contextAccessor.HttpContext, myUrlsOptions, appName); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netcoreapp2.0</TargetFramework> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="FakeItEasy" Version="4.3.0" /> |
|||
<PackageReference Include="IdentityServer4" Version="2.1.1" /> |
|||
<PackageReference Include="IdentityServer4.AspNetIdentity" Version="2.1.0" /> |
|||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" /> |
|||
<PackageReference Include="Moq" Version="4.7.145" /> |
|||
<PackageReference Include="NJsonSchema" Version="9.10.19" /> |
|||
<PackageReference Include="xunit" Version="2.3.1" /> |
|||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\src\Squidex.Domain.Users\Squidex.Domain.Users.csproj" /> |
|||
<ProjectReference Include="..\..\src\Squidex\Squidex.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<Reference Include="CivicPlusIdentityServer.SDK.NetCore"> |
|||
<HintPath>..\..\..\identityserver\CivicPlusIdentityServer.SDK.NetCore\bin\Debug\netcoreapp2.0\CivicPlusIdentityServer.SDK.NetCore.dll</HintPath> |
|||
</Reference> |
|||
<Reference Include="RestSharp"> |
|||
<HintPath>..\..\..\restsharp_core\RestSharp\bin\Debug\netstandard2.0\RestSharp.dll</HintPath> |
|||
</Reference> |
|||
<Reference Include="RestSharp.NetCore"> |
|||
<HintPath>..\..\..\..\Desktop\RestSharp.NetCore.dll</HintPath> |
|||
</Reference> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
Loading…
Reference in new issue