public async Task LinkPatient(LinkReferenceRequest request) { var cmUserId = request.Patient.Id; var cmSuffix = cmUserId.Substring( cmUserId.LastIndexOf("@", StringComparison.Ordinal) + 1); var patient = new LinkEnquiry( cmSuffix, cmUserId, request.Patient.ReferenceNumber, request.Patient.CareContexts); try { var doesRequestExists = await discoveryRequestRepository.RequestExistsFor( request.TransactionId, request.Patient?.Id, request.Patient?.ReferenceNumber); ErrorRepresentation errorRepresentation = null; if (!doesRequestExists) { errorRepresentation = new ErrorRepresentation( new Error(ErrorCode.DiscoveryRequestNotFound, ErrorMessage.DiscoveryRequestNotFound)); } var patientReferenceRequest = new PatientLinkEnquiry(request.TransactionId, request.RequestId, patient); var patientLinkEnquiryRepresentation = new PatientLinkEnquiryRepresentation(); var(linkReferenceResponse, error) = errorRepresentation != null ? (patientLinkEnquiryRepresentation, errorRepresentation) : await linkPatient.LinkPatients(patientReferenceRequest); var linkedPatientRepresentation = new LinkEnquiryRepresentation(); if (linkReferenceResponse != null) { linkedPatientRepresentation = linkReferenceResponse.Link; } var response = new GatewayLinkResponse( linkedPatientRepresentation, error?.Error, new Resp(request.RequestId), request.TransactionId, DateTime.Now.ToUniversalTime(), Guid.NewGuid()); await gatewayClient.SendDataToGateway(PATH_ON_LINK_INIT, response, cmSuffix); } catch (Exception exception) { Log.Error(exception, exception.StackTrace); } }
private async void ShouldReturnLinkReferenceResponse() { const string linkReferenceNumber = "linkreference"; const string authType = "MEDIATED"; const string programRefNo = "129"; const string medium = "MOBILE"; IEnumerable <CareContextEnquiry> careContexts = new[] { new CareContextEnquiry(programRefNo) }; var patient = new LinkEnquiry(TestBuilders.Faker().Random.Hash(), TestBuilders.Faker().Random.Hash(), testPatient.Identifier, careContexts); var patientReferenceRequest = new PatientLinkEnquiry(TestBuilders.Faker().Random.Hash(), TestBuilders.Faker().Random.Hash(), patient); guidGenerator.Setup(x => x.NewGuid()).Returns(linkReferenceNumber); patientVerification.Setup(x => x.SendTokenFor(new Session(linkReferenceNumber , new Communication(CommunicationMode.MOBILE, testPatient.PhoneNumber) , new OtpGenerationDetail(TestBuilder.Faker().Random.Word(), OtpAction.LINK_PATIENT_CARECONTEXT.ToString())))) .ReturnsAsync((OtpMessage)null); var initiatedLinkRequest = new InitiatedLinkRequest(patientReferenceRequest.RequestId, patientReferenceRequest.TransactionId, linkReferenceNumber, false, It.IsAny <string>()); linkRepository.Setup(x => x.SaveRequestWith(linkReferenceNumber, patientReferenceRequest.Patient.ConsentManagerId, patientReferenceRequest.Patient.ConsentManagerUserId, patientReferenceRequest.Patient.ReferenceNumber, new[] { programRefNo })) .ReturnsAsync(new Tuple <LinkEnquires, Exception>(null, null)); linkRepository.Setup(x => x.Save(patientReferenceRequest.RequestId, patientReferenceRequest.TransactionId, linkReferenceNumber)) .ReturnsAsync(Option.Some(initiatedLinkRequest)); patientRepository.Setup(x => x.PatientWith(testPatient.Identifier)) .Returns(Option.Some(testPatient)); var(response, _) = await linkPatient.LinkPatients(patientReferenceRequest); patientVerification.Verify(); linkRepository.Verify(); guidGenerator.Verify(); discoveryRequestRepository.Verify(x => x.Delete(patientReferenceRequest.TransactionId, patientReferenceRequest.Patient.ConsentManagerUserId)); response.Link.ReferenceNumber.Should().Be(linkReferenceNumber); response.Link.AuthenticationType.Should().Be(authType); response.Link.Meta.CommunicationHint.Should().Be(testPatient.PhoneNumber); response.Link.Meta.CommunicationMedium.Should().Be(medium); response.Link.Should().NotBeNull(); }
private async void ShouldReturnPatientNotFoundError() { IEnumerable <CareContextEnquiry> careContexts = new[] { new CareContextEnquiry("129") }; var patient = new LinkEnquiry(TestBuilders.Faker().Random.Hash(), TestBuilders.Faker().Random.Hash(), "1234", careContexts); var patientReferenceRequest = new PatientLinkEnquiry(TestBuilders.Faker().Random.Hash(), TestBuilders.Faker().Random.Hash(), patient); var expectedError = new ErrorRepresentation(new Error(ErrorCode.NoPatientFound, ErrorMessage.NoPatientFound)); var(_, error) = await linkPatient.LinkPatients(patientReferenceRequest); error.Should().BeEquivalentTo(expectedError); }
private async void ShouldReturnCareContextNotFoundError() { IEnumerable <CareContextEnquiry> careContexts = new[] { new CareContextEnquiry("1234") }; var patient = new LinkEnquiry(TestBuilders.Faker().Random.Hash(), TestBuilders.Faker().Random.Hash(), "4", careContexts); var patientReferenceRequest = new PatientLinkEnquiry(TestBuilders.Faker().Random.Hash(), TestBuilders.Faker().Random.Hash(), patient); patientRepository.Setup(e => e.PatientWith(testPatient.Identifier)) .Returns(Option.Some(testPatient)); var expectedError = new ErrorRepresentation( new Error(ErrorCode.CareContextNotFound, ErrorMessage.CareContextNotFound)); var(_, error) = await linkPatient.LinkPatients(patientReferenceRequest); patientRepository.Verify(); discoveryRequestRepository.Invocations.Count.Should().Be(0); error.Should().BeEquivalentTo(expectedError); }
private async Task <ValueTuple <Patient, ErrorRepresentation> > PatientAndCareContextValidation( PatientLinkEnquiry request) { var patient = await patientRepository.PatientWithAsync(request.Patient.ReferenceNumber); return(patient.Map(patient => { var programs = request.Patient.CareContexts .Where(careContext => patient.CareContexts.Any(c => c.ReferenceNumber == careContext.ReferenceNumber)) .Select(context => new CareContextRepresentation(context.ReferenceNumber, patient.CareContexts.First(info => info.ReferenceNumber == context.ReferenceNumber) .Display)).ToList(); if (programs.Count != request.Patient.CareContexts.Count()) { return (null, new ErrorRepresentation(new Error(ErrorCode.CareContextNotFound, ErrorMessage.CareContextNotFound))); } return (patient, (ErrorRepresentation)null); }) .ValueOr((null, new ErrorRepresentation(new Error(ErrorCode.NoPatientFound, ErrorMessage.NoPatientFound))))); }
private async void ErrorOnDuplicateRequestId() { const string linkReferenceNumber = "linkreference"; const string programRefNo = "129"; var expectedErrorResponse = new ErrorRepresentation(new Error(ErrorCode.DuplicateRequestId, ErrorMessage.DuplicateRequestId)); IEnumerable <CareContextEnquiry> careContexts = new[] { new CareContextEnquiry(programRefNo) }; var patient = new LinkEnquiry(TestBuilders.Faker().Random.Hash(), TestBuilders.Faker().Random.Hash(), testPatient.Identifier, careContexts); var patientReferenceRequest = new PatientLinkEnquiry(TestBuilders.Faker().Random.Hash(), TestBuilders.Faker().Random.Hash(), patient); guidGenerator.Setup(x => x.NewGuid()).Returns(linkReferenceNumber); patientVerification.Setup(x => x.SendTokenFor(new Session(linkReferenceNumber , new Communication(CommunicationMode.MOBILE, testPatient.PhoneNumber), new OtpGenerationDetail(TestBuilder.Faker().Random.Word(), OtpAction.LINK_PATIENT_CARECONTEXT.ToString())))) .ReturnsAsync((OtpMessage)null); linkRepository.Setup(x => x.SaveRequestWith(linkReferenceNumber, patientReferenceRequest.Patient.ConsentManagerId, patientReferenceRequest.Patient.ConsentManagerUserId, patientReferenceRequest.Patient.ReferenceNumber, new[] { programRefNo })) .ReturnsAsync(new Tuple <LinkEnquires, Exception>(null, null)); linkRepository.Setup(x => x.Save(patientReferenceRequest.RequestId, patientReferenceRequest.TransactionId, linkReferenceNumber)) .ReturnsAsync(Option.None <InitiatedLinkRequest>()); patientRepository.Setup(x => x.PatientWith(testPatient.Identifier)) .Returns(Option.Some(testPatient)); var(_, errorRepresentation) = await linkPatient.LinkPatients(patientReferenceRequest); patientVerification.Verify(); linkRepository.Verify(); guidGenerator.Verify(); errorRepresentation.Should().BeEquivalentTo(expectedErrorResponse); }
public virtual async Task <ValueTuple <PatientLinkEnquiryRepresentation, ErrorRepresentation> > LinkPatients( PatientLinkEnquiry request) { var(patient, error) = await PatientAndCareContextValidation(request); if (error != null) { Log.Error(error.Error.Message); return(null, error); } var linkRefNumber = referenceNumberGenerator.NewGuid(); using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) { if (!await SaveInitiatedLinkRequest(request.RequestId, request.TransactionId, linkRefNumber) .ConfigureAwait(false)) { return(null, new ErrorRepresentation(new Error(ErrorCode.DuplicateRequestId, ErrorMessage.DuplicateRequestId)) ); } var careContextReferenceNumbers = request.Patient.CareContexts .Select(context => context.ReferenceNumber) .ToArray(); var(_, exception) = await linkPatientRepository.SaveRequestWith( linkRefNumber, request.Patient.ConsentManagerId, request.Patient.ConsentManagerUserId, request.Patient.ReferenceNumber, careContextReferenceNumbers) .ConfigureAwait(false); if (exception != null) { return(null, new ErrorRepresentation(new Error(ErrorCode.ServerInternalError, ErrorMessage.DatabaseStorageError))); } var session = new Session( linkRefNumber, new Communication(CommunicationMode.MOBILE, patient.PhoneNumber), new OtpGenerationDetail(otpService.Value.SenderSystemName, OtpAction.LINK_PATIENT_CARECONTEXT.ToString())); var otpGeneration = await patientVerification.SendTokenFor(session); if (otpGeneration != null) { return(null, new ErrorRepresentation(new Error(ErrorCode.OtpGenerationFailed, otpGeneration.Message))); } await discoveryRequestRepository.Delete(request.TransactionId, request.Patient.ConsentManagerUserId) .ConfigureAwait(false); scope.Complete(); } var time = new TimeSpan(0, 0, otpService.Value.OffsetInMinutes, 0); var expiry = DateTime.Now.Add(time).ToUniversalTime().ToString(Constants.DateTimeFormat); var meta = new LinkReferenceMeta(nameof(CommunicationMode.MOBILE), patient.PhoneNumber, expiry); var patientLinkReferenceResponse = new PatientLinkEnquiryRepresentation( new LinkEnquiryRepresentation(linkRefNumber, "MEDIATED", meta)); return(patientLinkReferenceResponse, null); }