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"> |
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
<PropertyGroup> |
||||
<PropertyGroup> |
<OutputType>Exe</OutputType> |
||||
<TargetFramework>netcoreapp2.0</TargetFramework> |
<TargetFramework>netcoreapp2.0</TargetFramework> |
||||
|
<RootNamespace>Squidex</RootNamespace> |
||||
</PropertyGroup> |
</PropertyGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<PackageReference Include="FakeItEasy" Version="4.3.0" /> |
<ProjectReference Include="..\..\src\Squidex.Domain.Users\Squidex.Domain.Users.csproj" /> |
||||
<PackageReference Include="IdentityServer4" Version="2.1.1" /> |
<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="IdentityServer4.AspNetIdentity" Version="2.1.0" /> |
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" /> |
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.6.1" /> |
||||
<PackageReference Include="Moq" Version="4.7.145" /> |
<PackageReference Include="NJsonSchema" Version="9.10.35" /> |
||||
<PackageReference Include="NJsonSchema" Version="9.10.19" /> |
<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" Version="2.3.1" /> |
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" /> |
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<ProjectReference Include="..\..\src\Squidex.Domain.Users\Squidex.Domain.Users.csproj" /> |
<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="2.0.0" /> |
||||
<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> |
||||
|
<PropertyGroup> |
||||
|
<CodeAnalysisRuleSet>..\..\Squidex.ruleset</CodeAnalysisRuleSet> |
||||
|
</PropertyGroup> |
||||
<ItemGroup> |
<ItemGroup> |
||||
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" /> |
<AdditionalFiles Include="..\..\stylecop.json" Link="stylecop.json" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
|
|
||||
</Project> |
</Project> |
||||
|
|||||
Loading…
Reference in new issue