public async Task AddJobLog_Called_ReturnsJobLog() { string jobId = "5678"; IJobsApiClient jobsApiClient = Substitute.For <IJobsApiClient>(); JobManagementResiliencePolicies policies = new JobManagementResiliencePolicies { JobsApiClient = Policy.NoOpAsync() }; IMessengerService messengerService = Substitute.For <IMessengerService>(); ILogger logger = Substitute.For <ILogger>(); JobLog jobLog = new JobLog { JobId = jobId }; ApiResponse <JobLog> jobLogApiResponse = new ApiResponse <JobLog>(HttpStatusCode.OK, jobLog); JobLogUpdateModel jobLogUpdateModel = new JobLogUpdateModel(); jobsApiClient .AddJobLog(jobId, jobLogUpdateModel) .Returns(jobLogApiResponse); JobManagement jobManagement = new JobManagement(jobsApiClient, logger, policies, messengerService); //Act JobLog result = await jobManagement.AddJobLog(jobId, jobLogUpdateModel); Assert.AreEqual(result, jobLog); await jobsApiClient .Received(1) .AddJobLog(jobId, jobLogUpdateModel); }
public async Task UpdateJobStatusInternal_ApiResponseFailure_Logs(ApiResponse <JobLog> jobLogApiResponse) { //Arrange IJobsApiClient jobsApiClient = Substitute.For <IJobsApiClient>(); JobManagementResiliencePolicies policies = new JobManagementResiliencePolicies { JobsApiClient = Policy.NoOpAsync() }; IMessengerService messengerService = Substitute.For <IMessengerService>(); ILogger logger = Substitute.For <ILogger>(); jobsApiClient .AddJobLog(Arg.Any <string>(), Arg.Any <JobLogUpdateModel>()) .Returns(jobLogApiResponse); JobLogUpdateModel updateModel = new JobLogUpdateModel(); JobManagement jobManagement = new JobManagement(jobsApiClient, logger, policies, messengerService); string jobId = "3456"; //Act await jobManagement.UpdateJobStatus(jobId, updateModel); //Assert await jobsApiClient .Received(1) .AddJobLog(jobId, updateModel); logger .Received(1) .Write(LogEventLevel.Error, $"Failed to add a job log for job id '{jobId}'"); }
public async Task RefreshPublishResults_GivenSingleSpecificationId_ShouldReturnNoContentResult() { // Arrange const string specificationId1 = "123"; HttpRequest httpRequest = Substitute.For <HttpRequest>(); ISpecificationsRepository mockSpecificationsRepository = Substitute.For <ISpecificationsRepository>(); mockSpecificationsRepository.GetSpecificationById(Arg.Any <string>()).Returns(new Specification()); SpecificationCalculationExecutionStatus expectedSpecificationStatusCall1 = new SpecificationCalculationExecutionStatus(specificationId1, 0, CalculationProgressStatus.NotStarted); ICacheProvider mockCacheProvider = Substitute.For <ICacheProvider>(); IJobsApiClient jobsApiClient = CreateJobsApiClient(); SpecificationsService specificationsService = CreateService(specificationsRepository: mockSpecificationsRepository, cacheProvider: mockCacheProvider, jobsApiClient: jobsApiClient); httpRequest.Query.Returns(new QueryCollection(new Dictionary <string, StringValues>() { { "specificationId", new StringValues($"{specificationId1}") } })); // Act IActionResult actionResultReturned = await specificationsService.RefreshPublishedResults(httpRequest); // Assert actionResultReturned.Should().BeOfType <NoContentResult>(); await mockCacheProvider.Received().SetAsync($"{CalculationProgressPrependKey}{specificationId1}", expectedSpecificationStatusCall1, TimeSpan.FromHours(6), false); await jobsApiClient.Received(1).CreateJob(Arg.Is <JobCreateModel>(j => j.JobDefinitionId == JobConstants.DefinitionNames.PublishProviderResultsJob && j.SpecificationId == specificationId1 && j.Trigger.Message == $"Refreshing published provider results for specification")); }
public async Task UpdateJobStatus_ApiResponseSuccess_Runs() { //Arrange IJobsApiClient jobsApiClient = Substitute.For <IJobsApiClient>(); JobManagementResiliencePolicies policies = new JobManagementResiliencePolicies { JobsApiClient = Policy.NoOpAsync() }; IMessengerService messengerService = Substitute.For <IMessengerService>(); ILogger logger = Substitute.For <ILogger>(); ApiResponse <JobLog> jobLogApiResponse = new ApiResponse <JobLog>(HttpStatusCode.OK, new JobLog()); jobsApiClient .AddJobLog(Arg.Any <string>(), Arg.Any <JobLogUpdateModel>()) .Returns(jobLogApiResponse); JobLogUpdateModel updateModel = new JobLogUpdateModel(); JobManagement jobManagement = new JobManagement(jobsApiClient, logger, policies, messengerService); string jobId = "3456"; //Act await jobManagement.UpdateJobStatus(jobId, updateModel); //Assert await jobsApiClient .Received(1) .AddJobLog(jobId, updateModel); logger .Received(0) .Write(Arg.Any <LogEventLevel>(), Arg.Any <string>()); }
public async Task SelectSpecificationForFunding_GivenValidSpecification_ReturnsNoContentResult() { // Arrange IQueryCollection queryStringValues = new QueryCollection(new Dictionary <string, StringValues> { { "specificationId", new StringValues(SpecificationId) } }); HttpRequest request = Substitute.For <HttpRequest>(); request .Query .Returns(queryStringValues); Specification specification = CreateSpecification(); ILogger logger = CreateLogger(); ISpecificationsRepository specificationsRepository = CreateSpecificationsRepository(); specificationsRepository .GetSpecificationById(Arg.Is(SpecificationId)) .Returns(specification); specificationsRepository .UpdateSpecification(Arg.Is(specification)) .Returns(HttpStatusCode.OK); IJobsApiClient jobsApiClient = CreateJobsApiClient(); ICacheProvider cacheProvider = CreateCacheProvider(); SpecificationsService service = CreateService( logs: logger, specificationsRepository: specificationsRepository, jobsApiClient: jobsApiClient, cacheProvider: cacheProvider); // Act IActionResult result = await service.SelectSpecificationForFunding(request); // Assert result .Should() .BeOfType <NoContentResult>(); await jobsApiClient .Received(1) .CreateJob(Arg.Is <JobCreateModel>(j => j.JobDefinitionId == JobConstants.DefinitionNames.PublishProviderResultsJob && j.SpecificationId == SpecificationId && j.Trigger.Message == $"Selecting specification for funding")); await cacheProvider .Received(1) .RemoveAsync <SpecificationSummary>($"{CacheKeys.SpecificationSummaryById}{specification.Id}"); await cacheProvider .Received(1) .RemoveAsync <SpecificationCurrentVersion>($"{CacheKeys.SpecificationCurrentVersionById}{specification.Id}"); }
public async Task RegenerateProviderSourceDatasets_GivenSpecificationId_ThenCallJobServiceToProcess() { // Arrange IQueryCollection queryStringValues = new QueryCollection(new Dictionary <string, StringValues> { { "specificationId", new StringValues(SpecificationId) }, }); HttpRequest request = Substitute.For <HttpRequest>(); request.Query.Returns(queryStringValues); IDatasetRepository datasetRepository = CreateDatasetsRepository(); datasetRepository .GetDefinitionSpecificationRelationshipsByQuery(Arg.Any <Expression <Func <DefinitionSpecificationRelationship, bool> > >()) .Returns(new List <DefinitionSpecificationRelationship> { new DefinitionSpecificationRelationship { DatasetVersion = new DatasetRelationshipVersion { Id = "DSRV1", Version = 1 }, Specification = new Common.Models.Reference { Id = SpecificationId, Name = "SpecAbc" } } }); datasetRepository .GetDatasetsByQuery(Arg.Any <Expression <Func <Dataset, bool> > >()) .Returns(new List <Dataset> { new Dataset { Id = "DS1" } }); IJobsApiClient jobsApiClient = CreateJobsApiClient(); DatasetService service = CreateDatasetService(datasetRepository: datasetRepository, jobsApiClient: jobsApiClient); // Act await service.RegenerateProviderSourceDatasets(request); // Assert await jobsApiClient .Received(1) .CreateJob(Arg.Is <JobCreateModel>(j => j.JobDefinitionId == "MapDatasetJob" && j.Properties.ContainsKey("session-id") && j.Properties["session-id"] == SpecificationId)); }
public async Task QueueJobs_Called_ReturnsJobs() { string specificationId = "1234"; string jobId = "3456"; IJobsApiClient jobsApiClient = Substitute.For <IJobsApiClient>(); JobManagementResiliencePolicies policies = new JobManagementResiliencePolicies { JobsApiClient = Policy.NoOpAsync() }; IMessengerService messengerService = Substitute.For <IMessengerService>(); ILogger logger = Substitute.For <ILogger>(); IEnumerable <Job> jobApiResponse = new List <Job> { new Job { Id = jobId } }; IEnumerable <JobCreateModel> jobCreateModel = new List <JobCreateModel> { new JobCreateModel { SpecificationId = specificationId } }; jobsApiClient .CreateJobs(jobCreateModel) .Returns(jobApiResponse); JobManagement jobManagement = new JobManagement(jobsApiClient, logger, policies, messengerService); //Act await jobManagement.QueueJobs(jobCreateModel); await jobsApiClient .Received(1) .CreateJobs(jobCreateModel); }
public async Task GetNonCompletedJobsWithinTimeFrame_Called_ReturnsJobSummaries() { string jobId = "5678"; DateTimeOffset from = DateTimeOffset.UtcNow.AddDays(-2); DateTimeOffset to = DateTimeOffset.UtcNow.AddDays(-1); IJobsApiClient jobsApiClient = Substitute.For <IJobsApiClient>(); JobManagementResiliencePolicies policies = new JobManagementResiliencePolicies { JobsApiClient = Policy.NoOpAsync() }; IMessengerService messengerService = Substitute.For <IMessengerService>(); ILogger logger = Substitute.For <ILogger>(); JobSummary jobSummary = new JobSummary { JobId = jobId }; IEnumerable <JobSummary> jobSummaries = new List <JobSummary> { jobSummary }; ApiResponse <IEnumerable <JobSummary> > jobSummariesApiResponse = new ApiResponse <IEnumerable <JobSummary> >(HttpStatusCode.OK, jobSummaries); jobsApiClient .GetNonCompletedJobsWithinTimeFrame(from, to) .Returns(jobSummariesApiResponse); JobManagement jobManagement = new JobManagement(jobsApiClient, logger, policies, messengerService); //Act IEnumerable <JobSummary> result = await jobManagement.GetNonCompletedJobsWithinTimeFrame(from, to); Assert.AreEqual(result, jobSummaries); await jobsApiClient .Received(1) .GetNonCompletedJobsWithinTimeFrame(from, to); }
public async Task GetLatestJobForSpecification_Called_ReturnsJobSummary() { string specificationId = "1234"; string jobType = "3456"; string jobId = "5678"; IJobsApiClient jobsApiClient = Substitute.For <IJobsApiClient>(); JobManagementResiliencePolicies policies = new JobManagementResiliencePolicies { JobsApiClient = Policy.NoOpAsync() }; IMessengerService messengerService = Substitute.For <IMessengerService>(); ILogger logger = Substitute.For <ILogger>(); string[] jobTypes = new string[] { jobType }; IDictionary <string, JobSummary> jobSummary = new Dictionary <string, JobSummary> { { string.Empty, new JobSummary { JobId = jobId } } }; ApiResponse <IDictionary <string, JobSummary> > jobSummaryApiResponse = new ApiResponse <IDictionary <string, JobSummary> >(HttpStatusCode.OK, jobSummary); jobsApiClient .GetLatestJobsForSpecification(specificationId, jobTypes) .Returns(jobSummaryApiResponse); JobManagement jobManagement = new JobManagement(jobsApiClient, logger, policies, messengerService); //Act IDictionary <string, JobSummary> result = await jobManagement.GetLatestJobsForSpecification(specificationId, jobTypes); Assert.AreEqual(result, jobSummary); await jobsApiClient .Received(1) .GetLatestJobsForSpecification(specificationId, jobTypes); }
public async Task RetrieveJobAndCheckCanBeProcessed_ApiReturnsIncomplete_ReturnsCorrectly() { //Arrange IJobsApiClient jobsApiClient = Substitute.For <IJobsApiClient>(); JobManagementResiliencePolicies policies = new JobManagementResiliencePolicies { JobsApiClient = Policy.NoOpAsync() }; IMessengerService messengerService = Substitute.For <IMessengerService>(); ILogger logger = Substitute.For <ILogger>(); JobViewModel jvm = new JobViewModel { CompletionStatus = null }; ApiResponse <JobViewModel> jobApiResponse = new ApiResponse <JobViewModel>(HttpStatusCode.OK, jvm); jobsApiClient .GetJobById(Arg.Any <string>()) .Returns(jobApiResponse); JobManagement jobManagement = new JobManagement(jobsApiClient, logger, policies, messengerService); string jobId = "3456"; //Act JobViewModel viewModel = await jobManagement.RetrieveJobAndCheckCanBeProcessed(jobId); //Assert await jobsApiClient .Received(1) .GetJobById(jobId); viewModel .Should() .Be(jvm); }
public async Task RetrieveJobAndCheckCanBeProcessed_FailsWithJobAlreadyCompleted_LogsAndErrors(ApiResponse <JobViewModel> jobApiResponse, string jobId, string errorMessage, LogEventLevel logEventLevel) { //Arrange IJobsApiClient jobsApiClient = Substitute.For <IJobsApiClient>(); IMessengerService messengerService = Substitute.For <IMessengerService>(); JobManagementResiliencePolicies policies = new JobManagementResiliencePolicies { JobsApiClient = Policy.NoOpAsync() }; ILogger logger = Substitute.For <ILogger>(); jobsApiClient .GetJobById(Arg.Any <string>()) .Returns(jobApiResponse); JobManagement jobManagement = new JobManagement(jobsApiClient, logger, policies, messengerService); Func <Task> test = async() => await jobManagement.RetrieveJobAndCheckCanBeProcessed(jobId); test .Should().Throw <JobAlreadyCompletedException>() .Which .Message .Should().Be(errorMessage); await jobsApiClient .Received(1) .GetJobById(jobId); logger .Received(1) .Write(logEventLevel, errorMessage); }
public async Task UpdateCalculationsForSpecification_GivenModelHasChangedPolicyNameAndSourceCodeContainsCalculationAggregate_SavesChangesEnsuresGenerateAggregationsJobCreated() { // Arrange const string specificationId = "spec-id"; Models.Specs.SpecificationVersionComparisonModel specificationVersionComparison = new Models.Specs.SpecificationVersionComparisonModel() { Id = specificationId, Current = new Models.Specs.SpecificationVersion { FundingPeriod = new Reference { Id = "fp1" }, Name = "any-name", Policies = new[] { new Models.Specs.Policy { Id = "pol-id", Name = "policy2" } } }, Previous = new Models.Specs.SpecificationVersion { FundingPeriod = new Reference { Id = "fp1" }, Policies = new[] { new Models.Specs.Policy { Id = "pol-id", Name = "policy1" } } } }; string json = JsonConvert.SerializeObject(specificationVersionComparison); Message message = new Message(Encoding.UTF8.GetBytes(json)); message.UserProperties.Add("user-id", UserId); message.UserProperties.Add("user-name", Username); ILogger logger = CreateLogger(); IEnumerable <Calculation> calcs = new[] { new Calculation { SpecificationId = "spec-id", Name = "any name", Id = "any-id", CalculationSpecification = new Reference("any name", "any-id"), FundingPeriod = new Reference("18/19", "2018/2019"), CalculationType = CalculationType.Number, FundingStream = new Reference("fp1", "fs1-111"), Current = new CalculationVersion { Author = new Reference(UserId, Username), Date = DateTimeOffset.Now, PublishStatus = PublishStatus.Draft, SourceCode = "return Min(calc1)", Version = 1 }, Policies = new List <Reference> { new Reference { Id = "pol-id", Name = "policy1" } } } }; BuildProject buildProject = new BuildProject { Id = "build-project-1", SpecificationId = specificationId }; ICalculationsRepository calculationsRepository = CreateCalculationsRepository(); calculationsRepository .GetCalculationsBySpecificationId(Arg.Is(specificationId)) .Returns(calcs); IBuildProjectsService buildProjectsService = CreateBuildProjectsService(); buildProjectsService .GetBuildProjectForSpecificationId(Arg.Is(specificationId)) .Returns(buildProject); ISearchRepository <CalculationIndex> searchRepository = CreateSearchRepository(); IJobsApiClient jobsApiClient = CreateJobsApiClient(); jobsApiClient .CreateJob(Arg.Any <JobCreateModel>()) .Returns(new Job { Id = "job-id-1", JobDefinitionId = JobConstants.DefinitionNames.CreateInstructGenerateAggregationsAllocationJob }); CalculationService service = CreateCalculationService( calculationsRepository, logger, buildProjectsService: buildProjectsService, searchRepository: searchRepository, jobsApiClient: jobsApiClient); // Act await service.UpdateCalculationsForSpecification(message); // Assert await jobsApiClient .Received(1) .CreateJob(Arg.Is <JobCreateModel>( m => m.InvokerUserDisplayName == Username && m.InvokerUserId == UserId && m.JobDefinitionId == JobConstants.DefinitionNames.CreateInstructGenerateAggregationsAllocationJob && m.Properties["specification-id"] == specificationId && m.Trigger.EntityId == specificationId && m.Trigger.EntityType == nameof(Models.Specs.Specification) && m.Trigger.Message == $"Updating calculations for specification: '{specificationId}'" )); logger .Received(1) .Information(Arg.Is($"New job of type '{JobConstants.DefinitionNames.CreateInstructGenerateAggregationsAllocationJob}' created with id: 'job-id-1'")); }
public async Task UpdateCalculationsForSpecification_GivenModelHasChangedPolicyNameButCreatingJobReturnsNull_LogsError() { // Arrange const string specificationId = "spec-id"; Models.Specs.SpecificationVersionComparisonModel specificationVersionComparison = new Models.Specs.SpecificationVersionComparisonModel() { Id = specificationId, Current = new Models.Specs.SpecificationVersion { FundingPeriod = new Reference { Id = "fp1" }, Name = "any-name", Policies = new[] { new Models.Specs.Policy { Id = "pol-id", Name = "policy2" } } }, Previous = new Models.Specs.SpecificationVersion { FundingPeriod = new Reference { Id = "fp1" }, Policies = new[] { new Models.Specs.Policy { Id = "pol-id", Name = "policy1" } } } }; string json = JsonConvert.SerializeObject(specificationVersionComparison); Message message = new Message(Encoding.UTF8.GetBytes(json)); message.UserProperties.Add("user-id", UserId); message.UserProperties.Add("user-name", Username); ILogger logger = CreateLogger(); IEnumerable <Calculation> calcs = new[] { new Calculation { SpecificationId = "spec-id", Name = "any name", Id = "any-id", CalculationSpecification = new Reference("any name", "any-id"), FundingPeriod = new Reference("18/19", "2018/2019"), CalculationType = CalculationType.Number, FundingStream = new Reference("fp1", "fs1-111"), Current = new CalculationVersion { Author = new Reference(UserId, Username), Date = DateTimeOffset.Now, PublishStatus = PublishStatus.Draft, SourceCode = "source code", Version = 1 }, Policies = new List <Reference> { new Reference { Id = "pol-id", Name = "policy1" } } } }; BuildProject buildProject = new BuildProject { Id = "build-project-1", SpecificationId = specificationId }; ICalculationsRepository calculationsRepository = CreateCalculationsRepository(); calculationsRepository .GetCalculationsBySpecificationId(Arg.Is(specificationId)) .Returns(calcs); IBuildProjectsService buildProjectsService = CreateBuildProjectsService(); buildProjectsService .GetBuildProjectForSpecificationId(Arg.Is(specificationId)) .Returns(buildProject); ISearchRepository <CalculationIndex> searchRepository = CreateSearchRepository(); IJobsApiClient jobsApiClient = CreateJobsApiClient(); jobsApiClient .CreateJob(Arg.Any <JobCreateModel>()) .Returns((Job)null); CalculationService service = CreateCalculationService( calculationsRepository, logger, buildProjectsService: buildProjectsService, searchRepository: searchRepository, jobsApiClient: jobsApiClient); // Act Func <Task> test = async() => await service.UpdateCalculationsForSpecification(message); // Assert test .Should() .ThrowExactly <RetriableException>() .Which .Message .Should() .Be($"Failed to create job: '{JobConstants.DefinitionNames.CreateInstructAllocationJob} for specification id '{specificationId}'"); await jobsApiClient .Received(1) .CreateJob(Arg.Is <JobCreateModel>( m => m.InvokerUserDisplayName == Username && m.InvokerUserId == UserId && m.JobDefinitionId == JobConstants.DefinitionNames.CreateInstructAllocationJob && m.Properties["specification-id"] == specificationId && m.Trigger.EntityId == specificationId && m.Trigger.EntityType == nameof(Models.Specs.Specification) && m.Trigger.Message == $"Updating calculations for specification: '{specificationId}'" )); logger .Received(1) .Error(Arg.Is($"Failed to create job: '{JobConstants.DefinitionNames.CreateInstructAllocationJob} for specification id '{specificationId}'")); }
public async Task UpdatePublishedAllocationLineResultsStatus_GivenBatchingButNoUpdateModel_ReturnsBadRequest() { //arrange IQueryCollection queryStringValues = new QueryCollection(new Dictionary <string, StringValues> { { "specificationId", new StringValues(specificationId) }, }); IEnumerable <UpdatePublishedAllocationLineResultStatusProviderModel> Providers = new[] { new UpdatePublishedAllocationLineResultStatusProviderModel { ProviderId = "1111", AllocationLineIds = new[] { "AAAAA" } }, new UpdatePublishedAllocationLineResultStatusProviderModel { ProviderId = "1111-1", AllocationLineIds = new[] { "AAAAA" } }, new UpdatePublishedAllocationLineResultStatusProviderModel { ProviderId = "1111-2", AllocationLineIds = new[] { "AAAAA" } } }; UpdatePublishedAllocationLineResultStatusModel model = new UpdatePublishedAllocationLineResultStatusModel { Providers = Providers, Status = AllocationLineStatus.Approved }; string json = JsonConvert.SerializeObject(model); byte[] byteArray = Encoding.UTF8.GetBytes(json); MemoryStream stream = new MemoryStream(byteArray); HttpRequest request = Substitute.For <HttpRequest>(); request .Query .Returns(queryStringValues); request .Body .Returns(stream); ILogger logger = CreateLogger(); Job newJob = new Job { Id = "new-job-id" }; IEnumerable <PublishedProviderResult> publishedProviderResults = CreatePublishedProviderResultsWithDifferentProviders(); foreach (PublishedProviderResult publishedProviderResult in publishedProviderResults) { publishedProviderResult.FundingStreamResult.AllocationLineResult.Current.ProfilingPeriods = new[] { new ProfilingPeriod() }; } IJobsApiClient jobsApiClient = CreateJobsApiClient(); jobsApiClient .CreateJob(Arg.Any <JobCreateModel>()) .Returns(newJob); ICacheProvider cacheProvider = CreateCacheProvider(); PublishedResultsService resultsService = CreateResultsService(logger, jobsApiClient: jobsApiClient, cacheProvider: cacheProvider); //Act IActionResult actionResult = await resultsService.UpdatePublishedAllocationLineResultsStatus(request); //Arrange actionResult .Should() .BeAssignableTo <OkResult>(); logger .Received(1) .Information(Arg.Is($"New job: '{JobConstants.DefinitionNames.CreateInstructAllocationLineResultStatusUpdateJob}' created with id: '{newJob.Id}'")); await cacheProvider .Received(1) .SetAsync <UpdatePublishedAllocationLineResultStatusModel>(Arg.Any <string>(), Arg.Any <UpdatePublishedAllocationLineResultStatusModel>()); await jobsApiClient .Received(1) .CreateJob(Arg.Is <JobCreateModel>(m => !string.IsNullOrWhiteSpace(m.InvokerUserDisplayName) && !string.IsNullOrWhiteSpace(m.InvokerUserId) && m.JobDefinitionId == JobConstants.DefinitionNames.CreateInstructAllocationLineResultStatusUpdateJob && m.SpecificationId == specificationId && m.Properties["specification-id"] == specificationId && !string.IsNullOrWhiteSpace(m.Properties["cache-key"]) && m.Trigger.EntityId == specificationId && m.Trigger.EntityType == "Specification" && m.Trigger.Message == $"Updating allocation line results status" )); }
public async Task CreateAllocationLineResultStatusUpdateJobs_GivenUpateModelWith10ProvidersAndDefaultMaxPartitionSize_CreatesOneChildJob() { //Arrange const string cacheKey = "cache-key"; Message message = new Message(); message.UserProperties.Add("jobId", jobId); ILogger logger = CreateLogger(); JobViewModel job = new JobViewModel { Id = jobId, SpecificationId = specificationId, InvokerUserDisplayName = "user-name", InvokerUserId = "user-id", CorrelationId = "coorelation-id", Properties = new Dictionary <string, string> { { "cache-key", cacheKey } }, JobDefinitionId = JobConstants.DefinitionNames.CreateInstructAllocationLineResultStatusUpdateJob }; UpdatePublishedAllocationLineResultStatusModel updateModel = new UpdatePublishedAllocationLineResultStatusModel { Status = AllocationLineStatus.Approved, Providers = CreateProviderAllocationLineResults() }; ApiResponse <JobViewModel> apiResponse = new ApiResponse <JobViewModel>(HttpStatusCode.OK, job); IJobsApiClient jobsApiClient = CreateJobsApiClient(); jobsApiClient .GetJobById(jobId) .Returns(apiResponse); IEnumerable <Job> newJobs = new[] { new Job() }; jobsApiClient .CreateJobs(Arg.Any <IEnumerable <JobCreateModel> >()) .Returns(newJobs); ICacheProvider cacheProvider = CreateCacheProvider(); cacheProvider .GetAsync <UpdatePublishedAllocationLineResultStatusModel>(Arg.Is(cacheKey)) .Returns(updateModel); PublishedResultsService publishedResultsService = CreateResultsService(logger, jobsApiClient: jobsApiClient, cacheProvider: cacheProvider); //Act await publishedResultsService.CreateAllocationLineResultStatusUpdateJobs(message); //Assert await jobsApiClient .Received(1) .CreateJobs(Arg.Is <IEnumerable <JobCreateModel> >( m => m.First().Trigger.EntityId == jobId && m.First().Trigger.EntityType == "Job" && m.First().Trigger.Message == $"Triggered by parent job" && m.First().SpecificationId == specificationId && m.First().ParentJobId == jobId && m.First().InvokerUserId == job.InvokerUserId && m.First().InvokerUserDisplayName == job.InvokerUserDisplayName && m.First().CorrelationId == job.CorrelationId && !string.IsNullOrWhiteSpace(m.First().MessageBody))); await cacheProvider .Received(1) .RemoveAsync <UpdatePublishedAllocationLineResultStatusModel>(Arg.Is(cacheKey)); }
public async Task CreateAllocationLineResultStatusUpdateJobs_GivenUpateModelWith10ProvidersAndMaxPartitionSizeOf2_CreatesFiveChildJobs() { //Arrange const string cacheKey = "cache-key"; Message message = new Message(); message.UserProperties.Add("jobId", jobId); ILogger logger = CreateLogger(); JobViewModel job = new JobViewModel { Id = jobId, SpecificationId = specificationId, InvokerUserDisplayName = "user-name", InvokerUserId = "user-id", CorrelationId = "coorelation-id", Properties = new Dictionary <string, string> { { "cache-key", cacheKey } }, JobDefinitionId = JobConstants.DefinitionNames.CreateInstructAllocationLineResultStatusUpdateJob }; UpdatePublishedAllocationLineResultStatusModel updateModel = new UpdatePublishedAllocationLineResultStatusModel { Status = AllocationLineStatus.Approved, Providers = CreateProviderAllocationLineResults() }; ApiResponse <JobViewModel> apiResponse = new ApiResponse <JobViewModel>(HttpStatusCode.OK, job); IJobsApiClient jobsApiClient = CreateJobsApiClient(); jobsApiClient .GetJobById(jobId) .Returns(apiResponse); IEnumerable <Job> newJobs = new[] { new Job(), new Job(), new Job(), new Job(), new Job(), }; jobsApiClient .CreateJobs(Arg.Any <IEnumerable <JobCreateModel> >()) .Returns(newJobs); ICacheProvider cacheProvider = CreateCacheProvider(); cacheProvider .GetAsync <UpdatePublishedAllocationLineResultStatusModel>(Arg.Is(cacheKey)) .Returns(updateModel); IPublishedProviderResultsSettings settings = CreatePublishedProviderResultsSettings(); settings .UpdateAllocationLineResultStatusBatchCount .Returns(2); PublishedResultsService publishedResultsService = CreateResultsService(logger, jobsApiClient: jobsApiClient, cacheProvider: cacheProvider, publishedProviderResultsSettings: settings); //Act await publishedResultsService.CreateAllocationLineResultStatusUpdateJobs(message); //Assert await jobsApiClient .Received(1) .CreateJobs(Arg.Is <IEnumerable <JobCreateModel> >(m => m.Count() == 5)); await cacheProvider .Received(1) .RemoveAsync <UpdatePublishedAllocationLineResultStatusModel>(Arg.Is(cacheKey)); }
public async Task WaitForJobsToCompleteWithAllJobsSucceeded_ReturnsTrue(bool useServiceBus) { IJobsApiClient jobsApiClient = Substitute.For <IJobsApiClient>(); JobManagementResiliencePolicies policies = new JobManagementResiliencePolicies { JobsApiClient = Policy.NoOpAsync() }; IMessengerService messengerService = null; if (useServiceBus) { messengerService = Substitute.For <IMessengerService, IServiceBusService>(); } else { messengerService = Substitute.For <IMessengerService, IQueueService>(); } ILogger logger = Substitute.For <ILogger>(); JobManagement jobManagement = new JobManagement(jobsApiClient, logger, policies, messengerService); var jobId = "3456"; IEnumerable <Job> jobApiResponse = new List <Job> { new Job { Id = jobId } }; jobsApiClient .GetLatestJobsForSpecification("specificationId", Arg.Is <string[]>(_ => _.Single() == "PopulateScopedProviders")) .Returns(new ApiResponse <IDictionary <string, JobSummary> >(HttpStatusCode.OK, new Dictionary <string, JobSummary> { { string.Empty, new JobSummary { RunningStatus = RunningStatus.Completed, CompletionStatus = CompletionStatus.Succeeded, JobId = jobId } } })); messengerService .ReceiveMessage("topic/Subscriptions/correlationId", Arg.Any <Predicate <JobSummary> >(), TimeSpan.FromMilliseconds(600000)) .Returns(new JobSummary { CompletionStatus = CompletionStatus.Succeeded }); //Act bool jobsComplete = await jobManagement.QueueJobAndWait(async() => await Task.Run(() => { return(true); }), "PopulateScopedProviders", "specificationId", "correlationId", "topic"); //Assert if (useServiceBus) { await((IServiceBusService)messengerService) .Received(1) .CreateSubscription("topic", "correlationId", Arg.Is <TimeSpan>(_ => _.Days == 1)); await messengerService .Received(1) .ReceiveMessage("topic/Subscriptions/correlationId", Arg.Any <Predicate <JobSummary> >(), TimeSpan.FromMilliseconds(600000)); } else { await jobsApiClient .Received(2) .GetLatestJobsForSpecification("specificationId", Arg.Is <string[]>(_ => _.Single() == "PopulateScopedProviders")); } jobsComplete .Should() .BeTrue(); }