public async Task ExecuteRuleAsyncShouldGetContextFromFactory([Frozen] IGetsRuleContext contextFactory, [RuleContext] RuleContext context, [ExecutableModel] ExecutableRule rule, SingleRuleExecutor sut, [RuleResult] RuleResult expectedResult) { RuleContext capturedContext = null; Mock.Get(rule.RuleLogic) .Setup(x => x.GetResultAsync(It.IsAny <object>(), It.IsAny <object>(), It.IsAny <RuleContext>(), It.IsAny <CancellationToken>())) .Callback((object v1, object v2, RuleContext context, CancellationToken t) => capturedContext = context) .Returns(() => Task.FromResult(expectedResult)); Mock.Get(contextFactory).Setup(x => x.GetRuleContext(rule)).Returns(context); await sut.ExecuteRuleAsync(rule); Assert.That(capturedContext, Is.SameAs(context)); }
public async Task ExecuteRuleAsyncShouldReturnResultCreatedFromRuleLogic([Frozen] IGetsRuleContext contextFactory, [RuleContext] RuleContext context, [ExecutableModel] ExecutableRule rule, SingleRuleExecutor sut, [RuleResult] RuleResult expectedResult) { Mock.Get(rule.RuleLogic) .Setup(x => x.GetResultAsync(It.IsAny <object>(), It.IsAny <object>(), It.IsAny <RuleContext>(), It.IsAny <CancellationToken>())) .Returns(() => Task.FromResult(expectedResult)); Mock.Get(contextFactory).Setup(x => x.GetRuleContext(rule)).Returns(context); var result = await sut.ExecuteRuleAsync(rule); Assert.Multiple(() => { Assert.That(result.Data, Is.SameAs(expectedResult.Data), nameof(ValidationRuleResult.Data)); Assert.That(result.Outcome, Is.EqualTo(expectedResult.Outcome), nameof(ValidationRuleResult.Outcome)); }); }
public async Task ExecuteAllRulesAsyncShouldReturnAResultForEachRuleWithFailedDependencies([Frozen] IExecutesAllRules wrapped, [Frozen] IGetsRuleContext contextFactory, ResultsForRulesWithFailedDependenciesExecutionDecorator sut, IRuleExecutionContext executionContext, [ExecutableModel] ExecutableRule rule1, [ExecutableModel] ExecutableRule rule2, [RuleContext] RuleContext context) { Mock.Get(wrapped) .Setup(x => x.ExecuteAllRulesAsync(executionContext, default)) .Returns(Task.FromResult <IReadOnlyCollection <ValidationRuleResult> >(Array.Empty <ValidationRuleResult>())); Mock.Get(executionContext) .Setup(x => x.GetRulesWhoseDependenciesHaveFailed()) .Returns(new[] { rule1, rule2 }); Mock.Get(contextFactory) .Setup(x => x.GetRuleContext(It.IsAny <ExecutableRule>())) .Returns(context); rule1.Result = new RuleResult(RuleOutcome.DependencyFailed); rule2.Result = new RuleResult(RuleOutcome.DependencyFailed); var results = await sut.ExecuteAllRulesAsync(executionContext); Assert.Multiple(() => { Assert.That(results, Has.Count.EqualTo(2), "Count of results"); Assert.That(results.Select(x => x.ValidationLogic).ToList(), Is.EqualTo(new[] { rule1.RuleLogic, rule2.RuleLogic }), "Correct rules used, identified by their logic instances."); }); }
/// <summary> /// Initialises a new instance of <see cref="SingleRuleExecutor"/>. /// </summary> /// <param name="contextFactory">A factory for rule contexts.</param> /// <exception cref="System.ArgumentNullException">If <paramref name="contextFactory"/> is <see langword="null" />.</exception> public SingleRuleExecutor(IGetsRuleContext contextFactory) { this.contextFactory = contextFactory ?? throw new System.ArgumentNullException(nameof(contextFactory)); }
public async Task ExecuteRuleAsyncShouldReturnErrorResultWithTimeoutIfRuleTakesTooLongToExecute([Frozen] IGetsRuleContext contextFactory, [RuleContext] RuleContext context, [ExecutableModel] ExecutableRule rule, SingleRuleExecutor sut) { var timeout = TimeSpan.FromMilliseconds(100); Mock.Get(rule.RuleLogic).Setup(x => x.GetTimeout()).Returns(timeout); Mock.Get(rule.RuleLogic) .Setup(x => x.GetResultAsync(It.IsAny <object>(), It.IsAny <object>(), It.IsAny <RuleContext>(), It.IsAny <CancellationToken>())) .Returns(() => Task.Run(async() => { await Task.Delay(200); return(CommonResults.Pass()); })); Mock.Get(contextFactory).Setup(x => x.GetRuleContext(rule)).Returns(context); var result = await sut.ExecuteRuleAsync(rule); Assert.Multiple(() => { Assert.That(result.Outcome, Is.EqualTo(RuleOutcome.Errored), "Result has error outcome"); Assert.That(result.Data, Does.ContainKey(RuleResult.RuleTimeoutDataKey), "Result has a rule-timeout data key"); if (result.Data.TryGetValue(RuleResult.RuleTimeoutDataKey, out var timeoutData)) { Assert.That(timeoutData, Is.EqualTo(timeout), "Timeout data is equal"); } }); }
public async Task ExecuteRuleAsyncShouldExecuteRuleLogicWithCorrectValidatedInstances([Frozen] IGetsRuleContext contextFactory, [RuleContext] RuleContext context, [ExecutableModel] ExecutableRule rule, SingleRuleExecutor sut, ValidatedValue validatedValue, ValidatedValue parentValue, [RuleResult] RuleResult expectedResult) { rule.ValidatedValue = validatedValue; validatedValue.ParentValue = parentValue; Mock.Get(contextFactory).Setup(x => x.GetRuleContext(rule)).Returns(context); Mock.Get(rule.RuleLogic) .Setup(x => x.GetResultAsync(It.IsAny <object>(), It.IsAny <object>(), It.IsAny <RuleContext>(), It.IsAny <CancellationToken>())) .Returns(() => Task.FromResult(expectedResult)); await sut.ExecuteRuleAsync(rule); Mock.Get(rule.RuleLogic) .Verify(x => x.GetResultAsync(validatedValue.GetActualValue(), parentValue.GetActualValue(), It.IsAny <RuleContext>(), It.IsAny <CancellationToken>()), Times.Once); }
public void ExecuteRuleAsyncShouldThrowIfCancellationIsRequestedWithoutExecutingRuleLogic([Frozen] IGetsRuleContext contextFactory, [RuleContext] RuleContext context, [ExecutableModel] ExecutableRule rule, SingleRuleExecutor sut, [AlreadyCancelled] CancellationToken token) { Mock.Get(contextFactory).Setup(x => x.GetRuleContext(rule)).Returns(context); Assert.That(async() => await sut.ExecuteRuleAsync(rule, token), Throws.InstanceOf <OperationCanceledException>()); Mock.Get(rule.RuleLogic) .Verify(x => x.GetResultAsync(It.IsAny <object>(), It.IsAny <object>(), It.IsAny <RuleContext>(), It.IsAny <CancellationToken>()), Times.Never); }
public void ExecuteRuleAsyncShouldReturnPassResultWithTimeoutIfRuleCompletesInATimelyManner([Frozen] IGetsRuleContext contextFactory, [RuleContext] RuleContext context, [ExecutableModel] ExecutableRule rule, SingleRuleExecutor sut) { var timeout = TimeSpan.FromMilliseconds(300); Mock.Get(rule.RuleLogic).Setup(x => x.GetTimeout()).Returns(timeout); Mock.Get(rule.RuleLogic) .Setup(x => x.GetResultAsync(It.IsAny <object>(), It.IsAny <object>(), It.IsAny <RuleContext>(), It.IsAny <CancellationToken>())) .Returns(() => Task.Run(async() => { await Task.Delay(50); return(CommonResults.Pass()); })); Mock.Get(contextFactory).Setup(x => x.GetRuleContext(rule)).Returns(context); Assert.That(() => sut.ExecuteRuleAsync(rule), Is.PassingValidationResult); }
public void GetRuleExecutorAsyncShouldReturnANonNullRuleExecutorIfParallelisationIsEnabled([Frozen] IServiceProvider resolver, RuleExecutorFactory sut, ResolvedValidationOptions options, IGetsRuleExecutionContext dependencyTrackerFactory, IGetsSingleRuleExecutor ruleExecutorFactory, IGetsRuleContext contextFactory) { Mock.Get(resolver) .Setup(x => x.GetService(typeof(IGetsRuleExecutionContext))) .Returns(dependencyTrackerFactory); Mock.Get(resolver) .Setup(x => x.GetService(typeof(IGetsSingleRuleExecutor))) .Returns(ruleExecutorFactory); Mock.Get(resolver) .Setup(x => x.GetService(typeof(IGetsRuleContext))) .Returns(contextFactory); options.EnableRuleParallelization = true; Assert.That(async() => await sut.GetRuleExecutorAsync(options), Is.Not.Null); }
/// <summary> /// Initialises a new instance of <see cref="ResultsForRulesWithFailedDependenciesExecutionDecorator"/>. /// </summary> /// <param name="wrapped">The wrapped executor instance.</param> /// <param name="contextFactory">A rule context factory.</param> /// <exception cref="System.ArgumentNullException">If any parameter is <see langword="null" />.</exception> public ResultsForRulesWithFailedDependenciesExecutionDecorator(IExecutesAllRules wrapped, IGetsRuleContext contextFactory) { this.wrapped = wrapped ?? throw new System.ArgumentNullException(nameof(wrapped)); this.contextFactory = contextFactory ?? throw new System.ArgumentNullException(nameof(contextFactory)); }