Ejemplo n.º 1
0
 public VerifyTestCaseData(
     VerifyWarrantyCaseRequest request,
     VerifyWarrantyCaseResponse expectedResponse)
 {
     Request          = request;
     ExpectedResponse = expectedResponse;
 }
Ejemplo n.º 2
0
 public ValidatableRequest(
     VerifyWarrantyCaseRequest request,
     WarrantyCaseOperation operation)
 {
     Request   = request;
     Operation = operation;
 }
Ejemplo n.º 3
0
        public async Task <VerifyWarrantyCaseResponse> Verify(
            VerifyWarrantyCaseRequest request)
        {
            var preCommitVerifyResult = await PreCommitVerify(request);

            if (!preCommitVerifyResult.IsSuccess)
            {
                var preCommitVerifyWarrantyCaseResponse = BuidVerifyWarrantyCaseResponse(
                    preCommitVerifyResult,
                    preSavedResponse: null);
                return(preCommitVerifyWarrantyCaseResponse);
            }
            var preSavedResponse = preCommitVerifyResult.Success; // null if not commit

            var requestId = RequestIdGenerator.GenerateRequestId();
            var operation = request.Operation;

            var performVerifyActionResult = await PerformVerifyAction(request, operation, requestId);

            var saveResult = await SaveWarrantyCaseResponse(request, operation, requestId, performVerifyActionResult);

            var successfulConditionResult = SatisfySuccessfulCondition(
                operation,
                isPreCommitVerify: false,
                saveResult);
            var verifyWarrantyCaseResponse = BuidVerifyWarrantyCaseResponse(
                successfulConditionResult,
                preSavedResponse: preSavedResponse);

            return(verifyWarrantyCaseResponse);
        }
Ejemplo n.º 4
0
        // if the request is not Commit, returns Result with IsSuccess: true and Success: null
        internal async Task <Result <WarrantyCaseResponse, IFailure> > PreCommitVerify(
            VerifyWarrantyCaseRequest request)
        {
            if (request.Operation != WarrantyCaseOperation.Commit)
            {
                return(Result <WarrantyCaseResponse, IFailure> .SuccessNull());
            }

            var requestId = RequestIdGenerator.GenerateRequestId();

            var performVerifyActionResult = await PerformVerifyAction(request, WarrantyCaseOperation.Verify, requestId);

            var saveResult = await SaveWarrantyCaseResponse(request, WarrantyCaseOperation.Verify, requestId, performVerifyActionResult);

            var successfulConditionResult = SatisfySuccessfulCondition(
                WarrantyCaseOperation.Verify,
                isPreCommitVerify: true,
                saveResult);

            if (successfulConditionResult.IsSuccess)
            {
                return(successfulConditionResult);
            }
            else
            {
                var failure = successfulConditionResult.Failure !;
                return(new Result <WarrantyCaseResponse, IFailure>(
                           new VerifyBeforeCommitFailure(
                               message: $"Pre-commit verification failed RequestId: `{requestId}`, FailureType: `{failure.FailureType}`, FailureMessage: `{failure.Message}`.",
                               warrantyCaseResponse: failure is SuccessfulConditionFailure successfulConditionFailure
                            ? successfulConditionFailure.WarrantyCaseResponse
                            : null)));
            }
        }
        public Result <WarrantyRequest, RequestConversionFailure> Build(
            VerifyWarrantyCaseRequest verifyWarrantyCaseRequest,
            WarrantyCaseOperation operation,
            Guid requestId)
        {
            try
            {
                var(requestType, actionType) = GetRequestTypeActionType(operation);

                var warrantyRequest = new WarrantyRequest
                {
                    RequestId       = requestId,
                    RequestType     = requestType,
                    Action          = actionType,
                    WarrantyCaseId  = verifyWarrantyCaseRequest.WarrantyCaseId,
                    TransactionDate = operation != WarrantyCaseOperation.Cancel
                        ? GetTransactionDateString(verifyWarrantyCaseRequest.TransactionDateTime)
                        : null,
                    OrderDetails = GetOrderDetails(verifyWarrantyCaseRequest, operation),
                };

                return(new Result <WarrantyRequest, RequestConversionFailure>(warrantyRequest));
            }
            catch (Exception e)
            {
                return(new Result <WarrantyRequest, RequestConversionFailure>(
                           new RequestConversionFailure($"Cannot build request of RequestId: `{requestId}` because:" + Environment.NewLine + e.Message)));
            }
        }
