mirror of https://github.com/Squidex/squidex.git
19 changed files with 420 additions and 934 deletions
@ -1,86 +0,0 @@ |
|||
// ==========================================================================
|
|||
// 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); |
|||
} |
|||
} |
|||
} |
|||
@ -1,32 +0,0 @@ |
|||
// ==========================================================================
|
|||
// 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); |
|||
} |
|||
} |
|||
} |
|||
@ -1,104 +0,0 @@ |
|||
// ==========================================================================
|
|||
// 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; |
|||
} |
|||
} |
|||
} |
|||
@ -1,101 +0,0 @@ |
|||
// ==========================================================================
|
|||
// 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 }; |
|||
} |
|||
} |
|||
} |
|||
@ -1,90 +0,0 @@ |
|||
// ==========================================================================
|
|||
// 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); |
|||
} |
|||
} |
|||
} |
|||
@ -1,130 +0,0 @@ |
|||
// ==========================================================================
|
|||
// 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()); |
|||
} |
|||
} |
|||
} |
|||
@ -1,70 +0,0 @@ |
|||
// ==========================================================================
|
|||
// 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); |
|||
} |
|||
} |
|||
} |
|||
@ -1,120 +0,0 @@ |
|||
// ==========================================================================
|
|||
// 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); |
|||
} |
|||
} |
|||
} |
|||
@ -1,39 +1,31 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<PropertyGroup> |
|||
<OutputType>Exe</OutputType> |
|||
<TargetFramework>netcoreapp2.0</TargetFramework> |
|||
<RootNamespace>Squidex</RootNamespace> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="FakeItEasy" Version="4.3.0" /> |
|||
<PackageReference Include="IdentityServer4" Version="2.1.1" /> |
|||
<ProjectReference Include="..\..\src\Squidex.Domain.Users\Squidex.Domain.Users.csproj" /> |
|||
<ProjectReference Include="..\..\src\Squidex\Squidex.csproj" /> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<PackageReference Include="FakeItEasy" Version="4.5.1" /> |
|||
<PackageReference Include="IdentityServer4" Version="2.1.2" /> |
|||
<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="Microsoft.NET.Test.Sdk" Version="15.6.1" /> |
|||
<PackageReference Include="NJsonSchema" Version="9.10.35" /> |
|||
<PackageReference Include="RefactoringEssentials" Version="5.6.0" /> |
|||
<PackageReference Include="StyleCop.Analyzers" Version="1.0.2" /> |
|||
<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> |
|||
<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="2.0.0" /> |
|||
</ItemGroup> |
|||
|
|||
<PropertyGroup> |
|||
<CodeAnalysisRuleSet>..\..\Squidex.ruleset</CodeAnalysisRuleSet> |
|||
</PropertyGroup> |
|||
<ItemGroup> |
|||
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" /> |
|||
<AdditionalFiles Include="..\..\stylecop.json" Link="stylecop.json" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
|
|||
Loading…
Reference in new issue