From d81c2d2cd7492b9a8861fe65acd4f7532b13bbe4 Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Sun, 29 Oct 2017 21:46:30 +0100 Subject: [PATCH] Test added, damn --- .../Rules/RuleDequeuerTests.cs | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 tests/Squidex.Domain.Apps.Read.Tests/Rules/RuleDequeuerTests.cs diff --git a/tests/Squidex.Domain.Apps.Read.Tests/Rules/RuleDequeuerTests.cs b/tests/Squidex.Domain.Apps.Read.Tests/Rules/RuleDequeuerTests.cs new file mode 100644 index 000000000..8914346d7 --- /dev/null +++ b/tests/Squidex.Domain.Apps.Read.Tests/Rules/RuleDequeuerTests.cs @@ -0,0 +1,124 @@ +// ========================================================================== +// RuleDequeuerTests.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System; +using System.Threading; +using System.Threading.Tasks; +using FakeItEasy; +using NodaTime; +using Squidex.Domain.Apps.Core.HandleRules; +using Squidex.Domain.Apps.Core.Rules; +using Squidex.Domain.Apps.Read.Rules.Repositories; +using Squidex.Infrastructure.Log; +using Xunit; + +#pragma warning disable RECS0165 // Asynchronous methods should return a Task instead of void + +namespace Squidex.Domain.Apps.Read.Rules +{ + public class RuleDequeuerTests + { + private readonly IClock clock = A.Fake(); + private readonly ISemanticLog log = A.Fake(); + private readonly IRuleRepository ruleRepository = A.Fake(); + private readonly IRuleEventRepository ruleEventRepository = A.Fake(); + private readonly RuleService ruleService = A.Fake(); + private readonly Instant now = SystemClock.Instance.GetCurrentInstant(); + + public RuleDequeuerTests() + { + A.CallTo(() => clock.GetCurrentInstant()).Returns(now); + } + + [Theory] + [InlineData(0, 0, RuleResult.Success, RuleJobResult.Success)] + [InlineData(0, 5, RuleResult.Timeout, RuleJobResult.Retry)] + [InlineData(1, 60, RuleResult.Timeout, RuleJobResult.Retry)] + [InlineData(2, 360, RuleResult.Failed, RuleJobResult.Retry)] + [InlineData(3, 720, RuleResult.Failed, RuleJobResult.Retry)] + [InlineData(4, 0, RuleResult.Failed, RuleJobResult.Failed)] + public void Should_set_next_attempt_based_on_num_calls(int calls, int minutes, RuleResult result, RuleJobResult jobResult) + { + var actionData = new RuleJobData(); + var actionName = "MyAction"; + + var @event = CreateEvent(calls, actionName, actionData); + + var requestElapsed = TimeSpan.FromMinutes(1); + var requestDump = "Dump"; + + SetupSender(@event, requestDump, result, requestElapsed); + SetupPendingEvents(@event); + + var sut = new RuleDequeuer( + ruleService, + ruleEventRepository, + log, + clock); + + sut.Next(); + sut.Dispose(); + + Instant? nextCall = null; + + if (minutes > 0) + { + nextCall = now.Plus(Duration.FromMinutes(minutes)); + } + + VerifyRepositories(@event, requestDump, result, jobResult, requestElapsed, nextCall); + } + + private void SetupSender(IRuleEventEntity @event, string requestDump, RuleResult requestResult, TimeSpan requestTime) + { + A.CallTo(() => ruleService.InvokeAsync(@event.Job.ActionName, @event.Job.ActionData)) + .Returns((requestDump, requestResult, requestTime)); + } + + private void SetupPendingEvents(IRuleEventEntity @event) + { + A.CallTo(() => ruleEventRepository.QueryPendingAsync( + now, + A>.Ignored, + A.Ignored)) + .Invokes(async (Instant n, Func callback, CancellationToken ct) => + { + await callback(@event); + }); + } + + private void VerifyRepositories(IRuleEventEntity @event, string dump, RuleResult result, RuleJobResult jobResult, TimeSpan elapsed, Instant? nextCall) + { + A.CallTo(() => ruleEventRepository.MarkSendingAsync(@event.Id)) + .MustHaveHappened(); + + A.CallTo(() => ruleEventRepository.MarkSentAsync(@event.Id, dump, result, jobResult, elapsed, nextCall)) + .MustHaveHappened(); + } + + private IRuleEventEntity CreateEvent(int numCalls, string actionName, RuleJobData actionData) + { + var @event = A.Fake(); + + var job = new RuleJob + { + RuleId = Guid.NewGuid(), + ActionData = actionData, + ActionName = actionName, + Created = now + }; + + A.CallTo(() => @event.Id).Returns(Guid.NewGuid()); + A.CallTo(() => @event.Job).Returns(job); + A.CallTo(() => @event.Created).Returns(now); + A.CallTo(() => @event.NumCalls).Returns(numCalls); + + return @event; + } + } +}