async public Task GetCalculationById_GivenCalculationIdWasProvidedButCalculationCouldNotBeFound_ReturnsNotFound()
        {
            //Arrange
            IQueryCollection queryStringValues = new QueryCollection(new Dictionary<string, StringValues>
            {
                { "calculationId", new StringValues(CalculationId) }

            });

            HttpRequest request = Substitute.For<HttpRequest>();
            request
                .Query
                .Returns(queryStringValues);

            ILogger logger = CreateLogger();

            ICalculationsRepository calculationsRepository = CreateCalculationsRepository();
            calculationsRepository
                .GetCalculationById(Arg.Is(CalculationId))
                .Returns((Calculation)null);

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

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

            //Assert
            result
                .Should()
                .BeOfType<NotFoundResult>();

            logger
                .Received(1)
                .Information(Arg.Is($"A calculation was not found for calculation id {CalculationId}"));
        }
        async public Task GetCalculationCurrentVersion_GivencalculationWasFoundWithNoCurrent_ReturnsNotFound()
        {
            //Arrange
            Calculation calculation = new Calculation();

            ILogger logger = CreateLogger();

            ICalculationsRepository calculationsRepository = CreateCalculationsRepository();

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

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

            //Act
            IActionResult result = await service.GetCalculationById(CalculationId);

            //Assert
            result
            .Should()
            .BeOfType <NotFoundResult>();

            logger
            .Received(1)
            .Information(Arg.Is($"A current calculation was not found for calculation id {CalculationId}"));
        }
        public async Task GetCalculationCurrentVersion_GivenNoCalculationIdprovided_returnsBadrequest()
        {
            //Arrange
            ILogger logger = CreateLogger();

            CalculationService service = CreateCalculationService(logger: logger);

            //Act
            IActionResult result = await service.GetCalculationById(null);

            //Assert
            logger
            .Received(1)
            .Error("No calculation Id was provided to GetCalculationCurrentVersion");

            result
            .Should()
            .BeOfType <BadRequestObjectResult>();
        }
        async public Task GetCalculationById_GivenNoCalculationIdWasprovided_ReturnsBadRequest()
        {
            //Arrange
            HttpRequest request = Substitute.For<HttpRequest>();

            ILogger logger = CreateLogger();

            CalculationService service = CreateCalculationService(logger: logger);

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

            //Assert
            result
                .Should()
                .BeOfType<BadRequestObjectResult>();

            logger
                .Received(1)
                .Error(Arg.Is("No calculation Id was provided to GetCalculationById"));
        }
        async public Task GetCalculationCurrentVersion_GivenCalculationExistsAndWasWasFoundInCache_ReturnsOK()
        {
            //Arrange
            const string   specificationId  = "specId";
            DateTimeOffset lastModifiedDate = DateTimeOffset.Now;

            CalculationResponseModel calculation = new CalculationResponseModel
            {
                Author          = new Reference(UserId, Username),
                LastUpdated     = lastModifiedDate,
                SourceCode      = "source code",
                Version         = 1,
                Name            = "any name",
                Id              = CalculationId,
                FundingStreamId = "18/19",
                CalculationType = CalculationType.Additional,
                SpecificationId = specificationId,
            };

            ILogger logger = CreateLogger();

            ICalculationsRepository calculationsRepository = CreateCalculationsRepository();

            ICacheProvider cacheProvider = CreateCacheProvider();

            cacheProvider
            .GetAsync <CalculationResponseModel>(Arg.Is($"{CacheKeys.CurrentCalculation}{CalculationId}"))
            .Returns(calculation);

            CalculationService service = CreateCalculationService(logger: logger, calculationsRepository: calculationsRepository, cacheProvider: cacheProvider);

            //Act
            IActionResult result = await service.GetCalculationById(CalculationId);

            //Assert
            result
            .Should()
            .BeOfType <OkObjectResult>()
            .Which
            .Value
            .Should().BeEquivalentTo(new CalculationResponseModel
            {
                Author          = new Reference(UserId, Username),
                LastUpdated     = lastModifiedDate,
                SourceCode      = "source code",
                Version         = 1,
                Name            = "any name",
                Id              = CalculationId,
                FundingStreamId = "18/19",
                CalculationType = CalculationType.Additional,
                SpecificationId = specificationId,
            });

            await calculationsRepository
            .Received(0)
            .GetCalculationById(Arg.Any <string>());

            await cacheProvider
            .Received(1)
            .GetAsync <CalculationResponseModel>(Arg.Is($"{CacheKeys.CurrentCalculation}{CalculationId}"));
        }