Exemple #1
0
 private static CalculationService CreateCalculationService(
     ICalculationsRepository calculationsRepository = null,
     ILogger logger = null,
     ISearchRepository <CalculationIndex> searchRepository = null,
     IValidator <Calculation> calcValidator           = null,
     IBuildProjectsService buildProjectsService       = null,
     ISpecificationRepository specificationRepository = null,
     ICacheProvider cacheProvider = null,
     ICalcsResiliencePolicies resiliencePolicies = null,
     IVersionRepository <CalculationVersion> calculationVersionRepository = null,
     IJobsApiClient jobsApiClient                     = null,
     ISourceCodeService sourceCodeService             = null,
     IFeatureToggle featureToggle                     = null,
     IBuildProjectsRepository buildProjectsRepository = null,
     ICalculationCodeReferenceUpdate calculationCodeReferenceUpdate = null)
 {
     return(new CalculationService
                (calculationsRepository ?? CreateCalculationsRepository(),
                logger ?? CreateLogger(),
                searchRepository ?? CreateSearchRepository(),
                calcValidator ?? CreateCalculationValidator(),
                buildProjectsService ?? CreateBuildProjectsService(),
                specificationRepository ?? CreateSpecificationRepository(),
                cacheProvider ?? CreateCacheProvider(),
                resiliencePolicies ?? CalcsResilienceTestHelper.GenerateTestPolicies(),
                calculationVersionRepository ?? CreateCalculationVersionRepository(),
                jobsApiClient ?? CreateJobsApiClient(),
                sourceCodeService ?? CreateSourceCodeService(),
                featureToggle ?? CreateFeatureToggle(),
                buildProjectsRepository ?? CreateBuildProjectsRepository(),
                calculationCodeReferenceUpdate ?? CreateCalculationCodeReferenceUpdate()));
 }
Exemple #2
0
        public SpecificationCalculationAnalysis(ICalcsResiliencePolicies policies,
                                                ISpecificationsApiClient specifications,
                                                ICalculationsRepository calculations,
                                                ICalculationAnalysis calculationAnalysis,
                                                IBuildProjectsService buildProjectsService,
                                                IDatasetReferenceService datasetReferenceService,
                                                IMapper mapper)
        {
            Guard.ArgumentNotNull(policies?.CalculationsRepository, nameof(policies.CalculationsRepository));
            Guard.ArgumentNotNull(policies?.SpecificationsApiClient, nameof(policies.SpecificationsApiClient));
            Guard.ArgumentNotNull(specifications, nameof(specifications));
            Guard.ArgumentNotNull(calculations, nameof(calculations));
            Guard.ArgumentNotNull(calculationAnalysis, nameof(calculationAnalysis));
            Guard.ArgumentNotNull(buildProjectsService, nameof(buildProjectsService));
            Guard.ArgumentNotNull(datasetReferenceService, nameof(datasetReferenceService));
            Guard.ArgumentNotNull(mapper, nameof(mapper));

            _specificationsResilience = policies.SpecificationsApiClient;
            _calculationsResilience   = policies.CalculationsRepository;
            _specifications           = specifications;
            _calculations             = calculations;
            _calculationAnalysis      = calculationAnalysis;
            _buildProjectsService     = buildProjectsService;
            _datasetReferenceService  = datasetReferenceService;
            _mapper = mapper;
        }
Exemple #3
0
        public CalculationsController(
            ICalculationService calcsService,
            ICalculationsSearchService calcsSearchService,
            IPreviewService previewService,
            IBuildProjectsService buildProjectsService,
            IQueueReIndexSpecificationCalculationRelationships calculationRelationships,
            ICalculationFundingLineQueryService calculationFundingLineQueryService,
            ICodeContextCache codeContextCache)
        {
            Guard.ArgumentNotNull(calcsService, nameof(calcsService));
            Guard.ArgumentNotNull(calcsSearchService, nameof(calcsSearchService));
            Guard.ArgumentNotNull(previewService, nameof(previewService));
            Guard.ArgumentNotNull(buildProjectsService, nameof(buildProjectsService));
            Guard.ArgumentNotNull(calculationRelationships, nameof(calculationRelationships));
            Guard.ArgumentNotNull(calculationFundingLineQueryService, nameof(calculationFundingLineQueryService));
            Guard.ArgumentNotNull(codeContextCache, nameof(codeContextCache));

            _calcsService                       = calcsService;
            _previewService                     = previewService;
            _calcsSearchService                 = calcsSearchService;
            _buildProjectsService               = buildProjectsService;
            _calculationRelationships           = calculationRelationships;
            _calculationFundingLineQueryService = calculationFundingLineQueryService;
            _codeContextCache                   = codeContextCache;
        }