Ejemplo n.º 6
0
 public ValidatableResponse(
     VerifyWarrantyCaseRequest request,
     WarrantyCaseOperation operation,
     Guid requestId,
     WarrantyResponse warrantyResponse)
 {
     Request          = request;
     Operation        = operation;
     RequestId        = requestId;
     WarrantyResponse = warrantyResponse;
 }
Ejemplo n.º 7
0
 public Result <WarrantyCaseResponse, IFailure> Convert(
     VerifyWarrantyCaseRequest request,
     WarrantyCaseOperation operation,
     Guid requestId,
     WarrantyResponse warrantyResponse)
 {
     try
     {
         var warrantyCaseResponse = new WarrantyCaseResponse(
             orderId: request.OrderId,
             warrantyCaseId: warrantyResponse.Header.WarrantyCaseId !)
         {
             Operation          = operation,
             WarrantyCaseStatus = WarrantyCaseStatusMap[warrantyResponse.Body !.CaseStatus],
Ejemplo n.º 8
0
        public Result <Unit, IFailure> Validate(
            VerifyWarrantyCaseRequest request,
            WarrantyCaseOperation operation,
            Guid requestId,
            WarrantyResponse warrantyResponse)
        {
            if (warrantyResponse.Header.WarrantyResponseErrors
                .FirstOrDefault(e => e.Type == WarrantyResponseErrorType.ServiceNotAvailable)
                is WarrantyResponseError serviceNotAvailableError)
            {
                return(new Result <Unit, IFailure>(
                           new ServiceNotAvailableFailure(serviceNotAvailableError.Message)));
            }

            if (warrantyResponse.Header.WarrantyResponseErrors
                .FirstOrDefault(e => e.Type == WarrantyResponseErrorType.InvalidRequest)
                is WarrantyResponseError invalidRequestError)
            {
                return(new Result <Unit, IFailure>(
                           new InvalidRequestFailure(invalidRequestError.Message)));
            }

            if (warrantyResponse.Header.WarrantyResponseErrors
                .FirstOrDefault(e => e.Type == WarrantyResponseErrorType.InternalError)
                is WarrantyResponseError warrantyServiceInternalError)
            {
                return(new Result <Unit, IFailure>(
                           new WarrantyServiceInternalErrorFailure(warrantyServiceInternalError.Message)));
            }

            var validatableResponse = new ValidatableResponse(
                request,
                operation,
                requestId,
                warrantyResponse);
            var validationResult = Validator.Validate(validatableResponse);

            if (validationResult.IsValid)
            {
                return(new Result <Unit, IFailure>(Unit.Value));
            }

            var errorMessages = string.Join(Environment.NewLine, validationResult.Errors.Select(x => x.ErrorMessage));

            return(new Result <Unit, IFailure>(
                       new ResponseValidationFailure(
                           $"Response of RequestId: `{requestId}` failed validation:" + Environment.NewLine + errorMessages)));
        }
Ejemplo n.º 9
0
        public Result <Unit, RequestValidationFailure> Validate(
            VerifyWarrantyCaseRequest request,
            WarrantyCaseOperation operation,
            Guid requestId)
        {
            var validatableRequest = new ValidatableRequest(
                request,
                operation);

            var validationResult = Validator.Validate(validatableRequest);

            if (validationResult.IsValid)
            {
                return(new Result <Unit, RequestValidationFailure>(Unit.Value));
            }

            var errorMessages = string.Join(Environment.NewLine, validationResult.Errors.Select(x => x.ErrorMessage));

            return(new Result <Unit, RequestValidationFailure>(
                       new RequestValidationFailure(
                           $"Request of RequestId: `{requestId}` failed validation:" + Environment.NewLine + errorMessages)));
        }
Ejemplo n.º 10
0
        // success means called Thrid Party, saved raw request and raw response, (and saved warrantyProof), and returns a converted response
        // ---
        // anything here after SaveExternalPartyResponse in BudgetDatabase should be pure (non-deterministic and no side-effect)
        // so that the saved ExternalPartyResponse can be a source of truth
        internal async Task <Result <WarrantyCaseResponse, IFailure> > PerformVerifyAction(
            VerifyWarrantyCaseRequest request,
            WarrantyCaseOperation operation,
            Guid requestId)
        {
            var validateRequestResult = RequestValidator.Validate(request, operation, requestId);

            if (!validateRequestResult.IsSuccess)
            {
                return(new Result <WarrantyCaseResponse, IFailure>(validateRequestResult.Failure !));
            }

            var build = RequestBuilder.Build(request, operation, requestId);

            if (!build.IsSuccess)
            {
                return(new Result <WarrantyCaseResponse, IFailure>(build.Failure !));
            }
            var warrantyRequest = build.Success !;

            var saveWarrantyRequest = await BudgetDataWrapper.SaveExternalPartyRequest(
                new ExternalPartyRequest(
                    orderId : request.OrderId,
                    request : JsonConvert.SerializeObject(warrantyRequest))
            {
                Operation = operation,
                RequestId = requestId,
            });

            if (!saveWarrantyRequest.IsSuccess)
            {
                return(new Result <WarrantyCaseResponse, IFailure>(saveWarrantyRequest.Failure !));
            }

            var call = await ExternalPartyWrapper.Call(warrantyRequest);

            if (!call.IsSuccess)
            {
                return(new Result <WarrantyCaseResponse, IFailure>(call.Failure !));
            }
            var rawResponse = call.Success !;

            var saveWarrantyResponse = await BudgetDataWrapper.SaveExternalPartyResponse(
                new ExternalPartyResponse(
                    orderId : request.OrderId,
                    response : JsonConvert.SerializeObject(rawResponse))
            {
                Operation = operation,
                RequestId = requestId,
            });

            if (!saveWarrantyResponse.IsSuccess)
            {
                return(new Result <WarrantyCaseResponse, IFailure>(saveWarrantyRequest.Failure !));
            }

            var validateResponse = ResponseValidator.Validate(request, operation, requestId, rawResponse);

            if (!validateResponse.IsSuccess)
            {
                return(new Result <WarrantyCaseResponse, IFailure>(validateResponse.Failure !));
            }

            var convertResponse = ResponseConverter.Convert(request, operation, requestId, rawResponse);

            if (!convertResponse.IsSuccess)
            {
                return(new Result <WarrantyCaseResponse, IFailure>(convertResponse.Failure !));
            }
            var convertedResponse = convertResponse.Success !;

            if (operation == WarrantyCaseOperation.Commit &&
                convertedResponse.WarrantyCaseStatus == WarrantyCaseStatus.Committed)
            {
                var saveWarrantyProof = await ComprehensiveDataWrapper.SaveWarrantyProof(
                    new WarrantyProof(
                        orderId : request.OrderId,
                        warrantyCaseId : convertedResponse.WarrantyCaseId,
                        proof : rawResponse.Body !.OrderReports.Single().WarrantyProof !)
                {
                    RequestId = requestId,
                });
Ejemplo n.º 11
0
        public async Task Verify(
            VerifyWarrantyCaseRequest request,
            IList <Guid> requestIds,
            IList <ExternalPartyCall> externalPartyCalls,
            VerifyWarrantyCaseResponse expectedResponse,
            int expectedWarrantyCaseVerificationCount,
            IList <WarrantyCaseVerification> expectedWarrantyCaseVerifications,
            int expectedWarrantyProofCount,
            IList <WarrantyProof?> expectedWarrantyProofs,                 // corresponds to requestIds
            int expectedExternalPartyRequestCount,
            IList <ExternalPartyRequest?> expectedExternalPartyRequests,   // corresponds to requestIds
            int expectedExternalPartyResponseCount,
            IList <ExternalPartyResponse?> expectedExternalPartyResponses) // corresponds to requestIds
        {
            var services = GetServices();

            var mockedRequestIdGenerator = new Mock <IRequestIdGenerator>(MockBehavior.Strict);
            var mockedRequestIdGeneratorSetupSequence = mockedRequestIdGenerator
                                                        .SetupSequence(m => m.GenerateRequestId());

            foreach (var requestId in requestIds)
            {
                mockedRequestIdGeneratorSetupSequence.Returns(requestId);
            }
            services.AddSingleton(_ => mockedRequestIdGenerator.Object);

            List <WarrantyRequest> actualExternalPartyCallRequests = new List <WarrantyRequest>();
            var externalPartyProxyCallSequence = new MockSequence();

            var mockedExternalPartyProxy = new Mock <IExternalPartyProxy>(MockBehavior.Strict);

            foreach (var externalPartyCall in externalPartyCalls)
            {
                var mockedExternalPartyProxySetup = mockedExternalPartyProxy
                                                    .InSequence(externalPartyProxyCallSequence)
                                                    .Setup(m => m.Call(It.IsAny <WarrantyRequest>()))
                                                    .Callback <WarrantyRequest>(warrantyRequest => actualExternalPartyCallRequests.Add(warrantyRequest));
                if (externalPartyCall.Throws)
                {
                    mockedExternalPartyProxySetup.Throws(new NetworkException("Network exception."));
                }
                else
                {
                    mockedExternalPartyProxySetup.ReturnsAsync(externalPartyCall.Response !);
                }
            }
            services.AddScoped(_ => mockedExternalPartyProxy.Object);

            var serviceProvider = services.BuildServiceProvider();

            using var serviceScope = serviceProvider.CreateScope();
            var warrantyService = serviceScope.ServiceProvider.GetRequiredService <IWarrantyService>();

            var actual = await warrantyService.Verify(request);

            // assert
            Assert.Equal(expectedResponse.IsSuccess, actual.IsSuccess);
            actual.WarrantyCaseResponse.Should().BeEquivalentTo(expectedResponse.WarrantyCaseResponse);
            Assert.Equal(expectedResponse.FailureType, actual.FailureType);
            Assert.Equal(expectedResponse.FailureMessage is null, actual.FailureMessage is null);

            mockedExternalPartyProxy.Verify(
                m => m.Call(It.IsAny <WarrantyRequest>()),
                Times.Exactly(externalPartyCalls.Count));
            actualExternalPartyCallRequests.Should().BeEquivalentTo(externalPartyCalls.Select(c => c.ExpectedRequest).ToList());

            // assert saved data
            using (var comprehensiveDbContext = serviceScope.ServiceProvider.GetRequiredService <ComprehensiveDataDbContext>())
            {
                var actualWarrantyCaseVerificationCount = comprehensiveDbContext.WarrantyCaseVerification
                                                          .Where(v => v.OrderId == request.OrderId)
                                                          .Count();
                Assert.Equal(expectedWarrantyCaseVerificationCount, actualWarrantyCaseVerificationCount);

                foreach ((WarrantyCaseVerification expectedWarrantyCaseVerification, int i) in
                         expectedWarrantyCaseVerifications.Select((y, i) => (y, i)))
                {
                    var actualWarrantyCaseVerification = comprehensiveDbContext.WarrantyCaseVerification
                                                         .Where(v => v.OrderId == request.OrderId)
                                                         .OrderByDescending(v => v.DateTime)
                                                         .Skip(expectedWarrantyCaseVerifications.Count - 1 - i)
                                                         .First();
                    actualWarrantyCaseVerification.Should().BeEquivalentTo(
                        expectedWarrantyCaseVerification,
                        opt => opt
                        .Excluding(v => v.Id)
                        .Excluding(v => v.DateTime)
                        .Excluding(v => v.FailureMessage)
                        .Excluding(v => v.ConvertedResponse));
                    Assert.Equal(
                        expectedWarrantyCaseVerification.FailureMessage is null,
                        actualWarrantyCaseVerification.FailureMessage is null);
                    var expectedConvertedResponse = JsonConvert.DeserializeObject <WarrantyCaseResponse?>(expectedWarrantyCaseVerification.ConvertedResponse ?? "");
                    var actualConvertedResponse   = JsonConvert.DeserializeObject <WarrantyCaseResponse?>(actualWarrantyCaseVerification.ConvertedResponse ?? "");
                    actualConvertedResponse.Should().BeEquivalentTo(expectedConvertedResponse);
                }

                var actualWarrantyProofCount = comprehensiveDbContext.WarrantyProof
                                               .Where(p => p.OrderId == request.OrderId)
                                               .Count();
                Assert.Equal(actualWarrantyProofCount, expectedWarrantyProofCount);

                foreach ((WarrantyProof? expectedWarrantyProof, int i) in
                         expectedWarrantyProofs.Select((y, i) => (y, i)))
                {
                    var actualWarrantyProof = comprehensiveDbContext.WarrantyProof
                                              .Where(p => p.RequestId == requestIds.Last())
                                              .SingleOrDefault();
                    actualWarrantyProof.Should().BeEquivalentTo(
                        expectedWarrantyProof,
                        opt => opt
                        .Excluding(req => req.Id)
                        .Excluding(req => req.DateTime));
                }
            }

            using (var budgetDbContext = serviceScope.ServiceProvider.GetRequiredService <BudgetDataDbContext>())
            {
                var actualExternalPartyRequestCount = budgetDbContext.ExternalPartyRequest
                                                      .Where(req => req.OrderId == request.OrderId)
                                                      .Count();
                Assert.Equal(expectedExternalPartyRequestCount, actualExternalPartyRequestCount);

                foreach ((ExternalPartyRequest? expectedExternalPartyRequest, int i) in
                         expectedExternalPartyRequests.Select((y, i) => (y, i)))
                {
                    var actualExternalPartyRequest = budgetDbContext.ExternalPartyRequest
                                                     .Where(req => req.OrderId == request.OrderId && req.RequestId == requestIds[i])
                                                     .SingleOrDefault();
                    actualExternalPartyRequest.Should().BeEquivalentTo(
                        expectedExternalPartyRequest,
                        opt => opt
                        .Excluding(req => req.Id)
                        .Excluding(req => req.DateTime)
                        .Excluding(req => req.Request));
                    var expectedRawRequest = JsonConvert.DeserializeObject <WarrantyResponse?>(expectedExternalPartyRequest.Request ?? "");
                    var actualRawRequest   = JsonConvert.DeserializeObject <WarrantyResponse?>(actualExternalPartyRequest.Request ?? "");
                    actualRawRequest.Should().BeEquivalentTo(expectedRawRequest);
                }

                var actualExternalPartyResponseCount = budgetDbContext.ExternalPartyResponse
                                                       .Where(res => res.OrderId == request.OrderId)
                                                       .Count();
                Assert.Equal(expectedExternalPartyResponseCount, actualExternalPartyResponseCount);

                foreach ((ExternalPartyResponse? expectedExternalPartyResponse, int i) in
                         expectedExternalPartyResponses.Select((y, i) => (y, i)))
                {
                    var actualExternalPartyResponse = budgetDbContext.ExternalPartyResponse
                                                      .Where(req => req.OrderId == request.OrderId && req.RequestId == requestIds[i])
                                                      .SingleOrDefault();
                    actualExternalPartyResponse.Should().BeEquivalentTo(
                        expectedExternalPartyResponse,
                        opt => opt
                        .Excluding(res => res.Id)
                        .Excluding(res => res.DateTime)
                        .Excluding(res => res.Response));
                    var expectedRawResponse = JsonConvert.DeserializeObject <WarrantyResponse?>(expectedExternalPartyResponse.Response ?? "");
                    var actualRawResponse   = JsonConvert.DeserializeObject <WarrantyResponse?>(actualExternalPartyResponse.Response ?? "");
                    actualRawResponse.Should().BeEquivalentTo(expectedRawResponse);
                }
            }
        }
Ejemplo n.º 12
0
 public async Task <VerifyWarrantyCaseResponse> Verify([FromBody] VerifyWarrantyCaseRequest request)
 {
     return(await _warrantyService.Verify(request));
 }