Browse Source

More tests

pull/268/head
Sebastian Stehle 8 years ago
parent
commit
454f84b874
  1. 2
      src/Squidex.Infrastructure/UsageTracking/BackgroundUsageTracker.cs
  2. 2
      src/Squidex.Infrastructure/UsageTracking/IUsageTracker.cs
  3. 2
      src/Squidex/Areas/Api/Controllers/Statistics/UsagesController.cs
  4. 20
      src/Squidex/Pipeline/ApiCostsFilter.cs
  5. 4
      tests/Squidex.Infrastructure.Tests/UsageTracking/BackgroundUsageTrackerTests.cs
  6. 168
      tests/Squidex.Tests/Pipeline/ApiCostsFilterTests.cs
  7. 2
      tests/Squidex.Tests/Pipeline/EnforceHttpsMiddlewareTests.cs

2
src/Squidex.Infrastructure/UsageTracking/BackgroundUsageTracker.cs

@ -108,7 +108,7 @@ namespace Squidex.Infrastructure.UsageTracking
return enrichedUsages;
}
public async Task<long> GetMonthlyCalls(string key, DateTime date)
public async Task<long> GetMonthlyCallsAsync(string key, DateTime date)
{
ThrowIfDisposed();

2
src/Squidex.Infrastructure/UsageTracking/IUsageTracker.cs

@ -15,7 +15,7 @@ namespace Squidex.Infrastructure.UsageTracking
{
Task TrackAsync(string key, double weight, double elapsedMs);
Task<long> GetMonthlyCalls(string key, DateTime date);
Task<long> GetMonthlyCallsAsync(string key, DateTime date);
Task<IReadOnlyList<StoredUsage>> QueryAsync(string key, DateTime fromDate, DateTime toDate);
}

2
src/Squidex/Areas/Api/Controllers/Statistics/UsagesController.cs

@ -60,7 +60,7 @@ namespace Squidex.Areas.Api.Controllers.Statistics
[ApiCosts(0)]
public async Task<IActionResult> GetMonthlyCalls(string app)
{
var count = await usageTracker.GetMonthlyCalls(App.Id.ToString(), DateTime.Today);
var count = await usageTracker.GetMonthlyCallsAsync(App.Id.ToString(), DateTime.Today);
var plan = appPlanProvider.GetPlanForApp(App);

20
src/Squidex/Pipeline/ApiCostsFilter.cs

@ -47,20 +47,20 @@ namespace Squidex.Pipeline
if (appFeature?.App != null && FilterDefinition.Weight > 0)
{
var stopWatch = Stopwatch.StartNew();
var plan = appPlanProvider.GetPlanForApp(appFeature.App);
try
{
var plan = appPlanProvider.GetPlanForApp(appFeature.App);
var usage = await usageTracker.GetMonthlyCallsAsync(appFeature.App.Id.ToString(), DateTime.Today);
var usage = await usageTracker.GetMonthlyCalls(appFeature.App.Id.ToString(), DateTime.Today);
if (plan.MaxApiCalls >= 0 && usage > plan.MaxApiCalls * 1.1)
{
context.Result = new StatusCodeResult(429);
return;
}
if (plan.MaxApiCalls >= 0 && (usage * 1.1) > plan.MaxApiCalls)
{
context.Result = new StatusCodeResult(429);
return;
}
var stopWatch = Stopwatch.StartNew();
try
{
await next();
}
finally

4
tests/Squidex.Infrastructure.Tests/UsageTracking/BackgroundUsageTrackerTests.cs

@ -48,7 +48,7 @@ namespace Squidex.Infrastructure.UsageTracking
{
sut.Dispose();
return Assert.ThrowsAsync<ObjectDisposedException>(() => sut.GetMonthlyCalls("key1", DateTime.Today));
return Assert.ThrowsAsync<ObjectDisposedException>(() => sut.GetMonthlyCallsAsync("key1", DateTime.Today));
}
[Fact]
@ -67,7 +67,7 @@ namespace Squidex.Infrastructure.UsageTracking
A.CallTo(() => usageStore.QueryAsync("key", new DateTime(2016, 1, 1), new DateTime(2016, 1, 31)))
.Returns(originalData);
var result = await sut.GetMonthlyCalls("key", date);
var result = await sut.GetMonthlyCallsAsync("key", date);
Assert.Equal(55, result);
}

168
tests/Squidex.Tests/Pipeline/ApiCostsFilterTests.cs

@ -0,0 +1,168 @@
// ==========================================================================
// 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.Mvc;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Routing;
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 ApiCostsFilterTests
{
private readonly IActionContextAccessor actionContextAccessor = A.Fake<IActionContextAccessor>();
private readonly IAppEntity appEntity = A.Fake<IAppEntity>();
private readonly IAppPlansProvider appPlanProvider = A.Fake<IAppPlansProvider>();
private readonly IUsageTracker usageTracker = A.Fake<IUsageTracker>();
private readonly IAppLimitsPlan appPlan = A.Fake<IAppLimitsPlan>();
private readonly ActionExecutingContext actionContext;
private readonly HttpContext httpContext = new DefaultHttpContext();
private readonly ActionExecutionDelegate next;
private readonly ApiCostsFilter sut;
private long apiCallsMax;
private long apiCallsCurrent;
private bool isNextCalled;
public ApiCostsFilterTests()
{
actionContext =
new ActionExecutingContext(
new ActionContext(httpContext, new RouteData(),
new ActionDescriptor()),
new List<IFilterMetadata>(), new Dictionary<string, object>(), null);
A.CallTo(() => actionContextAccessor.ActionContext)
.Returns(actionContext);
A.CallTo(() => appPlanProvider.GetPlan(null))
.Returns(appPlan);
A.CallTo(() => appPlanProvider.GetPlanForApp(appEntity))
.Returns(appPlan);
A.CallTo(() => appPlan.MaxApiCalls)
.ReturnsLazily(x => apiCallsMax);
A.CallTo(() => usageTracker.GetMonthlyCallsAsync(A<string>.Ignored, DateTime.Today))
.ReturnsLazily(x => Task.FromResult(apiCallsCurrent));
next = () =>
{
isNextCalled = true;
return Task.FromResult<ActionExecutedContext>(null);
};
sut = new ApiCostsFilter(appPlanProvider, usageTracker);
}
[Fact]
public async Task Should_return_429_status_code_if_max_calls_over_limit()
{
sut.FilterDefinition = new ApiCostsAttribute(1);
SetupApp();
apiCallsCurrent = 1000;
apiCallsMax = 600;
await sut.OnActionExecutionAsync(actionContext, next);
Assert.Equal(429, (actionContext.Result as StatusCodeResult).StatusCode);
Assert.False(isNextCalled);
A.CallTo(() => usageTracker.TrackAsync(A<string>.Ignored, A<double>.Ignored, A<double>.Ignored))
.MustNotHaveHappened();
}
[Fact]
public async Task Should_track_if_calls_left()
{
sut.FilterDefinition = new ApiCostsAttribute(13);
SetupApp();
apiCallsCurrent = 1000;
apiCallsMax = 1600;
await sut.OnActionExecutionAsync(actionContext, next);
Assert.True(isNextCalled);
A.CallTo(() => usageTracker.TrackAsync(A<string>.Ignored, 13, A<double>.Ignored))
.MustHaveHappened();
}
[Fact]
public async Task Should_allow_small_buffer()
{
sut.FilterDefinition = new ApiCostsAttribute(13);
SetupApp();
apiCallsCurrent = 1099;
apiCallsMax = 1000;
await sut.OnActionExecutionAsync(actionContext, next);
Assert.True(isNextCalled);
A.CallTo(() => usageTracker.TrackAsync(A<string>.Ignored, 13, A<double>.Ignored))
.MustHaveHappened();
}
[Fact]
public async Task Should_not_track_if_weight_is_zero()
{
sut.FilterDefinition = new ApiCostsAttribute(0);
SetupApp();
apiCallsCurrent = 1000;
apiCallsMax = 600;
await sut.OnActionExecutionAsync(actionContext, next);
Assert.True(isNextCalled);
A.CallTo(() => usageTracker.TrackAsync(A<string>.Ignored, A<double>.Ignored, A<double>.Ignored))
.MustNotHaveHappened();
}
[Fact]
public async Task Should_not_track_if_app_not_defined()
{
sut.FilterDefinition = new ApiCostsAttribute(1);
apiCallsCurrent = 1000;
apiCallsMax = 600;
await sut.OnActionExecutionAsync(actionContext, next);
Assert.True(isNextCalled);
A.CallTo(() => usageTracker.TrackAsync(A<string>.Ignored, A<double>.Ignored, A<double>.Ignored))
.MustNotHaveHappened();
}
private void SetupApp()
{
httpContext.Features.Set<IAppFeature>(new AppApiFilter.AppFeature(appEntity));
}
}
}

2
tests/Squidex.Tests/Pipeline/EnforceHttpsMiddlewareTests.cs

@ -16,8 +16,8 @@ namespace Squidex.Pipeline
{
public class EnforceHttpsMiddlewareTests
{
private readonly RequestDelegate next;
private bool isNextCalled;
private RequestDelegate next;
public EnforceHttpsMiddlewareTests()
{

Loading…
Cancel
Save