Exemple #4
0
 public OnCalcsInstructAllocationResults(
     ILogger logger,
     IBuildProjectsService buildProjectsService,
     IMessengerService messengerService,
     IUserProfileProvider userProfileProvider, bool useAzureStorage = false)
     : base(logger, messengerService, FunctionName, QueueName, useAzureStorage, userProfileProvider, buildProjectsService)
 {
 }
 public CalcsAddRelationshipToBuildProject(
     ILogger logger,
     IBuildProjectsService buildProjectsService,
     IMessengerService messengerService,
     IUserProfileProvider userProfileProvider, bool useAzureStorage = false)
     : base(logger, messengerService, FunctionName, QueueName, useAzureStorage, userProfileProvider, buildProjectsService)
 {
 }
 public CalculationsController(
     ICalculationService calcsService,
     ICalculationsSearchService calcsSearchService,
     IPreviewService previewService,
     IBuildProjectsService buildProjectsService)
 {
     _calcsService         = calcsService;
     _previewService       = previewService;
     _calcsSearchService   = calcsSearchService;
     _buildProjectsService = buildProjectsService;
 }
        public OnCalcsInstructAllocationResults(
            ILogger logger,
            ICorrelationIdProvider correlationIdProvider,
            IBuildProjectsService buildProjectsService)
        {
            Guard.ArgumentNotNull(logger, nameof(logger));
            Guard.ArgumentNotNull(correlationIdProvider, nameof(correlationIdProvider));
            Guard.ArgumentNotNull(buildProjectsService, nameof(buildProjectsService));

            _logger = logger;
            _correlationIdProvider = correlationIdProvider;
            _buildProjectsService  = buildProjectsService;
        }
Exemple #8
0
        public static void SetupTests(TestContext tc)
        {
            SetupTests("calcs");

            _logger = CreateLogger();

            _applyTemplateCalculationsService = CreateApplyTemplateCalculationsService();
            _buildProjectsService             = CreateBuildProjectsService();
            _jobService         = CreateJobService();
            _calculationService = CreateCalculationService();
            _datasetDefinitionFieldChangesProcessor = CreateDatasetDefinitionFieldChangesProcessor();
            _userProfileProvider = CreateUserProfileProvider();
        }
Exemple #9
0
        public CalcsAddRelationshipToBuildProject(
            ILogger logger,
            ICorrelationIdProvider correlationIdProvider,
            IBuildProjectsService buildProjectsService)
        {
            Guard.ArgumentNotNull(logger, nameof(logger));
            Guard.ArgumentNotNull(correlationIdProvider, nameof(correlationIdProvider));
            Guard.ArgumentNotNull(buildProjectsService, nameof(buildProjectsService));

            _logger = logger;
            _correlationIdProvider = correlationIdProvider;
            _buildProjectsService  = buildProjectsService;
        }
Exemple #10
0
        public CodeContextBuilder(IBuildProjectsService buildProjects,
                                  ICalculationsRepository calculations,
                                  ISourceCodeService compiler,
                                  ICalcsResiliencePolicies resiliencePolicies,
                                  ILogger logger)
        {
            Guard.ArgumentNotNull(logger, nameof(logger));
            Guard.ArgumentNotNull(buildProjects, nameof(buildProjects));
            Guard.ArgumentNotNull(calculations, nameof(calculations));
            Guard.ArgumentNotNull(compiler, nameof(compiler));
            Guard.ArgumentNotNull(resiliencePolicies?.CalculationsRepository, nameof(resiliencePolicies.CalculationsRepository));

            _buildProjects          = buildProjects;
            _calculations           = calculations;
            _calculationsResilience = resiliencePolicies.CalculationsRepository;
            _compiler = compiler;
            _logger   = logger;
        }
Exemple #11
0
 public PreviewService(
     ILogger logger,
     IBuildProjectsService buildProjectsService,
     IValidator <PreviewRequest> previewRequestValidator,
     ICalculationsRepository calculationsRepository,
     IDatasetRepository datasetRepository,
     IFeatureToggle featureToggle,
     ICacheProvider cacheProvider,
     ISourceCodeService sourceCodeService,
     ITokenChecker tokenChecker)
 {
     _logger = logger;
     _buildProjectsService    = buildProjectsService;
     _previewRequestValidator = previewRequestValidator;
     _calculationsRepository  = calculationsRepository;
     _datasetRepository       = datasetRepository;
     _featureToggle           = featureToggle;
     _cacheProvider           = cacheProvider;
     _sourceCodeService       = sourceCodeService;
     _tokenChecker            = tokenChecker;
 }
