public VerifyTestCaseData( VerifyWarrantyCaseRequest request, VerifyWarrantyCaseResponse expectedResponse) { Request = request; ExpectedResponse = expectedResponse; }
public ValidatableRequest( VerifyWarrantyCaseRequest request, WarrantyCaseOperation operation) { Request = request; Operation = operation; }
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); }
// 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))); } }
public ValidatableResponse( VerifyWarrantyCaseRequest request, WarrantyCaseOperation operation, Guid requestId, WarrantyResponse warrantyResponse) { Request = request; Operation = operation; RequestId = requestId; WarrantyResponse = warrantyResponse; }
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],
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))); }
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))); }
// 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, });
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); } } }
public async Task <VerifyWarrantyCaseResponse> Verify([FromBody] VerifyWarrantyCaseRequest request) { return(await _warrantyService.Verify(request)); }