public void CreateCalculation_CreatingCalculationButAssociatedCalculationSpecificationNotFound_ThrowsException()
        {
            //Arrange
            Calculation calculation = CreateCalculation();

            IEnumerable <Calculation> calculations = new[]
            {
                calculation
            };
            string json = JsonConvert.SerializeObject(calculation);

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

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

            message.UserProperties.Add("user-id", UserId);
            message.UserProperties.Add("user-name", Username);

            ILogger logger = CreateLogger();

            ISearchRepository <CalculationIndex> searchRepository = CreateSearchRepository();

            Models.Specs.SpecificationSummary specificationSummary = new Models.Specs.SpecificationSummary()
            {
                Id   = calculation.SpecificationId,
                Name = "Test Spec Name",
            };

            ISpecificationRepository specificationRepository = CreateSpecificationRepository();

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

            specificationRepository
            .GetCalculationSpecificationsForSpecification(Arg.Is(calculation.SpecificationId))
            .Returns(calculationSpecifications);

            CalculationService service = CreateCalculationService(logger: logger, searchRepository: searchRepository, specificationRepository: specificationRepository);

            //Act
            Func <Task> test = async() => await service.CreateCalculation(message);

            //Assert
            test
            .Should().ThrowExactly <RetriableException>()
            .WithMessage($"A calculation specification was not found for calculation specification id '{calculation.CalculationSpecification.Id}'");
        }
        public async Task <IActionResult> ReIndex(HttpRequest request)
        {
            IEnumerable <DocumentEntity <TestScenario> > testScenarios = await _scenariosRepository.GetAllTestScenarios();

            List <ScenarioIndex> testScenarioIndexes = new List <ScenarioIndex>();

            Dictionary <string, Models.Specs.SpecificationSummary> specifications = new Dictionary <string, Models.Specs.SpecificationSummary>();

            foreach (DocumentEntity <TestScenario> entity in testScenarios)
            {
                TestScenario testScenario = entity.Content;

                Models.Specs.SpecificationSummary specificationSummary = null;
                if (!specifications.ContainsKey(testScenario.SpecificationId))
                {
                    specificationSummary = await _specificationsRepository.GetSpecificationSummaryById(testScenario.SpecificationId);

                    specifications.Add(testScenario.SpecificationId, specificationSummary);
                }
                else
                {
                    specificationSummary = specifications[testScenario.SpecificationId];
                }

                testScenarioIndexes.Add(new ScenarioIndex()
                {
                    Id                 = testScenario.Id,
                    Name               = testScenario.Name,
                    Description        = testScenario.Current.Description,
                    LastUpdatedDate    = entity.UpdatedAt,
                    FundingStreamIds   = testScenario.Current?.FundingStreamIds.ToArray(),
                    FundingStreamNames = specificationSummary.FundingStreams.Select(s => s.Name).ToArray(),
                    FundingPeriodId    = testScenario.Current?.FundingPeriodId,
                    FundingPeriodName  = specificationSummary.FundingPeriod.Name,
                    SpecificationId    = testScenario.SpecificationId,
                    SpecificationName  = specificationSummary.Name,
                    Status             = Enum.GetName(typeof(PublishStatus), testScenario.Current.PublishStatus),
                });
            }

            await _searchRepository.Index(testScenarioIndexes);

            return(new OkObjectResult($"Updated {testScenarioIndexes.Count} records"));
        }
        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 EditCalculationStatus_GivenCalculationIsApprovedButNewStatusIsDraft_UpdatesSearchReturnsOK()
        {
            //Arrange
            EditStatusModel CalculationEditStatusModel = new EditStatusModel
            {
                PublishStatus = PublishStatus.Draft
            };

            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;

            ICalculationsRepository CalculationsRepository = CreateCalculationsRepository();

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

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


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

            ISpecificationRepository specificationRepository = CreateSpecificationRepository();

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

            ISearchRepository <CalculationIndex> searchRepository = CreateSearchRepository();

            CalculationService service = CreateCalculationService(
                logger: logger, calculationsRepository: CalculationsRepository, searchRepository: searchRepository, specificationRepository: specificationRepository);

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

            //Arrange
            result
            .Should()
            .BeOfType <BadRequestObjectResult>()
            .Which
            .Value
            .Should()
            .Be("Publish status can't be changed to Draft from Updated or Approved");

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

            await
            searchRepository
            .Received(0)
            .Index(Arg.Any <IEnumerable <CalculationIndex> >());
        }
        public async Task EditCalculationStatus_GivenNewStatusButUpdatingDbReturnsBadRequest_ReturnsStatusCode400()
        {
            //Arrange
            EditStatusModel CalculationEditStatusModel = new EditStatusModel
            {
                PublishStatus = PublishStatus.Approved
            };

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

            ICalculationsRepository CalculationsRepository = CreateCalculationsRepository();

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

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

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

            ISpecificationRepository specificationRepository = CreateSpecificationRepository();

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

            CalculationService service = CreateCalculationService(
                logger: logger, calculationsRepository: CalculationsRepository, specificationRepository: specificationRepository);

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

            //Arrange
            result
            .Should()
            .BeAssignableTo <StatusCodeResult>()
            .Which
            .StatusCode
            .Should()
            .Be(400);
        }
        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}"));
        }
        public async Task CreateCalculation_GivenValidCalculation_ButFailedToSave_DoesNotUpdateSearch()
        {
            //Arrange
            Calculation calculation = CreateCalculation();

            IEnumerable <Calculation> calculations = new[]
            {
                calculation
            };

            IEnumerable <Models.Specs.Calculation> calculationSpecifications = new[]
            {
                new Models.Specs.Calculation
                {
                    Id = calculation.CalculationSpecification.Id
                }
            };

            string json = JsonConvert.SerializeObject(calculation);

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

            message.UserProperties.Add("user-id", UserId);
            message.UserProperties.Add("user-name", Username);

            ICalculationsRepository repository = CreateCalculationsRepository();

            repository
            .CreateDraftCalculation(Arg.Any <Calculation>())
            .Returns(HttpStatusCode.BadRequest);

            repository
            .GetCalculationsBySpecificationId(Arg.Is("any-spec-id"))
            .Returns(calculations);

            ILogger logger = CreateLogger();

            ISearchRepository <CalculationIndex> searchRepository = CreateSearchRepository();

            Models.Specs.SpecificationSummary specificationSummary = new Models.Specs.SpecificationSummary()
            {
                Id   = calculation.SpecificationId,
                Name = "Test Spec Name",
            };

            ISpecificationRepository specificationRepository = CreateSpecificationRepository();

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

            specificationRepository
            .GetCalculationSpecificationsForSpecification(Arg.Is(calculation.SpecificationId))
            .Returns(calculationSpecifications);

            CalculationService service = CreateCalculationService(calculationsRepository: repository, logger: logger, searchRepository: searchRepository, specificationRepository: specificationRepository);

            //Act
            await service.CreateCalculation(message);

            //Assert
            logger
            .Received(1)
            .Error($"There was problem creating a new calculation with id {calculation.Id} in Cosmos Db with status code 400");

            await
            repository
            .Received(1)
            .CreateDraftCalculation(Arg.Is <Calculation>(m =>
                                                         m.Id == CalculationId &&
                                                         m.Current.PublishStatus == PublishStatus.Draft &&
                                                         m.Current.Author.Id == UserId &&
                                                         m.Current.Author.Name == Username &&
                                                         m.Current.Date.Date == DateTimeOffset.Now.Date &&
                                                         m.Current.Version == 1 &&
                                                         m.Current.DecimalPlaces == 6
                                                         ));

            await
            searchRepository
            .DidNotReceive()
            .Index(Arg.Any <List <CalculationIndex> >());
        }
        public async Task CreateCalculation_GivenValidCalculationWithNullFundingStream_AndSavesLogs()
        {
            //Arrange
            Calculation calculation = CreateCalculation();

            calculation.FundingStream = null;

            IEnumerable <Calculation> calculations = new[]
            {
                calculation
            };

            IEnumerable <Models.Specs.Calculation> calculationSpecifications = new[]
            {
                new Models.Specs.Calculation
                {
                    Id = calculation.CalculationSpecification.Id
                }
            };

            string json = JsonConvert.SerializeObject(calculation);

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

            message.UserProperties.Add("user-id", UserId);
            message.UserProperties.Add("user-name", Username);

            ICalculationsRepository repository = CreateCalculationsRepository();

            repository
            .CreateDraftCalculation(Arg.Any <Calculation>())
            .Returns(HttpStatusCode.Created);

            repository
            .GetCalculationsBySpecificationId(Arg.Is("any-spec-id"))
            .Returns(calculations);

            Models.Specs.SpecificationSummary specificationSummary = new Models.Specs.SpecificationSummary()
            {
                Id   = calculation.SpecificationId,
                Name = "Test Spec Name",
            };

            ISpecificationRepository specificationRepository = CreateSpecificationRepository();

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

            specificationRepository
            .GetCalculationSpecificationsForSpecification(Arg.Is(calculation.SpecificationId))
            .Returns(calculationSpecifications);

            ILogger logger = CreateLogger();

            ISearchRepository <CalculationIndex> searchRepository = CreateSearchRepository();

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

            ISourceCodeService sourceCodeService = CreateSourceCodeService();

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

            CalculationService service = CreateCalculationService(
                calculationsRepository: repository,
                logger: logger, searchRepository:
                searchRepository,
                specificationRepository: specificationRepository,
                sourceCodeService: sourceCodeService);

            //Act
            await service.CreateCalculation(message);

            //Assert
            logger
            .Received(1)
            .Information($"Calculation with id: {calculation.Id} was successfully saved to Cosmos Db");

            await
            repository
            .Received(1)
            .CreateDraftCalculation(Arg.Is <Calculation>(m =>
                                                         m.Id == CalculationId &&
                                                         m.Current.PublishStatus == PublishStatus.Draft &&
                                                         m.Current.Author.Id == UserId &&
                                                         m.Current.Author.Name == Username &&
                                                         m.Current.Date.Date == DateTimeOffset.Now.Date &&
                                                         m.Current.Version == 1 &&
                                                         m.Current.DecimalPlaces == 6
                                                         ));

            await
            searchRepository
            .Received(1)
            .Index(Arg.Is <List <CalculationIndex> >(
                       m => m.First().Id == CalculationId &&
                       m.First().Name == "Test Calc Name" &&
                       m.First().CalculationSpecificationId == "any-calc-id" &&
                       m.First().CalculationSpecificationName == "Test Calc Name" &&
                       m.First().SpecificationId == "any-spec-id" &&
                       m.First().SpecificationName == "Test Spec Name" &&
                       m.First().FundingPeriodId == "18/19" &&
                       m.First().FundingPeriodName == "2018/2019" &&
                       m.First().FundingStreamId == string.Empty &&
                       m.First().FundingStreamName == "No funding stream set" &&
                       m.First().AllocationLineId == "test-alloc-id" &&
                       m.First().AllocationLineName == "test-alloc-name" &&
                       m.First().PolicySpecificationIds.First() == "policy-id" &&
                       m.First().PolicySpecificationNames.First() == "policy-name"
                       ));
        }