Exemple #12
0
        public PreviewService(
            ILogger logger,
            IBuildProjectsService buildProjectsService,
            IValidator <PreviewRequest> previewRequestValidator,
            ICalculationsRepository calculationsRepository,
            IDatasetsApiClient datasetsApiClient,
            ICacheProvider cacheProvider,
            ISourceCodeService sourceCodeService,
            ICalcsResiliencePolicies resiliencePolicies,
            IMapper mapper,
            ICalcEngineApiClient calcEngineApiClient)
        {
            Guard.ArgumentNotNull(logger, nameof(logger));
            Guard.ArgumentNotNull(buildProjectsService, nameof(buildProjectsService));
            Guard.ArgumentNotNull(previewRequestValidator, nameof(previewRequestValidator));
            Guard.ArgumentNotNull(calculationsRepository, nameof(calculationsRepository));
            Guard.ArgumentNotNull(datasetsApiClient, nameof(datasetsApiClient));
            Guard.ArgumentNotNull(cacheProvider, nameof(cacheProvider));
            Guard.ArgumentNotNull(sourceCodeService, nameof(sourceCodeService));
            Guard.ArgumentNotNull(resiliencePolicies, nameof(resiliencePolicies));
            Guard.ArgumentNotNull(mapper, nameof(mapper));
            Guard.ArgumentNotNull(resiliencePolicies.DatasetsApiClient, nameof(resiliencePolicies.DatasetsApiClient));
            Guard.ArgumentNotNull(resiliencePolicies.CalcEngineApiClient, nameof(resiliencePolicies.CalcEngineApiClient));
            Guard.ArgumentNotNull(calcEngineApiClient, nameof(calcEngineApiClient));

            _logger = logger;
            _buildProjectsService    = buildProjectsService;
            _previewRequestValidator = previewRequestValidator;
            _calculationsRepository  = calculationsRepository;
            _datasetsApiClient       = datasetsApiClient;
            _cacheProvider           = cacheProvider;
            _sourceCodeService       = sourceCodeService;
            _datasetsApiClientPolicy = resiliencePolicies.DatasetsApiClient;
            _mapper = mapper;
            _calcEngineApiClient       = calcEngineApiClient;
            _calcEngineApiClientPolicy = resiliencePolicies.CalcEngineApiClient;

            _typeIdentifierGenerator = new VisualBasicTypeIdentifierGenerator();
        }
        private static CalculationService CreateCalculationService(
            ICalculationsRepository calculationsRepository = null,
            ILogger logger = null,
            ISearchRepository <CalculationIndex> searchRepository = null,
            IBuildProjectsService buildProjectsService            = null,
            IPoliciesApiClient policiesApiClient        = null,
            ICacheProvider cacheProvider                = null,
            ICalcsResiliencePolicies resiliencePolicies = null,
            IVersionRepository <CalculationVersion> calculationVersionRepository = null,
            IJobManagement jobManagement                     = null,
            ISourceCodeService sourceCodeService             = null,
            IFeatureToggle featureToggle                     = null,
            IBuildProjectsRepository buildProjectsRepository = null,
            ICalculationCodeReferenceUpdate calculationCodeReferenceUpdate      = null,
            IValidator <CalculationCreateModel> calculationCreateModelValidator = null,
            IValidator <CalculationEditModel> calculationEditModelValidator     = null,
            ISpecificationsApiClient specificationsApiClient = null,
            IGraphRepository graphRepository = null,
            ICalculationsFeatureFlag calculationsFeatureFlag = null,
            ICodeContextCache codeContextCache         = null,
            ISourceFileRepository sourceFileRepository = null,
            IResultsApiClient resultsApiClient         = null,
            IDatasetsApiClient datasetsApiClient       = null,
            IApproveAllCalculationsJobAction approveAllCalculationsJobAction = null)
        {
            CalculationNameInUseCheck calculationNameInUseCheck = new CalculationNameInUseCheck(calculationsRepository ?? CreateCalculationsRepository(),
                                                                                                specificationsApiClient ?? CreateSpecificationsApiClient(),
                                                                                                resiliencePolicies ?? CalcsResilienceTestHelper.GenerateTestPolicies());

            InstructionAllocationJobCreation instructionAllocationJobCreation =
                new InstructionAllocationJobCreation(
                    calculationsRepository ?? CreateCalculationsRepository(),
                    resiliencePolicies ?? CalcsResilienceTestHelper.GenerateTestPolicies(),
                    logger ?? CreateLogger(),
                    calculationsFeatureFlag ?? CreateCalculationsFeatureFlag(),
                    jobManagement ?? CreateJobManagement());

            return(new CalculationService
                   (
                       calculationsRepository ?? CreateCalculationsRepository(),
                       logger ?? CreateLogger(),
                       searchRepository ?? CreateSearchRepository(),
                       buildProjectsService ?? CreateBuildProjectsService(),
                       policiesApiClient ?? CreatePoliciesApiClient(),
                       cacheProvider ?? CreateCacheProvider(),
                       resiliencePolicies ?? CalcsResilienceTestHelper.GenerateTestPolicies(),
                       calculationVersionRepository ?? CreateCalculationVersionRepository(),
                       sourceCodeService ?? CreateSourceCodeService(),
                       featureToggle ?? CreateFeatureToggle(),
                       buildProjectsRepository ?? CreateBuildProjectsRepository(),
                       calculationCodeReferenceUpdate ?? CreateCalculationCodeReferenceUpdate(),
                       calculationCreateModelValidator ?? CreateCalculationCreateModelValidator(),
                       calculationEditModelValidator ?? CreateCalculationEditModelValidator(),
                       specificationsApiClient ?? CreateSpecificationsApiClient(),
                       calculationNameInUseCheck,
                       instructionAllocationJobCreation,
                       new CreateCalculationService(calculationNameInUseCheck,
                                                    calculationsRepository ?? CreateCalculationsRepository(),
                                                    calculationVersionRepository ?? CreateCalculationVersionRepository(),
                                                    resiliencePolicies ?? CalcsResilienceTestHelper.GenerateTestPolicies(),
                                                    calculationCreateModelValidator ?? CreateCalculationCreateModelValidator(),
                                                    cacheProvider ?? CreateCacheProvider(),
                                                    searchRepository ?? CreateSearchRepository(),
                                                    logger ?? CreateLogger(),
                                                    instructionAllocationJobCreation),
                       graphRepository ?? CreateGraphRepository(),
                       CreateJobManagement(),
                       codeContextCache ?? Substitute.For <ICodeContextCache>(),
                       resultsApiClient ?? Substitute.For <IResultsApiClient>(),
                       datasetsApiClient ?? Substitute.For <IDatasetsApiClient>(),
                       approveAllCalculationsJobAction ?? CreateApproveAllCalculationsJobAction()));
        }
        public async Task EditCalculationStatus_GivenNewStatusOfUpdated_UpdatesSearchReturnsOK()
        {
            //Arrange
            EditStatusModel CalculationEditStatusModel = new EditStatusModel
            {
                PublishStatus = PublishStatus.Updated
            };

            string json = JsonConvert.SerializeObject(CalculationEditStatusModel);

            byte[]       byteArray = Encoding.UTF8.GetBytes(json);
            MemoryStream stream    = new MemoryStream(byteArray);

            HttpContext context = Substitute.For <HttpContext>();

            HttpRequest request = Substitute.For <HttpRequest>();

            IQueryCollection queryStringValues = new QueryCollection(new Dictionary <string, StringValues>
            {
                { "calculationId", new StringValues(CalculationId) },
            });

            request
            .Query
            .Returns(queryStringValues);
            request
            .Body
            .Returns(stream);

            request
            .HttpContext
            .Returns(context);

            ILogger logger = CreateLogger();

            Calculation calculation = CreateCalculation();

            calculation.Current.PublishStatus = PublishStatus.Approved;

            CalculationVersion calculationVersion = calculation.Current.Clone() as CalculationVersion;

            calculationVersion.PublishStatus = PublishStatus.Updated;

            ICalculationsRepository CalculationsRepository = CreateCalculationsRepository();

            CalculationsRepository
            .GetCalculationById(Arg.Is(CalculationId))
            .Returns(calculation);

            CalculationsRepository
            .UpdateCalculation(Arg.Any <Calculation>())
            .Returns(HttpStatusCode.OK);


            ISearchRepository <CalculationIndex> searchRepository = CreateSearchRepository();

            Models.Specs.SpecificationSummary specificationSummary = new Models.Specs.SpecificationSummary();

            ISpecificationRepository specificationRepository = CreateSpecificationRepository();

            specificationRepository
            .GetSpecificationSummaryById(Arg.Is(calculation.SpecificationId))
            .Returns(specificationSummary);

            IVersionRepository <CalculationVersion> versionRepository = CreateCalculationVersionRepository();

            versionRepository
            .CreateVersion(Arg.Any <CalculationVersion>(), Arg.Any <CalculationVersion>())
            .Returns(calculationVersion);

            Build build = new Build
            {
                SourceFiles = new List <SourceFile> {
                    new SourceFile()
                }
            };

            BuildProject buildProject = new BuildProject();

            IBuildProjectsService buildProjectsService = CreateBuildProjectsService();

            buildProjectsService
            .GetBuildProjectForSpecificationId(Arg.Is(calculation.SpecificationId))
            .Returns(buildProject);

            ISourceCodeService sourceCodeService = CreateSourceCodeService();

            sourceCodeService
            .Compile(Arg.Any <BuildProject>(), Arg.Any <IEnumerable <Models.Calcs.Calculation> >(), Arg.Any <CompilerOptions>())
            .Returns(build);

            CalculationService service = CreateCalculationService(
                logger: logger, calculationsRepository: CalculationsRepository, searchRepository: searchRepository,
                specificationRepository: specificationRepository, calculationVersionRepository: versionRepository,
                sourceCodeService: sourceCodeService, buildProjectsService: buildProjectsService);

            //Act
            IActionResult result = await service.UpdateCalculationStatus(request);

            //Arrange
            result
            .Should()
            .BeOfType <OkObjectResult>()
            .Which
            .Value
            .Should()
            .BeOfType <PublishStatusResultModel>()
            .Which
            .PublishStatus
            .Should()
            .Be(PublishStatus.Updated);

            calculation
            .Current
            .PublishStatus
            .Should()
            .Be(PublishStatus.Updated);

            await
            searchRepository
            .Received(1)
            .Index(Arg.Is <IEnumerable <CalculationIndex> >(m => m.First().Status == "Updated"));
        }
        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 UpdateCalculationsForSpecification_GivenModelHasChangedFundingStreams_SetsTheAllocationLineAndFundingStreamToNull()
        {
            //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",
                    FundingStreams = new List <Reference> {
                        new Reference {
                            Id = "fs2"
                        }
                    }
                },
                Previous = new Models.Specs.SpecificationVersion
                {
                    FundingPeriod = new Reference {
                        Id = "fp1"
                    },
                    FundingStreams = new List <Reference> {
                        new Reference {
                            Id = "fs1"
                        }
                    }
                }
            };

            string json = JsonConvert.SerializeObject(specificationVersionComparison);

            Message message = new Message(Encoding.UTF8.GetBytes(json));

            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("fs1", "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>()
                }
            };

            BuildProject buildProject = new BuildProject();

            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"
            });

            CalculationService service = CreateCalculationService(calculationsRepository, logger, buildProjectsService: buildProjectsService, searchRepository: searchRepository, jobsApiClient: jobsApiClient);

            //Act
            await service.UpdateCalculationsForSpecification(message);

            //Assert
            calcs
            .First()
            .FundingStream
            .Should()
            .BeNull();

            calcs
            .First()
            .AllocationLine
            .Should()
            .BeNull();

            await searchRepository
            .Received(1)
            .Index(Arg.Is <IEnumerable <CalculationIndex> >(c =>
                                                            c.First().Id == calcs.First().Id&&
                                                            c.First().FundingStreamId == "" &&
                                                            c.First().FundingStreamName == "No funding stream set"));
        }
        public async Task UpdateCalculationsForSpecification_GivenModelHasChangedPolicyNameAndGraphEnabled_SavesChangesEnsuresJobCreated()
        {
            // Arrange
            const string specificationId = "spec-id";

            SpecificationVersionComparisonModel specificationVersionComparison = new SpecificationVersionComparisonModel()
            {
                Id      = specificationId,
                Current = new SpecificationVersion
                {
                    FundingPeriod = new Reference {
                        Id = "fp1"
                    },
                    Name = "any-name"
                },
                Previous = new SpecificationVersion
                {
                    FundingPeriod = new Reference {
                        Id = "fp1"
                    }
                }
            };

            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",
                    Id      = "any-id",
                    Current = new CalculationVersion
                    {
                        Author          = new Reference(UserId, Username),
                        Date            = DateTimeOffset.Now,
                        PublishStatus   = PublishStatus.Draft,
                        SourceCode      = "source code",
                        Version         = 1,
                        Name            = "any name",
                        CalculationType = CalculationType.Template,
                    }
                }
            };

            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();

            IJobManagement jobManagement = CreateJobManagement();

            jobManagement
            .QueueJob(Arg.Is <JobCreateModel>(_ => _.JobDefinitionId == JobConstants.DefinitionNames.GenerateGraphAndInstructAllocationJob))
            .Returns(new Job {
                Id = "job-id-1", JobDefinitionId = JobConstants.DefinitionNames.GenerateGraphAndInstructAllocationJob
            });

            jobManagement
            .QueueJob(Arg.Is <JobCreateModel>(_ => _.JobDefinitionId == JobConstants.DefinitionNames.ReIndexSpecificationCalculationRelationshipsJob))
            .Returns(new Job {
                Id = "job-id-2", JobDefinitionId = JobConstants.DefinitionNames.ReIndexSpecificationCalculationRelationshipsJob
            });

            IMapper mapper = Substitute.For <IMapper>();

            ICalculationsFeatureFlag calculationsFeatureFlag = CreateCalculationsFeatureFlag(true);

            CalculationService service = CreateCalculationService(
                calculationsRepository,
                logger,
                buildProjectsService: buildProjectsService,
                searchRepository: searchRepository,
                jobManagement: jobManagement,
                calculationsFeatureFlag: calculationsFeatureFlag);

            // Act
            await service.Run(message);

            // Assert
            await
            jobManagement
            .Received(1)
            .QueueJob(Arg.Is <JobCreateModel>(
                          m =>
                          m.InvokerUserDisplayName == Username &&
                          m.InvokerUserId == UserId &&
                          m.JobDefinitionId == JobConstants.DefinitionNames.ReIndexSpecificationCalculationRelationshipsJob &&
                          m.Properties["specification-id"] == specificationId &&
                          m.Trigger.EntityId == specificationId &&
                          m.Trigger.EntityType == "Specification" &&
                          m.Trigger.Message == $"Updating calculations for specification: '{specificationId}'"
                          ));

            await
            jobManagement
            .Received(1)
            .QueueJob(Arg.Is <JobCreateModel>(
                          m =>
                          m.InvokerUserDisplayName == Username &&
                          m.InvokerUserId == UserId &&
                          m.JobDefinitionId == JobConstants.DefinitionNames.GenerateGraphAndInstructAllocationJob &&
                          m.Properties["specification-id"] == specificationId &&
                          m.Trigger.EntityId == specificationId &&
                          m.Trigger.EntityType == "Specification" &&
                          m.Trigger.Message == $"Updating calculations for specification: '{specificationId}'"
                          ));

            logger
            .Received(1)
            .Information(Arg.Is($"New job of type '{JobConstants.DefinitionNames.GenerateGraphAndInstructAllocationJob}' created with id: 'job-id-1'"));

            logger
            .Received(1)
            .Information(Arg.Is($"New job of type '{JobConstants.DefinitionNames.ReIndexSpecificationCalculationRelationshipsJob}' created with id: 'job-id-2'"));
        }
