From 93c6aa8f1d27e9f599d82edcca3936a41538cab5 Mon Sep 17 00:00:00 2001 From: will-larkin <160748088+will-larkin-nhs@users.noreply.github.com> Date: Mon, 23 Dec 2024 12:30:17 +0000 Subject: [PATCH 1/4] feat: new external endpoint for getting filtered data --- .../DemographicDataFunction.cs | 19 +++++++++++++++++++ .../FilteredDemographicData.cs | 9 +++++++++ 2 files changed, 28 insertions(+) create mode 100644 application/CohortManager/src/Functions/DemographicServices/DemographicDataManagementFunction/FilteredDemographicData.cs diff --git a/application/CohortManager/src/Functions/DemographicServices/DemographicDataManagementFunction/DemographicDataFunction.cs b/application/CohortManager/src/Functions/DemographicServices/DemographicDataManagementFunction/DemographicDataFunction.cs index 65c8c6b16..a2574acb6 100644 --- a/application/CohortManager/src/Functions/DemographicServices/DemographicDataManagementFunction/DemographicDataFunction.cs +++ b/application/CohortManager/src/Functions/DemographicServices/DemographicDataManagementFunction/DemographicDataFunction.cs @@ -24,6 +24,17 @@ public DemographicDataFunction(ILogger logger, ICreateR [Function("DemographicDataFunction")] public async Task Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req) + { + return await Main(req, false); + } + + [Function("DemographicDataFunctionExternal")] + public async Task RunExternal([HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequestData req) + { + return await Main(req, true); + } + + private async Task Main(HttpRequestData req, bool externalRequest) { var participantData = new Participant(); try @@ -56,6 +67,14 @@ public async Task Run([HttpTrigger(AuthorizationLevel.Anonymou _logger.LogInformation("demographic function failed"); return _createResponse.CreateHttpResponse(HttpStatusCode.NotFound, req); } + + // Filters out unnsecessry data for use in the BI prdoduct + if (externalRequest) + { + var filterdData = JsonSerializer.Deserialize(data); + data = JsonSerializer.Serialize(filterdData); + } + return _createResponse.CreateHttpResponse(HttpStatusCode.OK, req, data); } } diff --git a/application/CohortManager/src/Functions/DemographicServices/DemographicDataManagementFunction/FilteredDemographicData.cs b/application/CohortManager/src/Functions/DemographicServices/DemographicDataManagementFunction/FilteredDemographicData.cs new file mode 100644 index 000000000..03b516f9b --- /dev/null +++ b/application/CohortManager/src/Functions/DemographicServices/DemographicDataManagementFunction/FilteredDemographicData.cs @@ -0,0 +1,9 @@ +/// Demographic fields required in requests from the BI product. + +namespace NHS.CohortManager.DemographicServices; + +public class FilteredDemographicData +{ + public string? PrimaryCareProvider { get; set; } + public string? PreferredLanguage { get; set; } +} From c32c71a9f53779a0e1f8a872ab0ea3e644bebc8d Mon Sep 17 00:00:00 2001 From: will-larkin <160748088+will-larkin-nhs@users.noreply.github.com> Date: Mon, 23 Dec 2024 12:42:47 +0000 Subject: [PATCH 2/4] feat: documentation --- .../DemographicDataFunction.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/application/CohortManager/src/Functions/DemographicServices/DemographicDataManagementFunction/DemographicDataFunction.cs b/application/CohortManager/src/Functions/DemographicServices/DemographicDataManagementFunction/DemographicDataFunction.cs index a2574acb6..7dfc16f34 100644 --- a/application/CohortManager/src/Functions/DemographicServices/DemographicDataManagementFunction/DemographicDataFunction.cs +++ b/application/CohortManager/src/Functions/DemographicServices/DemographicDataManagementFunction/DemographicDataFunction.cs @@ -28,6 +28,13 @@ public async Task Run([HttpTrigger(AuthorizationLevel.Anonymou return await Main(req, false); } + + /// + /// Gets filtered demographic data from the demographic data service, + /// this endpoint is used by the external BI product + /// + /// The NHS number to get the demographic data for. + /// JSON response containing the Primary Care Provider & Preferred Language [Function("DemographicDataFunctionExternal")] public async Task RunExternal([HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequestData req) { From 21f01495edaa59bdea4f6d17fc78b20e36e4bdc6 Mon Sep 17 00:00:00 2001 From: will-larkin <160748088+will-larkin-nhs@users.noreply.github.com> Date: Fri, 10 Jan 2025 13:32:58 +0000 Subject: [PATCH 3/4] feat: tests --- .../DemographicDataFunctionTests.cs | 47 +++++++++++++++++-- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/tests/UnitTests/DemographicServicesTests/DemographicDataFunctionTests/DemographicDataFunctionTests.cs b/tests/UnitTests/DemographicServicesTests/DemographicDataFunctionTests/DemographicDataFunctionTests.cs index 413a4ad24..0e7258ae8 100644 --- a/tests/UnitTests/DemographicServicesTests/DemographicDataFunctionTests/DemographicDataFunctionTests.cs +++ b/tests/UnitTests/DemographicServicesTests/DemographicDataFunctionTests/DemographicDataFunctionTests.cs @@ -68,7 +68,7 @@ public DemographicDataFunctionTests() } [TestMethod] - public async Task Run_return_DemographicDataSavedPostRequest_OK() + public async Task RunPost_ValidRequest_ReturnOk() { // Arrange var json = JsonSerializer.Serialize(_participant); @@ -85,7 +85,7 @@ public async Task Run_return_DemographicDataSavedPostRequest_OK() } [TestMethod] - public async Task Run_return_DemographicDataSavedPostRequest_InternalServerEver() + public async Task RunPost_DataServiceReturns500_ReturnInternalServerError() { // Arrange var json = JsonSerializer.Serialize(_participant); @@ -105,7 +105,7 @@ public async Task Run_return_DemographicDataSavedPostRequest_InternalServerEver( } [TestMethod] - public async Task Run_return_DemographicDataGetRequest_OK() + public async Task RunGet_ValidRequest_ReturnOk() { // Arrange var json = JsonSerializer.Serialize(_participant); @@ -157,7 +157,7 @@ public async Task Run_return_DemographicDataNotSaved_InternalServerError() } [TestMethod] - public async Task Run_Return_DemographicFunctionThrows_InternalServerError() + public async Task RunPost_CallFunctionThrowsError_ReturnInternalServerError() { // Arrange var json = JsonSerializer.Serialize(_participant); @@ -193,4 +193,43 @@ public async Task Run_Return_DemographicFunctionThrows_InternalServerError() (Func)It.IsAny() )); } + + [TestMethod] + public async Task RunExternal_ValidRequest_ReturnFilteredDemographicData() + { + // Arrange + var json = JsonSerializer.Serialize(_participant); + + _request = _setupRequest.Setup(json); + + FilteredDemographicData DataServiceResponse = new() + { + PrimaryCareProvider = "Blerg", + PreferredLanguage = "Francais" + }; + + string serialisedResponse = JsonSerializer.Serialize(DataServiceResponse); + + _request.Setup(x => x.Query).Returns(new System.Collections.Specialized.NameValueCollection() { { "Id", "1" } }); + + _callFunction.Setup(call => call.SendGet(It.IsAny())) + .ReturnsAsync(serialisedResponse); + + _request.Setup(r => r.Method).Returns("GET"); + var sut = new DemographicDataFunction(_logger.Object, _createResponse.Object, _callFunction.Object); + + // Act + var result = await sut.RunExternal(_request.Object); + + // var demographicData = JsonSerializer.Deserialize(result.Body.ReadAsync()); + + string responseBody; + using (var reader = new StreamReader(result.Body)) + { + responseBody = await reader.ReadToEndAsync(); + } + + // Assert + Assert.AreEqual(serialisedResponse, responseBody); + } } From 721ff1bce28c352f0e4a45709d4733bcdc5d2206 Mon Sep 17 00:00:00 2001 From: will-larkin <160748088+will-larkin-nhs@users.noreply.github.com> Date: Tue, 14 Jan 2025 11:06:02 +0000 Subject: [PATCH 4/4] Update DemographicDataFunctionTests.cs --- .../DemographicDataFunctionTests.cs | 46 ++++++++----------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/tests/UnitTests/DemographicServicesTests/DemographicDataFunctionTests/DemographicDataFunctionTests.cs b/tests/UnitTests/DemographicServicesTests/DemographicDataFunctionTests/DemographicDataFunctionTests.cs index 3a12e8df0..92c425a42 100644 --- a/tests/UnitTests/DemographicServicesTests/DemographicDataFunctionTests/DemographicDataFunctionTests.cs +++ b/tests/UnitTests/DemographicServicesTests/DemographicDataFunctionTests/DemographicDataFunctionTests.cs @@ -17,7 +17,7 @@ public class DemographicDataFunctionTests { private readonly Mock> _logger = new(); private readonly Mock _createResponse = new(); - private readonly Mock _callFunction = new(); + private readonly Mock _callFunctionMock = new(); private readonly Mock _context = new(); private Mock _request; private readonly Mock _webResponse = new(); @@ -59,11 +59,11 @@ public DemographicDataFunctionTests() _webResponse.Setup(x => x.StatusCode).Returns(HttpStatusCode.OK); - _callFunction.Setup(call => call.SendPost(It.IsAny(), It.IsAny())) + _callFunctionMock.Setup(call => call.SendPost(It.IsAny(), It.IsAny())) .Returns(Task.FromResult(_webResponse.Object)); _webResponse.Setup(x => x.StatusCode).Returns(HttpStatusCode.OK); - _callFunction.Setup(call => call.SendGet(It.IsAny())) + _callFunctionMock.Setup(call => call.SendGet(It.IsAny())) .Returns(Task.FromResult("")); } @@ -72,7 +72,7 @@ public async Task RunPost_ValidRequest_ReturnOk() { // Arrange var json = JsonSerializer.Serialize(_participant); - var sut = new DemographicDataFunction(_logger.Object, _createResponse.Object, _callFunction.Object); + var sut = new DemographicDataFunction(_logger.Object, _createResponse.Object, _callFunctionMock.Object); _request = _setupRequest.Setup(json); @@ -89,11 +89,11 @@ public async Task RunPost_DataServiceReturns500_ReturnInternalServerError() { // Arrange var json = JsonSerializer.Serialize(_participant); - var sut = new DemographicDataFunction(_logger.Object, _createResponse.Object, _callFunction.Object); + var sut = new DemographicDataFunction(_logger.Object, _createResponse.Object, _callFunctionMock.Object); _request = _setupRequest.Setup(json); _webResponse.Setup(x => x.StatusCode).Returns(HttpStatusCode.InternalServerError); - _callFunction.Setup(call => call.SendPost(It.IsAny(), It.IsAny())) + _callFunctionMock.Setup(call => call.SendPost(It.IsAny(), It.IsAny())) .Returns(Task.FromResult(_webResponse.Object)); // Act @@ -109,14 +109,14 @@ public async Task RunGet_ValidRequest_ReturnOk() { // Arrange var json = JsonSerializer.Serialize(_participant); - var sut = new DemographicDataFunction(_logger.Object, _createResponse.Object, _callFunction.Object); + var sut = new DemographicDataFunction(_logger.Object, _createResponse.Object, _callFunctionMock.Object); _request = _setupRequest.Setup(json); // Act _request.Setup(x => x.Query).Returns(new System.Collections.Specialized.NameValueCollection() { { "Id", "1" } }); - _callFunction.Setup(call => call.SendGet(It.IsAny())) + _callFunctionMock.Setup(call => call.SendGet(It.IsAny())) .Returns(Task.FromResult("data")); @@ -132,7 +132,7 @@ public async Task Run_return_DemographicDataNotSaved_InternalServerError() { // Arrange var json = JsonSerializer.Serialize(_participant); - var sut = new DemographicDataFunction(_logger.Object, _createResponse.Object, _callFunction.Object); + var sut = new DemographicDataFunction(_logger.Object, _createResponse.Object, _callFunctionMock.Object); _request = _setupRequest.Setup(json); @@ -146,7 +146,7 @@ public async Task Run_return_DemographicDataNotSaved_InternalServerError() _webResponse.Setup(x => x.StatusCode).Returns(HttpStatusCode.InternalServerError); - _callFunction.Setup(call => call.SendPost(It.Is(s => s.Contains("DemographicDataFunctionURI")), It.IsAny())) + _callFunctionMock.Setup(call => call.SendPost(It.Is(s => s.Contains("DemographicDataFunctionURI")), It.IsAny())) .Returns(Task.FromResult(_webResponse.Object)); // Act @@ -161,7 +161,7 @@ public async Task RunPost_CallFunctionThrowsError_ReturnInternalServerError() { // Arrange var json = JsonSerializer.Serialize(_participant); - var sut = new DemographicDataFunction(_logger.Object, _createResponse.Object, _callFunction.Object); + var sut = new DemographicDataFunction(_logger.Object, _createResponse.Object, _callFunctionMock.Object); _request = _setupRequest.Setup(json); @@ -175,7 +175,7 @@ public async Task RunPost_CallFunctionThrowsError_ReturnInternalServerError() _webResponse.Setup(x => x.StatusCode).Returns(HttpStatusCode.InternalServerError); - _callFunction.Setup(call => call.SendPost(It.Is(s => s.Contains("DemographicDataFunctionURI")), It.IsAny())) + _callFunctionMock.Setup(call => call.SendPost(It.Is(s => s.Contains("DemographicDataFunctionURI")), It.IsAny())) .ThrowsAsync(new Exception("there was an error")); // Act @@ -195,41 +195,31 @@ public async Task RunPost_CallFunctionThrowsError_ReturnInternalServerError() } [TestMethod] - public async Task RunExternal_ValidRequest_ReturnFilteredDemographicData() + public async Task RunExternal_ValidRequest_ReturnOk() { // Arrange var json = JsonSerializer.Serialize(_participant); _request = _setupRequest.Setup(json); - FilteredDemographicData DataServiceResponse = new() + Demographic DataServiceResponse = new() { PrimaryCareProvider = "Blerg", PreferredLanguage = "Francais" }; - string serialisedResponse = JsonSerializer.Serialize(DataServiceResponse); - _request.Setup(x => x.Query).Returns(new System.Collections.Specialized.NameValueCollection() { { "Id", "1" } }); - _callFunction.Setup(call => call.SendGet(It.IsAny())) - .ReturnsAsync(serialisedResponse); + _callFunctionMock.Setup(call => call.SendGet(It.IsAny())) + .ReturnsAsync(JsonSerializer.Serialize(DataServiceResponse)); _request.Setup(r => r.Method).Returns("GET"); - var sut = new DemographicDataFunction(_logger.Object, _createResponse.Object, _callFunction.Object); + var sut = new DemographicDataFunction(_logger.Object, _createResponse.Object, _callFunctionMock.Object); // Act var result = await sut.RunExternal(_request.Object); - // var demographicData = JsonSerializer.Deserialize(result.Body.ReadAsync()); - - string responseBody; - using (var reader = new StreamReader(result.Body)) - { - responseBody = await reader.ReadToEndAsync(); - } - // Assert - Assert.AreEqual(serialisedResponse, responseBody); + Assert.AreEqual(HttpStatusCode.OK, result.StatusCode); } }