Example #9
0
        public async Task UpdateCalculationCodeOnCalculationSpecificationChange_WhenNoCalculationsFoundReferencingCalculationToBeUpdated_ThenNoCalculationsUpdated()
        {
            // Arrange
            ICalculationsRepository  calculationsRepository           = CreateCalculationsRepository();
            ISpecificationRepository specificationRepository          = CreateSpecificationRepository();
            IVersionRepository <CalculationVersion> versionRepository = CreateCalculationVersionRepository();
            ICalculationCodeReferenceUpdate         calculationCodeReferenceUpdate = FakeCalculationCodeReferenceUpdate();

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

            const string specificationId = "specId";
            const string calculationId   = "updatedCalc";

            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>()
            {
                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    = "Return 10",
                        DecimalPlaces = 6,
                    }
                },
                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    = "Return 50",
                        DecimalPlaces = 6,
                    }
                }
            };

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

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

            foreach (Calculation calculation in calculations)
            {
                calculationCodeReferenceUpdate
                .Received(1)
                .ReplaceSourceCodeReferences(calculation.Current.SourceCode,
                                             VisualBasicTypeGenerator.GenerateIdentifier(comparison.Previous.Name),
                                             VisualBasicTypeGenerator.GenerateIdentifier(comparison.Current.Name));
            }
        }