Exemple #19
0
        public async Task UpdateCalculationCodeOnCalculationSpecificationChange_WhenCalculationsFoundReferencingCalculationToBeUpdated_ThenSourceCodeUpdated()
        {
            // Arrange
            ICalculationsRepository  calculationsRepository                = CreateCalculationsRepository();
            ISpecificationRepository specificationRepository               = CreateSpecificationRepository();
            IVersionRepository <CalculationVersion> versionRepository      = CreateCalculationVersionRepository();
            IBuildProjectsService           buildProjectsService           = CreateBuildProjectsService();
            ICalculationCodeReferenceUpdate calculationCodeReferenceUpdate = FakeCalculationCodeReferenceUpdate();

            CalculationService service = CreateCalculationService(calculationsRepository: calculationsRepository,
                                                                  specificationRepository: specificationRepository,
                                                                  calculationVersionRepository: versionRepository,
                                                                  buildProjectsService: buildProjectsService,
                                                                  calculationCodeReferenceUpdate: calculationCodeReferenceUpdate);

            const string specificationId    = "specId";
            const string calculationId      = "updatedCalc";
            const string originalCodeUpdate = "Return OriginalName()";
            const string originalCodeIgnore = "Return 10";

            Models.Specs.CalculationVersionComparisonModel comparison = new Models.Specs.CalculationVersionComparisonModel()
            {
                CalculationId = calculationId,
                Current       = new Models.Specs.Calculation
                {
                    Id              = "calcSpec1",
                    Name            = "Calculation To Update",
                    CalculationType = Models.Specs.CalculationType.Funding,
                },
                Previous = new Models.Specs.Calculation
                {
                    Id              = "calcSpec1",
                    Name            = "Original Name",
                    CalculationType = Models.Specs.CalculationType.Funding,
                },
                SpecificationId = specificationId,
            };

            Reference user = new Reference("userId", "User Name");

            List <Calculation> calculations = new List <Calculation>();
            Calculation        calc1        = new Calculation
            {
                Id                       = calculationId,
                Name                     = "Calculation to Update",
                SpecificationId          = specificationId,
                FundingPeriod            = new Reference("fp1", "Funding Period"),
                CalculationSpecification = new Reference("calcSpec1", "Calculation to Update"),
                CalculationType          = CalculationType.Funding,
                Description              = "Calculation Description",
                BuildProjectId           = "bpC1",
                Policies                 = new List <Reference>(),
                Current                  = new CalculationVersion
                {
                    SourceCode    = originalCodeIgnore,
                    DecimalPlaces = 6,
                }
            };

            calculations.Add(calc1);

            Calculation calc2 = new Calculation
            {
                Id                       = "referenceCalc",
                Name                     = "Calling Calculation To Update",
                SpecificationId          = specificationId,
                FundingPeriod            = new Reference("fp1", "Funding Period"),
                CalculationSpecification = new Reference("calcSpec1", "Calculation to Update"),
                CalculationType          = CalculationType.Funding,
                Description              = "Calculation Description",
                BuildProjectId           = "bpC1",
                Policies                 = new List <Reference>(),
                Current                  = new CalculationVersion
                {
                    SourceCode    = originalCodeUpdate,
                    DecimalPlaces = 6,
                }
            };

            calculations.Add(calc2);

            calculationsRepository
            .GetCalculationsBySpecificationId(Arg.Is(specificationId))
            .Returns(calculations);

            calculationsRepository
            .UpdateCalculation(Arg.Any <Calculation>())
            .Returns(HttpStatusCode.OK);

            calculationsRepository
            .GetCalculationById(Arg.Is(calculations[0].Id))
            .Returns(calculations[0]);

            Models.Specs.SpecificationSummary specification = new Models.Specs.SpecificationSummary()
            {
                Id   = specificationId,
                Name = "Specification Name",
            };

            specificationRepository
            .GetSpecificationSummaryById(Arg.Is(specificationId))
            .Returns(specification);

            CalculationVersion calculationVersion = new CalculationVersion
            {
                SourceCode = "Return CalculationToUpdate()",
                Version    = 2
            };

            versionRepository
            .CreateVersion(Arg.Any <CalculationVersion>(), Arg.Any <CalculationVersion>())
            .Returns(calculationVersion);

            // Act
            IEnumerable <Calculation> updatedCalculations = await service.UpdateCalculationCodeOnCalculationSpecificationChange(comparison, user);

            // Assert
            updatedCalculations
            .Should()
            .HaveCount(1);

            Calculation calculation = updatedCalculations.Single();

            calculation.Current.SourceCode
            .Should()
            .Be("Return CalculationToUpdate()");


            calculation.Current.Version
            .Should()
            .Be(2);

            calculation.Id
            .Should()
            .Be("referenceCalc");

            await buildProjectsService
            .DidNotReceive()
            .GetBuildProjectForSpecificationId(Arg.Any <string>());

            calculationCodeReferenceUpdate
            .Received(calculations.Count)
            .ReplaceSourceCodeReferences(Arg.Any <string>(),
                                         VisualBasicTypeGenerator.GenerateIdentifier(comparison.Previous.Name),
                                         VisualBasicTypeGenerator.GenerateIdentifier(comparison.Current.Name));

            calculationCodeReferenceUpdate
            .Received(1)
            .ReplaceSourceCodeReferences(originalCodeIgnore, Arg.Any <string>(), Arg.Any <string>());

            calculationCodeReferenceUpdate
            .Received(1)
            .ReplaceSourceCodeReferences(originalCodeUpdate, Arg.Any <string>(), Arg.Any <string>());
        }
        public async Task EditCalculationStatus_GivenNewStatusOfUpdated_UpdatesSearchReturnsOK()
        {
            //Arrange
            EditStatusModel CalculationEditStatusModel = new EditStatusModel
            {
                PublishStatus = PublishStatus.Updated
            };

            ILogger logger = CreateLogger();

            Calculation calculation = CreateCalculation();

            calculation.Current.PublishStatus = PublishStatus.Approved;

            CalculationVersion calculationVersion = calculation.Current.Clone() as CalculationVersion;

            calculationVersion.PublishStatus = PublishStatus.Updated;

            ICalculationsRepository CalculationsRepository = CreateCalculationsRepository();

            CalculationsRepository
            .GetCalculationById(Arg.Is(CalculationId))
            .Returns(calculation);

            CalculationsRepository
            .UpdateCalculation(Arg.Any <Calculation>())
            .Returns(HttpStatusCode.OK);


            ISearchRepository <CalculationIndex> searchRepository = CreateSearchRepository();

            SpecModel.SpecificationSummary specificationSummary = new SpecModel.SpecificationSummary()
            {
                Id             = calculation.SpecificationId,
                Name           = "spec name",
                FundingStreams = new[]
                {
                    new Reference(calculation.FundingStreamId, "funding stream name")
                }
            };

            ISpecificationsApiClient specificationsApiClient = CreateSpecificationsApiClient();

            specificationsApiClient
            .GetSpecificationSummaryById(Arg.Is(calculation.SpecificationId))
            .Returns(new Common.ApiClient.Models.ApiResponse <SpecModel.SpecificationSummary>(HttpStatusCode.OK, specificationSummary));

            IVersionRepository <CalculationVersion> versionRepository = CreateCalculationVersionRepository();

            versionRepository
            .CreateVersion(Arg.Any <CalculationVersion>(), Arg.Any <CalculationVersion>())
            .Returns(calculationVersion);

            Build build = new Build
            {
                SourceFiles = new List <SourceFile> {
                    new SourceFile()
                }
            };

            BuildProject buildProject = new BuildProject();

            IBuildProjectsService buildProjectsService = CreateBuildProjectsService();

            buildProjectsService
            .GetBuildProjectForSpecificationId(Arg.Is(calculation.SpecificationId))
            .Returns(buildProject);

            ISourceCodeService sourceCodeService = CreateSourceCodeService();

            sourceCodeService
            .Compile(Arg.Any <BuildProject>(), Arg.Any <IEnumerable <Models.Calcs.Calculation> >(), Arg.Any <CompilerOptions>())
            .Returns(build);

            CalculationService service = CreateCalculationService(
                logger: logger, calculationsRepository: CalculationsRepository, searchRepository: searchRepository,
                specificationsApiClient: specificationsApiClient, calculationVersionRepository: versionRepository,
                sourceCodeService: sourceCodeService, buildProjectsService: buildProjectsService);

            //Act
            IActionResult result = await service.UpdateCalculationStatus(CalculationId, CalculationEditStatusModel);

            //Arrange
            result
            .Should()
            .BeOfType <OkObjectResult>()
            .Which
            .Value
            .Should()
            .BeOfType <PublishStatusResultModel>()
            .Which
            .PublishStatus
            .Should()
            .Be(PublishStatus.Updated);

            calculation
            .Current
            .PublishStatus
            .Should()
            .Be(PublishStatus.Updated);
        }
        public async Task ResetCalculationForFieldDefinitionChanges_GivenCalculationRequiresReset_UpdatesCalculationsAndDeletesAssembly()
        {
            //Arrange
            const string specificationId = "spec-id";

            IEnumerable <DatasetSpecificationRelationshipViewModel> relationships = new[]
            {
                new DatasetSpecificationRelationshipViewModel
                {
                    Name = "Test Name"
                }
            };

            IEnumerable <string> currentFieldDefinitionNames = new[]
            {
                "Test Field"
            };

            ILogger logger = CreateLogger();

            CalculationVersion calculationVersion = new CalculationVersion
            {
                SourceCode = "return Datasets.TestName.TestField",
                Date       = DateTimeOffset.Now
            };

            IEnumerable <Calculation> calculations = new[]
            {
                new Calculation
                {
                    Current                  = calculationVersion,
                    SpecificationId          = specificationId,
                    CalculationSpecification = new Reference("calc-spac-id", "calc spec name"),
                    FundingPeriod            = new Reference("fp1", "fp 1"),
                    FundingStream            = new Reference("fs1", "fs 1"),
                    Policies                 = new List <Reference> {
                        new Reference {
                            Id = "policy-1", Name = "policy 1"
                        }
                    }
                }
            };

            IEnumerable <Models.Specs.Calculation> calculationSpecifications = new[]
            {
                new Models.Specs.Calculation
                {
                    Id = "calc-spec-id"
                }
            };

            BuildProject buildProject = new BuildProject();

            Build build = new Build
            {
                SourceFiles = new List <SourceFile>()
            };

            Models.Specs.SpecificationSummary specificationSummary = new Models.Specs.SpecificationSummary();

            ICalculationsRepository calculationsRepository = CreateCalculationsRepository();

            calculationsRepository
            .GetCalculationsBySpecificationId(Arg.Is(specificationId))
            .Returns(calculations);
            calculationsRepository
            .UpdateCalculation(Arg.Any <Calculation>())
            .Returns(HttpStatusCode.OK);

            ISpecificationRepository specificationRepository = CreateSpecificationRepository();

            specificationRepository
            .GetCalculationSpecificationsForSpecification(Arg.Is(specificationId))
            .Returns(calculationSpecifications);

            specificationRepository
            .GetSpecificationSummaryById(Arg.Is(specificationId))
            .Returns(specificationSummary);

            IBuildProjectsService buildProjectsService = CreateBuildProjectsService();

            buildProjectsService
            .GetBuildProjectForSpecificationId(Arg.Is(specificationId))
            .Returns(buildProject);

            ISourceCodeService sourceCodeService = CreateSourceCodeService();

            sourceCodeService
            .Compile(Arg.Is(buildProject), Arg.Any <IEnumerable <Calculation> >(), Arg.Any <CompilerOptions>())
            .Returns(build);

            IVersionRepository <CalculationVersion> calculationVersionRepository = CreateCalculationVersionRepository();

            calculationVersionRepository
            .CreateVersion(Arg.Any <CalculationVersion>(), Arg.Any <CalculationVersion>())
            .Returns(calculationVersion);

            ICacheProvider cacheProvider = CreateCacheProvider();

            CalculationService calculationService = CreateCalculationService(
                logger: logger,
                calculationsRepository: calculationsRepository,
                specificationRepository: specificationRepository,
                buildProjectsService: buildProjectsService,
                sourceCodeService: sourceCodeService,
                calculationVersionRepository: calculationVersionRepository,
                cacheProvider: cacheProvider);

            //Act
            await calculationService.ResetCalculationForFieldDefinitionChanges(relationships, specificationId, currentFieldDefinitionNames);

            //Assert
            await
            sourceCodeService
            .Received(1)
            .DeleteAssembly(Arg.Is(specificationId));

            await
            cacheProvider
            .Received(1)
            .RemoveAsync <List <DatasetSchemaRelationshipModel> >(Arg.Is($"{CacheKeys.DatasetRelationshipFieldsForSpecification}{specificationId}"));
        }
Exemple #22
0
        public async Task UpdateCalculationCodeOnCalculationChange_WhenCalculationsFoundReferencingCalculationToBeUpdated_ThenSourceCodeUpdated()
        {
            // Arrange
            ICalculationsRepository  calculationsRepository           = CreateCalculationsRepository();
            ISpecificationsApiClient specificationsApiClient          = CreateSpecificationsApiClient();
            IVersionRepository <CalculationVersion> versionRepository = CreateCalculationVersionRepository();
            IBuildProjectsService buildProjectsService = CreateBuildProjectsService();
            ISourceCodeService    sourceCodeService    = CreateSourceCodeService();

            CalculationService service = CreateCalculationService(calculationsRepository: calculationsRepository,
                                                                  specificationsApiClient: specificationsApiClient,
                                                                  calculationVersionRepository: versionRepository,
                                                                  buildProjectsService: buildProjectsService,
                                                                  sourceCodeService: sourceCodeService);

            const string specificationId    = "specId";
            const string calculationId      = "updatedCalc";
            const string originalCodeUpdate = @"Dim test as OriginalNameOptions? 
                                                OriginalNameOptions.enumName 
                                                Return Calculations.OriginalName()";
            const string newCodeUpdated     = @"Dim test as CalculationToUpdateOptions? 
                                                CalculationToUpdateOptions.enumName 
                                                Return Calculations.CalculationToUpdate()";
            const string originalCodeIgnore = "Return 10";
            const string fundingStreamId    = "fundingstreamid";

            CalculationVersionComparisonModel comparison = new CalculationVersionComparisonModel()
            {
                CalculationId       = calculationId,
                CurrentName         = "Calculation To Update",
                PreviousName        = "Original Name",
                SpecificationId     = specificationId,
                CalculationDataType = CalculationDataType.Enum,
                Namespace           = "Calculations"
            };

            Reference user = new Reference("userId", "User Name");

            List <Calculation> calculations = new List <Calculation>
            {
                new Calculation
                {
                    Id = calculationId,
                    SpecificationId = specificationId,
                    FundingStreamId = fundingStreamId,
                    Current         = new CalculationVersion
                    {
                        SourceCode      = originalCodeIgnore,
                        Name            = "Calculation to Update",
                        CalculationType = CalculationType.Template,
                        Description     = "Calculation Description",
                        DataType        = CalculationDataType.Enum
                    }
                },
                new Calculation
                {
                    Id = "referenceCalc",
                    SpecificationId = specificationId,
                    FundingStreamId = fundingStreamId,
                    Current         = new CalculationVersion
                    {
                        SourceCode      = originalCodeUpdate,
                        Name            = "Calling Calculation To Update",
                        CalculationType = CalculationType.Template,
                        Description     = "Calculation Description"
                    }
                }
            };

            calculationsRepository
            .GetCalculationsBySpecificationId(Arg.Is(specificationId))
            .Returns(calculations);

            calculationsRepository
            .UpdateCalculation(Arg.Any <Calculation>())
            .Returns(HttpStatusCode.OK);

            calculationsRepository
            .GetCalculationById(Arg.Is(calculations[0].Id))
            .Returns(calculations[0]);

            SpecModel.SpecificationSummary specification = new SpecModel.SpecificationSummary()
            {
                Id             = specificationId,
                Name           = "Specification Name",
                FundingStreams = new [] { new Reference(fundingStreamId, "fundingStreamName"), }
            };

            specificationsApiClient
            .GetSpecificationSummaryById(Arg.Is(specificationId))
            .Returns(new Common.ApiClient.Models.ApiResponse <SpecModel.SpecificationSummary>(HttpStatusCode.OK, specification));

            CalculationVersion calculationVersion = new CalculationVersion
            {
                SourceCode = newCodeUpdated,
                Version    = 2
            };

            versionRepository
            .CreateVersion(Arg.Is <CalculationVersion>(_ => _.SourceCode == newCodeUpdated), Arg.Any <CalculationVersion>())
            .Returns(calculationVersion);

            buildProjectsService
            .GetBuildProjectForSpecificationId(specificationId)
            .Returns(new BuildProject());

            sourceCodeService
            .Compile(Arg.Any <BuildProject>(), Arg.Any <IEnumerable <Calculation> >(), Arg.Any <CompilerOptions>())
            .Returns(new Build());

            // Act
            IEnumerable <Calculation> updatedCalculations = await service.UpdateCalculationCodeOnCalculationChange(comparison, user);

            // Assert
            updatedCalculations
            .Should()
            .HaveCount(1);

            Calculation calculation = updatedCalculations.Single();

            calculation.Current.SourceCode
            .Should()
            .Be(newCodeUpdated);


            calculation.Current.Version
            .Should()
            .Be(2);

            calculation.Id
            .Should()
            .Be("referenceCalc");
        }