From 037ce094e3d9d7deae38b332cf7842f01623ced8 Mon Sep 17 00:00:00 2001 From: theanandankit Date: Wed, 13 Jan 2021 22:07:13 +0530 Subject: [PATCH 1/8] CORS filter fix --- .../openmrs/module/smartonfhir/web/filter/CORSFilter.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/omod/src/main/java/org/openmrs/module/smartonfhir/web/filter/CORSFilter.java b/omod/src/main/java/org/openmrs/module/smartonfhir/web/filter/CORSFilter.java index b77be23..d5da32f 100644 --- a/omod/src/main/java/org/openmrs/module/smartonfhir/web/filter/CORSFilter.java +++ b/omod/src/main/java/org/openmrs/module/smartonfhir/web/filter/CORSFilter.java @@ -29,12 +29,16 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse throws ServletException, IOException { // CORS "pre-flight" request response.addHeader("Access-Control-Allow-Credentials", "true"); - response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE"); + response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); response.addHeader("Access-Control-Allow-Headers", "Authorization"); response.addHeader("Access-Control-Allow-Headers", "Content-Type"); response.addHeader("Access-Control-Allow-Origin", "*"); response.addHeader("Access-Control-Max-Age", "1"); - filterChain.doFilter(request, response); + if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { + response.setStatus(HttpServletResponse.SC_OK); + } else { + filterChain.doFilter(request, response); + } } } From 9421ccb488b09ec74712e51c803c42ce04d0ad8a Mon Sep 17 00:00:00 2001 From: theanandankit Date: Wed, 13 Jan 2021 23:22:08 +0530 Subject: [PATCH 2/8] options methode added --- .../module/smartonfhir/web/filter/CORSFilter.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/omod/src/main/java/org/openmrs/module/smartonfhir/web/filter/CORSFilter.java b/omod/src/main/java/org/openmrs/module/smartonfhir/web/filter/CORSFilter.java index d5da32f..37ed35f 100644 --- a/omod/src/main/java/org/openmrs/module/smartonfhir/web/filter/CORSFilter.java +++ b/omod/src/main/java/org/openmrs/module/smartonfhir/web/filter/CORSFilter.java @@ -23,22 +23,23 @@ * To use this declare filter mapping in config.xml */ public class CORSFilter extends OncePerRequestFilter { - + @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) - throws ServletException, IOException { + throws ServletException, IOException { // CORS "pre-flight" request response.addHeader("Access-Control-Allow-Credentials", "true"); - response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); + response.addHeader("Access-Control-Allow-Methods", " OPTIONS"); response.addHeader("Access-Control-Allow-Headers", "Authorization"); response.addHeader("Access-Control-Allow-Headers", "Content-Type"); response.addHeader("Access-Control-Allow-Origin", "*"); response.addHeader("Access-Control-Max-Age", "1"); - + if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { response.setStatus(HttpServletResponse.SC_OK); - } else { - filterChain.doFilter(request, response); + return; } + + filterChain.doFilter(request, response); } } From bc964e9051aeb359da9ca6dd432b457594f05e09 Mon Sep 17 00:00:00 2001 From: theanandankit Date: Wed, 13 Jan 2021 23:27:42 +0530 Subject: [PATCH 3/8] Small change in CORSFilter --- .../openmrs/module/smartonfhir/web/filter/CORSFilter.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/omod/src/main/java/org/openmrs/module/smartonfhir/web/filter/CORSFilter.java b/omod/src/main/java/org/openmrs/module/smartonfhir/web/filter/CORSFilter.java index 37ed35f..ca2a453 100644 --- a/omod/src/main/java/org/openmrs/module/smartonfhir/web/filter/CORSFilter.java +++ b/omod/src/main/java/org/openmrs/module/smartonfhir/web/filter/CORSFilter.java @@ -23,10 +23,10 @@ * To use this declare filter mapping in config.xml */ public class CORSFilter extends OncePerRequestFilter { - + @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) - throws ServletException, IOException { + throws ServletException, IOException { // CORS "pre-flight" request response.addHeader("Access-Control-Allow-Credentials", "true"); response.addHeader("Access-Control-Allow-Methods", " OPTIONS"); @@ -34,12 +34,12 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response.addHeader("Access-Control-Allow-Headers", "Content-Type"); response.addHeader("Access-Control-Allow-Origin", "*"); response.addHeader("Access-Control-Max-Age", "1"); - + if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { response.setStatus(HttpServletResponse.SC_OK); return; } - + filterChain.doFilter(request, response); } } From 882bdc6b76000a6ae55cdea1bc2e47b352e72282 Mon Sep 17 00:00:00 2001 From: Ankit kumar <49350053+theanandankit@users.noreply.github.com> Date: Wed, 13 Jan 2021 23:44:41 +0530 Subject: [PATCH 4/8] Update CORSFilter.java --- .../org/openmrs/module/smartonfhir/web/filter/CORSFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/omod/src/main/java/org/openmrs/module/smartonfhir/web/filter/CORSFilter.java b/omod/src/main/java/org/openmrs/module/smartonfhir/web/filter/CORSFilter.java index ca2a453..fbff2f7 100644 --- a/omod/src/main/java/org/openmrs/module/smartonfhir/web/filter/CORSFilter.java +++ b/omod/src/main/java/org/openmrs/module/smartonfhir/web/filter/CORSFilter.java @@ -29,7 +29,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse throws ServletException, IOException { // CORS "pre-flight" request response.addHeader("Access-Control-Allow-Credentials", "true"); - response.addHeader("Access-Control-Allow-Methods", " OPTIONS"); + response.addHeader("Access-Control-Allow-Methods", "OPTIONS"); response.addHeader("Access-Control-Allow-Headers", "Authorization"); response.addHeader("Access-Control-Allow-Headers", "Content-Type"); response.addHeader("Access-Control-Allow-Origin", "*"); From caba4bfdc5582955ed216a685aa9b8e77bcc7dfc Mon Sep 17 00:00:00 2001 From: theanandankit Date: Sat, 16 Jan 2021 16:40:53 +0530 Subject: [PATCH 5/8] Update CORSFilter --- .../module/smartonfhir/web/filter/CORSFilter.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/omod/src/main/java/org/openmrs/module/smartonfhir/web/filter/CORSFilter.java b/omod/src/main/java/org/openmrs/module/smartonfhir/web/filter/CORSFilter.java index ca2a453..f1cf6d3 100644 --- a/omod/src/main/java/org/openmrs/module/smartonfhir/web/filter/CORSFilter.java +++ b/omod/src/main/java/org/openmrs/module/smartonfhir/web/filter/CORSFilter.java @@ -28,14 +28,16 @@ public class CORSFilter extends OncePerRequestFilter { protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // CORS "pre-flight" request - response.addHeader("Access-Control-Allow-Credentials", "true"); - response.addHeader("Access-Control-Allow-Methods", " OPTIONS"); - response.addHeader("Access-Control-Allow-Headers", "Authorization"); - response.addHeader("Access-Control-Allow-Headers", "Content-Type"); + response.addHeader("Access-Control-Allow-Origin", "*"); - response.addHeader("Access-Control-Max-Age", "1"); - if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { + if ("OPTIONS".equals(request.getMethod())) { + response.addHeader("Access-Control-Allow-Credentials", "true"); + response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE"); + response.addHeader("Access-Control-Allow-Headers", "Authorization"); + response.addHeader("Access-Control-Allow-Headers", "Content-Type"); + response.addHeader("Access-Control-Max-Age", "600"); + response.setStatus(HttpServletResponse.SC_OK); return; } From 029c4ec76a31c8f7511fb07e8632a1755452434b Mon Sep 17 00:00:00 2001 From: theanandankit Date: Tue, 4 Jan 2022 12:57:07 +0530 Subject: [PATCH 6/8] FM2-448: Add Unit Test for Servlets in SMART-on-FHIR --- .../servlet/SmartLaunchOptionSelected.java | 10 +- .../servlet/SmartAccessConfirmationTest.java | 128 ++++++++++++++++++ .../servlet/SmartAppSelectorServletTest.java | 92 +++++++++++++ .../servlet/SmartEhrLaunchServletTest.java | 96 +++++++++++++ .../SmartLaunchOptionSelectedTest.java | 121 +++++++++++++++++ pom.xml | 6 + 6 files changed, 451 insertions(+), 2 deletions(-) create mode 100644 omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartAccessConfirmationTest.java create mode 100644 omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartAppSelectorServletTest.java create mode 100644 omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartEhrLaunchServletTest.java create mode 100644 omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartLaunchOptionSelectedTest.java diff --git a/omod/src/main/java/org/openmrs/module/smartonfhir/web/servlet/SmartLaunchOptionSelected.java b/omod/src/main/java/org/openmrs/module/smartonfhir/web/servlet/SmartLaunchOptionSelected.java index c410e47..aa7a327 100644 --- a/omod/src/main/java/org/openmrs/module/smartonfhir/web/servlet/SmartLaunchOptionSelected.java +++ b/omod/src/main/java/org/openmrs/module/smartonfhir/web/servlet/SmartLaunchOptionSelected.java @@ -42,6 +42,12 @@ public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOExce String token = getParameter(req, "token"); String patientId = getParameter(req, "patientId"); String visitId = getParameter(req, "visitId"); + + if (token == null) { + res.sendError(HttpServletResponse.SC_BAD_REQUEST, "Couldn't found token in url"); + return; + } + String decodedUrl = URLDecoder.decode(token, StandardCharsets.UTF_8.name()); String jwtKeyToken = null; @@ -75,8 +81,8 @@ public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOExce return; } - if (token == null || (patientId == null && visitId == null)) { - res.sendError(HttpServletResponse.SC_BAD_REQUEST); + if (patientId == null && visitId == null) { + res.sendError(HttpServletResponse.SC_BAD_REQUEST, "PatientId must be provided"); return; } diff --git a/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartAccessConfirmationTest.java b/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartAccessConfirmationTest.java new file mode 100644 index 0000000..f951540 --- /dev/null +++ b/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartAccessConfirmationTest.java @@ -0,0 +1,128 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public License, + * v. 2.0. If a copy of the MPL was not distributed with this file, You can + * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under + * the terms of the Healthcare Disclaimer located at http://openmrs.org/license. + * + * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS + * graphic logo is a trademark of OpenMRS Inc. + */ +package org.openmrs.module.smartonfhir.web.servlet; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.notNullValue; +import static org.powermock.api.mockito.PowerMockito.doReturn; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; +import static org.powermock.api.mockito.PowerMockito.whenNew; + +import javax.crypto.spec.SecretKeySpec; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.User; +import org.openmrs.api.context.Context; +import org.openmrs.module.smartonfhir.model.SmartSession; +import org.openmrs.module.smartonfhir.util.SmartSecretKeyHolder; +import org.openmrs.module.smartonfhir.util.SmartSessionCache; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; + +@RunWith(PowerMockRunner.class) +@PowerMockIgnore("javax.crypto.*") +@PrepareForTest({ Context.class, SmartSessionCache.class, SmartAccessConfirmation.class, SecretKeySpec.class, + SmartSecretKeyHolder.class }) +public class SmartAccessConfirmationTest { + + private static final String TOKEN = "http://localhost:8180/auth/realms/openmrs/login-actions/action-token?key=abcd&app-token=%7BAPP_TOKEN%7D"; + + private static final byte[] SMART_SECRET_KEY_HOLDER = "SecretKey".getBytes(StandardCharsets.UTF_8); + + private static final String BASE_URL = "http://localhost:8180/auth/realms/openmrs/login-actions/action-token"; + + private static final String APP_TOKEN_VALUE = "eyJhbGciOiJIUzI1NiJ9.eyJwYXRpZW50IjoiNDU2IiwidmlzaXQiOiI3ODkifQ.XujZXboXbmJ5ZOgmWg6ihX8kN1Vf2XaZO0RQMBlOygA"; + + private static final String LAUNCH_ID = "12345"; + + private static final String USER_UUID = "123"; + + private static final String PATIENT_UUID = "456"; + + private static final String VISIT_UUID = "789"; + + private MockHttpServletRequest request; + + private MockHttpServletResponse response; + + @Mock + private SmartSessionCache smartSessionCache; + + private SmartSession smartSession; + + private User user; + + private SmartAccessConfirmation smartAccessConfirmation; + + @Before + public void setup() throws Exception { + request = new MockHttpServletRequest(); + response = new MockHttpServletResponse(); + user = new User(); + smartSession = new SmartSession(); + smartAccessConfirmation = new SmartAccessConfirmation(); + + smartSession.setPatientUuid(PATIENT_UUID); + smartSession.setVisitUuid(VISIT_UUID); + + request.setParameter("token", TOKEN); + request.setParameter("launch", LAUNCH_ID); + + user.setUuid(USER_UUID); + + mockStatic(Context.class); + mockStatic(SmartSecretKeyHolder.class); + + doReturn(user).when(Context.class, "getAuthenticatedUser"); + doReturn(SMART_SECRET_KEY_HOLDER).when(SmartSecretKeyHolder.class, "getSecretKey"); + + whenNew(SmartSessionCache.class).withNoArguments().thenReturn(smartSessionCache); + when(smartSessionCache.get(LAUNCH_ID)).thenReturn(smartSession); + } + + @Test + public void shouldReturnCorrectBaseURL() throws IOException { + smartAccessConfirmation.doGet(request, response); + + assertThat(response, notNullValue()); + assertThat(response.getRedirectedUrl(), notNullValue()); + assertThat(response.getRedirectedUrl().contains(BASE_URL), equalTo(true)); + } + + @Test + public void shouldContainsEveryQuery() throws IOException { + smartAccessConfirmation.doGet(request, response); + + assertThat(response, notNullValue()); + assertThat(response.getRedirectedUrl(), notNullValue()); + assertThat(response.getRedirectedUrl().contains("key="), equalTo(true)); + assertThat(response.getRedirectedUrl().contains("app-token="), equalTo(true)); + } + + @Test + public void shouldContainAppToken() throws IOException { + smartAccessConfirmation.doGet(request, response); + + assertThat(response, notNullValue()); + assertThat(response.getRedirectedUrl(), notNullValue()); + assertThat(response.getRedirectedUrl().contains(APP_TOKEN_VALUE), equalTo(true)); + } +} diff --git a/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartAppSelectorServletTest.java b/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartAppSelectorServletTest.java new file mode 100644 index 0000000..8f5ab21 --- /dev/null +++ b/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartAppSelectorServletTest.java @@ -0,0 +1,92 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public License, + * v. 2.0. If a copy of the MPL was not distributed with this file, You can + * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under + * the terms of the Healthcare Disclaimer located at http://openmrs.org/license. + * + * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS + * graphic logo is a trademark of OpenMRS Inc. + */ +package org.openmrs.module.smartonfhir.web.servlet; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.notNullValue; +import static org.powermock.api.mockito.PowerMockito.when; +import static org.powermock.api.mockito.PowerMockito.whenNew; + +import java.io.IOException; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.module.smartonfhir.util.FhirBaseAddressStrategy; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ SmartAppSelectorServlet.class, FhirBaseAddressStrategy.class }) +public class SmartAppSelectorServletTest { + + private static final String BASE_LAUNCH_ADDRESS_R4 = "http://127.0.0.1:9090/launch-standalone.html?iss=http://demo.org/openmrs/ws/fhir2/R4&launch="; + + private static final String BASE_LAUNCH_ADDRESS_R3 = "http://127.0.0.1:9090/launch-standalone.html?iss=http://demo.org/openmrs/ws/fhir2/R3&launch="; + + private static final String SMART_APP_BASE_URL = "http://127.0.0.1:9090/launch-standalone.html"; + + private MockHttpServletResponse response; + + private MockHttpServletRequest request; + + private SmartAppSelectorServlet smartAppSelectorServlet; + + @Mock + private FhirBaseAddressStrategy fhirBaseAddressStrategy; + + @Before + public void setup() throws Exception { + response = new MockHttpServletResponse(); + request = new MockHttpServletRequest(); + smartAppSelectorServlet = new SmartAppSelectorServlet(); + + whenNew(FhirBaseAddressStrategy.class).withNoArguments().thenReturn(fhirBaseAddressStrategy); + } + + @Test + public void shouldReturnCorrectSMARTAppBaseURLForR4() throws IOException { + when(fhirBaseAddressStrategy.getBaseSmartLaunchAddress(request)).thenReturn(BASE_LAUNCH_ADDRESS_R4); + + smartAppSelectorServlet.doGet(request, response); + + assertThat(response, notNullValue()); + assertThat(response.getRedirectedUrl(), notNullValue()); + assertThat(response.getRedirectedUrl().contains(SMART_APP_BASE_URL), equalTo(true)); + assertThat(response.getRedirectedUrl(), equalTo(BASE_LAUNCH_ADDRESS_R4)); + } + + @Test + public void shouldReturnCorrectSMARTAppBaseURLForR3() throws IOException { + when(fhirBaseAddressStrategy.getBaseSmartLaunchAddress(request)).thenReturn(BASE_LAUNCH_ADDRESS_R3); + + smartAppSelectorServlet.doGet(request, response); + + assertThat(response, notNullValue()); + assertThat(response.getRedirectedUrl(), notNullValue()); + assertThat(response.getRedirectedUrl().contains(SMART_APP_BASE_URL), equalTo(true)); + assertThat(response.getRedirectedUrl(), equalTo(BASE_LAUNCH_ADDRESS_R3)); + } + + @Test + public void shouldContainsEveryQuery() throws IOException { + when(fhirBaseAddressStrategy.getBaseSmartLaunchAddress(request)).thenReturn(BASE_LAUNCH_ADDRESS_R4); + + smartAppSelectorServlet.doGet(request, response); + + assertThat(response, notNullValue()); + assertThat(response.getRedirectedUrl(), notNullValue()); + assertThat(response.getRedirectedUrl().contains("iss="), equalTo(true)); + } +} diff --git a/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartEhrLaunchServletTest.java b/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartEhrLaunchServletTest.java new file mode 100644 index 0000000..a5b89af --- /dev/null +++ b/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartEhrLaunchServletTest.java @@ -0,0 +1,96 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public License, + * v. 2.0. If a copy of the MPL was not distributed with this file, You can + * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under + * the terms of the Healthcare Disclaimer located at http://openmrs.org/license. + * + * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS + * graphic logo is a trademark of OpenMRS Inc. + */ +package org.openmrs.module.smartonfhir.web.servlet; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.notNullValue; +import static org.powermock.api.mockito.PowerMockito.when; +import static org.powermock.api.mockito.PowerMockito.whenNew; + +import java.io.IOException; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.module.smartonfhir.util.FhirBaseAddressStrategy; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ SmartEhrLaunchServlet.class, FhirBaseAddressStrategy.class }) +public class SmartEhrLaunchServletTest { + + private static final String BASE_LAUNCH_ADDRESS = "http://127.0.0.1:9090/launch-standalone.html?iss=http://demo.org/openmrs/ws/fhir2/R4&launch="; + + private static final String PATIENT_UUID = "12345"; + + private static final String VISIT_UUID = "67890"; + + private static final String PATIENT_LAUNCH_CONTEXT = "patient"; + + private static final String VISIT_LAUNCH_CONTEXT = "encounter"; + + @Mock + private FhirBaseAddressStrategy fhirBaseAddressStrategy; + + private MockHttpServletResponse response; + + private MockHttpServletRequest request; + + private SmartEhrLaunchServlet servlet; + + @Before + public void setup() throws Exception { + request = new MockHttpServletRequest(); + response = new MockHttpServletResponse(); + servlet = new SmartEhrLaunchServlet(); + + request.setParameter("patientId", PATIENT_UUID); + request.setParameter("visitId", VISIT_UUID); + + whenNew(FhirBaseAddressStrategy.class).withNoArguments().thenReturn(fhirBaseAddressStrategy); + } + + @Test + public void shouldReturnCorrectURLForPatientContext() throws IOException { + when(fhirBaseAddressStrategy.getBaseSmartLaunchAddress(request)).thenReturn(BASE_LAUNCH_ADDRESS); + request.setParameter("launchContext", PATIENT_LAUNCH_CONTEXT); + + servlet.doGet(request, response); + + assertThat(response, notNullValue()); + assertThat(response.getRedirectedUrl(), notNullValue()); + assertThat(response.getRedirectedUrl().equals(BASE_LAUNCH_ADDRESS + PATIENT_UUID), equalTo(true)); + } + + public void shouldReturnCorrectURLForEncounterContext() throws IOException { + when(fhirBaseAddressStrategy.getBaseSmartLaunchAddress(request)).thenReturn(BASE_LAUNCH_ADDRESS); + request.setParameter("launchContext", VISIT_LAUNCH_CONTEXT); + + servlet.doGet(request, response); + + assertThat(response, notNullValue()); + assertThat(response.getRedirectedUrl(), notNullValue()); + assertThat(response.getRedirectedUrl().equals(BASE_LAUNCH_ADDRESS + VISIT_UUID), equalTo(true)); + } + + public void shouldReturnErrorWhenURLNotPresent() throws IOException { + when(fhirBaseAddressStrategy.getBaseSmartLaunchAddress(request)).thenReturn(""); + + servlet.doGet(request, response); + + assertThat(response, notNullValue()); + assertThat(response.getErrorMessage(), equalTo("A url must be provided")); + } +} diff --git a/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartLaunchOptionSelectedTest.java b/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartLaunchOptionSelectedTest.java new file mode 100644 index 0000000..bb95c21 --- /dev/null +++ b/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartLaunchOptionSelectedTest.java @@ -0,0 +1,121 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public License, + * v. 2.0. If a copy of the MPL was not distributed with this file, You can + * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under + * the terms of the Healthcare Disclaimer located at http://openmrs.org/license. + * + * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS + * graphic logo is a trademark of OpenMRS Inc. + */ +package org.openmrs.module.smartonfhir.web.servlet; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.notNullValue; +import static org.powermock.api.mockito.PowerMockito.doReturn; +import static org.powermock.api.mockito.PowerMockito.mockStatic; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openmrs.module.smartonfhir.util.SmartSecretKeyHolder; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; + +@RunWith(PowerMockRunner.class) +@PowerMockIgnore("javax.crypto.*") +@PrepareForTest({ SmartLaunchOptionSelected.class, SmartSecretKeyHolder.class }) +public class SmartLaunchOptionSelectedTest { + + private static final String TOKEN_ENCOUNTER = "http://localhost:8180/auth/realms/openmrs/login-actions/action-token?key=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIzNGQzMTk4Ny0zYjI0LTQ4MzMtOWUwZi1hMWExYTIxYzc5NDUifQ.eyJleHAiOjE2NDEwMTQ0NzAsImlhdCI6MTY0MTAxNDE3MCwianRpIjoiMTVjZDgxYzItMGM5Ni00MGI2LTkyZTUtNGM2Y2MyMWEzZDQ4IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MTgwL2F1dGgvcmVhbG1zL29wZW5tcnMiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjgxODAvYXV0aC9yZWFsbXMvb3Blbm1ycyIsInN1YiI6ImY6ZDllNTk0ZDItMWE5NC00YjNjLTkwZTQtODBhYmI5ODAzOTY4OjEiLCJ0eXAiOiJzbWFydC1wYXRpZW50LXNlbGVjdGlvbiIsIm5vbmNlIjoiMTVjZDgxYzItMGM5Ni00MGI2LTkyZTUtNGM2Y2MyMWEzZDQ4IiwiYXNpZCI6ImRmZTUwMTczLWE1NjQtNDE1ZS1hOGQzLTBiYjNmZDY4MGFkNy5VZDhUS2x2amJoNC45MzBkM2JkYS1iNTY4LTQ1YTItODgyZS05MGQxMTNjNjMxNzciLCJhc2lkIjoiZGZlNTAxNzMtYTU2NC00MTVlLWE4ZDMtMGJiM2ZkNjgwYWQ3LlVkOFRLbHZqYmg0LjkzMGQzYmRhLWI1NjgtNDVhMi04ODJlLTkwZDExM2M2MzE3NyIsInVzZXIiOiJleUpoYkdjaU9pSklVekkxTmlJc0luUjVjQ0lnT2lBaVNsZFVJbjAuZXlKbGVIQWlPakUyTkRFd01UUTBOekFzSW1semN5STZJbWgwZEhBNkx5OXNiMk5oYkdodmMzUTZPREU0TUM5aGRYUm9MM0psWVd4dGN5OXZjR1Z1YlhKeklpd2lZWFZrSWpvaWFIUjBjRG92TDJ4dlkyRnNhRzl6ZERvNE1EZ3dJaXdpYzNWaUlqb2lZV1J0YVc0aUxDSjBlWEFpT2lKemJXRnlkQzExYzJWeWJtRnRaUzEwYjJ0bGJpSXNJbUZ6YVdRaU9pSnpiV0Z5ZEVOc2FXVnVkQ0o5LmV0Wm5BN2JPZEpWWGR5dEhha1VCVEJPZ1BzLWg4WVBkV3hyUDRWZl9fbWMiLCJsYXVuY2hUeXBlIjoiL3BhdGllbnQgL2VuY291bnRlciJ9.SyloT1oqNdLGCPdFTb4CjKQMrvO0Pjhv1vOp5YLaSrI&client_id=smartClient&tab_id=Ud8TKlvjbh4&execution=9e89e1f3-41cd-4d92-946c-d8f56e9af62a&app-token=%7BAPP_TOKEN%7D"; + + private static final String TOKEN_PATIENT = "http://localhost:8180/auth/realms/openmrs/login-actions/action-token?key=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJkZjJhYTBjMC0wMzFjLTQ5ZjItYTczMC1hYmM0Mjg2OTM1Y2UifQ.eyJleHAiOjE2NDEyNzIyNzIsImlhdCI6MTY0MTI3MTk3MiwianRpIjoiMjIwZDlmYWMtYjgyNi00ZjVhLWJmM2UtNDg4NmY3MjI3OWFiIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MTgwL2F1dGgvcmVhbG1zL29wZW5tcnMiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjgxODAvYXV0aC9yZWFsbXMvb3Blbm1ycyIsInN1YiI6ImY6ZDllNTk0ZDItMWE5NC00YjNjLTkwZTQtODBhYmI5ODAzOTY4OjEiLCJ0eXAiOiJzbWFydC1wYXRpZW50LXNlbGVjdGlvbiIsIm5vbmNlIjoiMjIwZDlmYWMtYjgyNi00ZjVhLWJmM2UtNDg4NmY3MjI3OWFiIiwiYXNpZCI6IjcwZmU4ODNjLWVhNGUtNGRmNy1iYmI5LWU0MTdjNGVlOWI5OS5JOUlhSEFGWFBaMC45MzBkM2JkYS1iNTY4LTQ1YTItODgyZS05MGQxMTNjNjMxNzciLCJhc2lkIjoiNzBmZTg4M2MtZWE0ZS00ZGY3LWJiYjktZTQxN2M0ZWU5Yjk5Lkk5SWFIQUZYUFowLjkzMGQzYmRhLWI1NjgtNDVhMi04ODJlLTkwZDExM2M2MzE3NyIsInVzZXIiOiJleUpoYkdjaU9pSklVekkxTmlJc0luUjVjQ0lnT2lBaVNsZFVJbjAuZXlKbGVIQWlPakUyTkRFeU56SXlOeklzSW1semN5STZJbWgwZEhBNkx5OXNiMk5oYkdodmMzUTZPREU0TUM5aGRYUm9MM0psWVd4dGN5OXZjR1Z1YlhKeklpd2lZWFZrSWpvaWFIUjBjRG92TDJ4dlkyRnNhRzl6ZERvNE1EZ3dJaXdpYzNWaUlqb2lZV1J0YVc0aUxDSjBlWEFpT2lKemJXRnlkQzExYzJWeWJtRnRaUzEwYjJ0bGJpSXNJbUZ6YVdRaU9pSnpiV0Z5ZEVOc2FXVnVkQ0o5LnFoeHE1Z3Z1RERFcmNUbFYyY0lzOFpLSHpzd2VoZWkxRVlqZDNJR05mTk0iLCJsYXVuY2hUeXBlIjoiL3BhdGllbnQifQ.7rqOafcWeQhr0YGhG6cxrIrKUarDTxl3lb0dBi-Hjkk&client_id=smartClient&tab_id=Ud8TKlvjbh4&execution=9e89e1f3-41cd-4d92-946c-d8f56e9af62a&app-token=%7BAPP_TOKEN%7D"; + + private static final byte[] SMART_SECRET_KEY_HOLDER = "SecretKey".getBytes(StandardCharsets.UTF_8); + + private static final String PATIENT_UUID = "12345"; + + private static final String VISIT_UUID = "56789"; + + private MockHttpServletRequest request; + + private MockHttpServletResponse response; + + private SmartLaunchOptionSelected smartLaunchOptionSelected; + + @Before + public void setup() throws Exception { + request = new MockHttpServletRequest(); + response = new MockHttpServletResponse(); + smartLaunchOptionSelected = new SmartLaunchOptionSelected(); + + mockStatic(SmartSecretKeyHolder.class); + + doReturn(SMART_SECRET_KEY_HOLDER).when(SmartSecretKeyHolder.class, "getSecretKey"); + } + + @Test + public void shouldReturnCorrectURLWhenLaunchTypeIsEncounter() throws IOException { + request.setParameter("patientId", PATIENT_UUID); + request.setParameter("token", TOKEN_ENCOUNTER); + + smartLaunchOptionSelected.doGet(request, response); + + assertThat(response, notNullValue()); + assertThat(response.getRedirectedUrl(), notNullValue()); + assertThat(response.getRedirectedUrl().contains("app=smartonfhir.search.visit"), equalTo(true)); + assertThat(response.getRedirectedUrl().contains("patientId=12345"), equalTo(true)); + } + + @Test + public void shouldReturnCorrectURLWhenLaunchTypeIsPatient() throws IOException { + request.setParameter("patientId", PATIENT_UUID); + request.setParameter("token", TOKEN_PATIENT); + + smartLaunchOptionSelected.doGet(request, response); + + assertThat(response, notNullValue()); + assertThat(response.getRedirectedUrl(), notNullValue()); + assertThat(response.getRedirectedUrl().contains("key="), equalTo(true)); + assertThat(response.getRedirectedUrl().contains("app-token="), equalTo(true)); + } + + @Test + public void shouldReturnCorrectRedirectURlWhenLaunchTypeIsEncounter() throws IOException { + request.setParameter("token", TOKEN_ENCOUNTER); + request.setParameter("visitId", VISIT_UUID); + request.setParameter("patientId", PATIENT_UUID); + + smartLaunchOptionSelected.doGet(request, response); + + assertThat(response, notNullValue()); + assertThat(response.getRedirectedUrl(), notNullValue()); + assertThat(response.getRedirectedUrl().contains("key="), equalTo(true)); + assertThat(response.getRedirectedUrl().contains("app-token="), equalTo(true)); + } + + @Test + public void shouldThrowErrorWhenPatientAndVisitIdIsNull() throws IOException { + request.setParameter("token", TOKEN_PATIENT); + smartLaunchOptionSelected.doGet(request, response); + + assertThat(response, notNullValue()); + assertThat(response.getErrorMessage(), notNullValue()); + assertThat(response.getErrorMessage(), equalTo("PatientId must be provided")); + } + + @Test + public void shouldThrowErrorWhenTokenIsNull() throws IOException { + smartLaunchOptionSelected.doGet(request, response); + + assertThat(response, notNullValue()); + assertThat(response.getErrorMessage(), notNullValue()); + assertThat(response.getErrorMessage(), equalTo("Couldn't found token in url")); + } +} diff --git a/pom.xml b/pom.xml index d40f7b4..1937dbc 100644 --- a/pom.xml +++ b/pom.xml @@ -324,6 +324,12 @@ 1.28.0 provided + + com.fasterxml.jackson.core + jackson-databind + 2.7.3 + + From 1547912a1b6c26e745e1cd2d3121bb365e19f7e6 Mon Sep 17 00:00:00 2001 From: theanandankit Date: Sun, 16 Jan 2022 12:08:37 +0530 Subject: [PATCH 7/8] Refactoring --- .../web/servlet/SmartLaunchOptionSelected.java | 2 +- .../web/servlet/SmartAccessConfirmationTest.java | 9 +++++---- .../web/servlet/SmartAppSelectorServletTest.java | 9 +++++---- .../web/servlet/SmartEhrLaunchServletTest.java | 2 +- .../servlet/SmartLaunchOptionSelectedTest.java | 15 ++++++++------- pom.xml | 1 + 6 files changed, 21 insertions(+), 17 deletions(-) diff --git a/omod/src/main/java/org/openmrs/module/smartonfhir/web/servlet/SmartLaunchOptionSelected.java b/omod/src/main/java/org/openmrs/module/smartonfhir/web/servlet/SmartLaunchOptionSelected.java index aa7a327..a07aaa0 100644 --- a/omod/src/main/java/org/openmrs/module/smartonfhir/web/servlet/SmartLaunchOptionSelected.java +++ b/omod/src/main/java/org/openmrs/module/smartonfhir/web/servlet/SmartLaunchOptionSelected.java @@ -44,7 +44,7 @@ public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOExce String visitId = getParameter(req, "visitId"); if (token == null) { - res.sendError(HttpServletResponse.SC_BAD_REQUEST, "Couldn't found token in url"); + res.sendError(HttpServletResponse.SC_BAD_REQUEST, "Couldn't find token in url"); return; } diff --git a/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartAccessConfirmationTest.java b/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartAccessConfirmationTest.java index f951540..fd25e3d 100644 --- a/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartAccessConfirmationTest.java +++ b/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartAccessConfirmationTest.java @@ -10,11 +10,12 @@ package org.openmrs.module.smartonfhir.web.servlet; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.notNullValue; +import static org.mockito.Mockito.when; import static org.powermock.api.mockito.PowerMockito.doReturn; import static org.powermock.api.mockito.PowerMockito.mockStatic; -import static org.powermock.api.mockito.PowerMockito.when; import static org.powermock.api.mockito.PowerMockito.whenNew; import javax.crypto.spec.SecretKeySpec; @@ -104,7 +105,7 @@ public void shouldReturnCorrectBaseURL() throws IOException { assertThat(response, notNullValue()); assertThat(response.getRedirectedUrl(), notNullValue()); - assertThat(response.getRedirectedUrl().contains(BASE_URL), equalTo(true)); + assertThat(response.getRedirectedUrl(), containsString(BASE_URL)); } @Test @@ -113,8 +114,8 @@ public void shouldContainsEveryQuery() throws IOException { assertThat(response, notNullValue()); assertThat(response.getRedirectedUrl(), notNullValue()); - assertThat(response.getRedirectedUrl().contains("key="), equalTo(true)); - assertThat(response.getRedirectedUrl().contains("app-token="), equalTo(true)); + assertThat(response.getRedirectedUrl(), containsString("key=")); + assertThat(response.getRedirectedUrl(), containsString("app-token=")); } @Test diff --git a/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartAppSelectorServletTest.java b/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartAppSelectorServletTest.java index 8f5ab21..7dcb399 100644 --- a/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartAppSelectorServletTest.java +++ b/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartAppSelectorServletTest.java @@ -10,9 +10,10 @@ package org.openmrs.module.smartonfhir.web.servlet; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.notNullValue; -import static org.powermock.api.mockito.PowerMockito.when; +import static org.mockito.Mockito.when; import static org.powermock.api.mockito.PowerMockito.whenNew; import java.io.IOException; @@ -63,7 +64,7 @@ public void shouldReturnCorrectSMARTAppBaseURLForR4() throws IOException { assertThat(response, notNullValue()); assertThat(response.getRedirectedUrl(), notNullValue()); - assertThat(response.getRedirectedUrl().contains(SMART_APP_BASE_URL), equalTo(true)); + assertThat(response.getRedirectedUrl(), containsString(SMART_APP_BASE_URL)); assertThat(response.getRedirectedUrl(), equalTo(BASE_LAUNCH_ADDRESS_R4)); } @@ -75,7 +76,7 @@ public void shouldReturnCorrectSMARTAppBaseURLForR3() throws IOException { assertThat(response, notNullValue()); assertThat(response.getRedirectedUrl(), notNullValue()); - assertThat(response.getRedirectedUrl().contains(SMART_APP_BASE_URL), equalTo(true)); + assertThat(response.getRedirectedUrl(), containsString(SMART_APP_BASE_URL)); assertThat(response.getRedirectedUrl(), equalTo(BASE_LAUNCH_ADDRESS_R3)); } @@ -87,6 +88,6 @@ public void shouldContainsEveryQuery() throws IOException { assertThat(response, notNullValue()); assertThat(response.getRedirectedUrl(), notNullValue()); - assertThat(response.getRedirectedUrl().contains("iss="), equalTo(true)); + assertThat(response.getRedirectedUrl(), containsString("iss=")); } } diff --git a/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartEhrLaunchServletTest.java b/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartEhrLaunchServletTest.java index a5b89af..51613f6 100644 --- a/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartEhrLaunchServletTest.java +++ b/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartEhrLaunchServletTest.java @@ -12,7 +12,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.notNullValue; -import static org.powermock.api.mockito.PowerMockito.when; +import static org.mockito.Mockito.when; import static org.powermock.api.mockito.PowerMockito.whenNew; import java.io.IOException; diff --git a/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartLaunchOptionSelectedTest.java b/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartLaunchOptionSelectedTest.java index bb95c21..f4a9fac 100644 --- a/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartLaunchOptionSelectedTest.java +++ b/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartLaunchOptionSelectedTest.java @@ -10,6 +10,7 @@ package org.openmrs.module.smartonfhir.web.servlet; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.notNullValue; import static org.powermock.api.mockito.PowerMockito.doReturn; @@ -69,8 +70,8 @@ public void shouldReturnCorrectURLWhenLaunchTypeIsEncounter() throws IOException assertThat(response, notNullValue()); assertThat(response.getRedirectedUrl(), notNullValue()); - assertThat(response.getRedirectedUrl().contains("app=smartonfhir.search.visit"), equalTo(true)); - assertThat(response.getRedirectedUrl().contains("patientId=12345"), equalTo(true)); + assertThat(response.getRedirectedUrl(), containsString("app=smartonfhir.search.visit")); + assertThat(response.getRedirectedUrl(), containsString("patientId=12345")); } @Test @@ -82,8 +83,8 @@ public void shouldReturnCorrectURLWhenLaunchTypeIsPatient() throws IOException { assertThat(response, notNullValue()); assertThat(response.getRedirectedUrl(), notNullValue()); - assertThat(response.getRedirectedUrl().contains("key="), equalTo(true)); - assertThat(response.getRedirectedUrl().contains("app-token="), equalTo(true)); + assertThat(response.getRedirectedUrl(), containsString("key=")); + assertThat(response.getRedirectedUrl(), containsString("app-token=")); } @Test @@ -96,8 +97,8 @@ public void shouldReturnCorrectRedirectURlWhenLaunchTypeIsEncounter() throws IOE assertThat(response, notNullValue()); assertThat(response.getRedirectedUrl(), notNullValue()); - assertThat(response.getRedirectedUrl().contains("key="), equalTo(true)); - assertThat(response.getRedirectedUrl().contains("app-token="), equalTo(true)); + assertThat(response.getRedirectedUrl(), containsString("key=")); + assertThat(response.getRedirectedUrl(), containsString("app-token=")); } @Test @@ -116,6 +117,6 @@ public void shouldThrowErrorWhenTokenIsNull() throws IOException { assertThat(response, notNullValue()); assertThat(response.getErrorMessage(), notNullValue()); - assertThat(response.getErrorMessage(), equalTo("Couldn't found token in url")); + assertThat(response.getErrorMessage(), equalTo("Couldn't find token in url")); } } diff --git a/pom.xml b/pom.xml index 1937dbc..1f5af10 100644 --- a/pom.xml +++ b/pom.xml @@ -328,6 +328,7 @@ com.fasterxml.jackson.core jackson-databind 2.7.3 + provided From b22de3cfbfc30cdb9e453727c7c610b79d9d2aa7 Mon Sep 17 00:00:00 2001 From: theanandankit Date: Sat, 29 Jan 2022 23:52:29 +0530 Subject: [PATCH 8/8] Change the dependency from PowerMock to Mockito --- .../web/servlet/SmartEhrLaunchServlet.java | 5 ++ .../servlet/SmartAccessConfirmationTest.java | 48 ++++++++++--------- .../servlet/SmartAppSelectorServletTest.java | 36 +++++++++----- .../servlet/SmartEhrLaunchServletTest.java | 45 ++++++++++------- .../SmartLaunchOptionSelectedTest.java | 25 +++++----- 5 files changed, 97 insertions(+), 62 deletions(-) diff --git a/omod/src/main/java/org/openmrs/module/smartonfhir/web/servlet/SmartEhrLaunchServlet.java b/omod/src/main/java/org/openmrs/module/smartonfhir/web/servlet/SmartEhrLaunchServlet.java index 8155ff3..a618be2 100644 --- a/omod/src/main/java/org/openmrs/module/smartonfhir/web/servlet/SmartEhrLaunchServlet.java +++ b/omod/src/main/java/org/openmrs/module/smartonfhir/web/servlet/SmartEhrLaunchServlet.java @@ -37,6 +37,11 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO smartSession.setPatientUuid(patientId); smartSession.setVisitUuid(visitId); + if (launchContext == null) { + resp.sendError(HttpStatus.SC_BAD_REQUEST, "launchContext must be provided"); + return; + } + if (launchContext.equals("patient")) { url = url + patientId; smartSessionCache.put(patientId, smartSession); diff --git a/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartAccessConfirmationTest.java b/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartAccessConfirmationTest.java index fd25e3d..f2ceaf2 100644 --- a/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartAccessConfirmationTest.java +++ b/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartAccessConfirmationTest.java @@ -14,34 +14,27 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.notNullValue; import static org.mockito.Mockito.when; -import static org.powermock.api.mockito.PowerMockito.doReturn; -import static org.powermock.api.mockito.PowerMockito.mockStatic; -import static org.powermock.api.mockito.PowerMockito.whenNew; - -import javax.crypto.spec.SecretKeySpec; import java.io.IOException; import java.nio.charset.StandardCharsets; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Mock; +import org.mockito.MockedConstruction; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; import org.openmrs.User; import org.openmrs.api.context.Context; import org.openmrs.module.smartonfhir.model.SmartSession; import org.openmrs.module.smartonfhir.util.SmartSecretKeyHolder; import org.openmrs.module.smartonfhir.util.SmartSessionCache; -import org.powermock.core.classloader.annotations.PowerMockIgnore; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; -@RunWith(PowerMockRunner.class) -@PowerMockIgnore("javax.crypto.*") -@PrepareForTest({ Context.class, SmartSessionCache.class, SmartAccessConfirmation.class, SecretKeySpec.class, - SmartSecretKeyHolder.class }) +@RunWith(MockitoJUnitRunner.class) public class SmartAccessConfirmationTest { private static final String TOKEN = "http://localhost:8180/auth/realms/openmrs/login-actions/action-token?key=abcd&app-token=%7BAPP_TOKEN%7D"; @@ -64,15 +57,18 @@ public class SmartAccessConfirmationTest { private MockHttpServletResponse response; - @Mock - private SmartSessionCache smartSessionCache; - private SmartSession smartSession; private User user; private SmartAccessConfirmation smartAccessConfirmation; + private MockedStatic contextMockedStatic; + + private MockedStatic smartSecretKeyHolderMockedStatic; + + private MockedConstruction smartSessionCacheMockedConstruction; + @Before public void setup() throws Exception { request = new MockHttpServletRequest(); @@ -89,14 +85,22 @@ public void setup() throws Exception { user.setUuid(USER_UUID); - mockStatic(Context.class); - mockStatic(SmartSecretKeyHolder.class); + contextMockedStatic = Mockito.mockStatic(Context.class); + smartSecretKeyHolderMockedStatic = Mockito.mockStatic(SmartSecretKeyHolder.class); + smartSessionCacheMockedConstruction = Mockito.mockConstruction(SmartSessionCache.class, (mock, context) -> { + when(mock.get(LAUNCH_ID)).thenReturn(smartSession); + }); - doReturn(user).when(Context.class, "getAuthenticatedUser"); - doReturn(SMART_SECRET_KEY_HOLDER).when(SmartSecretKeyHolder.class, "getSecretKey"); + contextMockedStatic.when(Context::getAuthenticatedUser).thenReturn(user); + smartSecretKeyHolderMockedStatic.when(SmartSecretKeyHolder::getSecretKey).thenReturn(SMART_SECRET_KEY_HOLDER); - whenNew(SmartSessionCache.class).withNoArguments().thenReturn(smartSessionCache); - when(smartSessionCache.get(LAUNCH_ID)).thenReturn(smartSession); + } + + @After + public void close() { + contextMockedStatic.close(); + smartSecretKeyHolderMockedStatic.close(); + smartSessionCacheMockedConstruction.close(); } @Test diff --git a/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartAppSelectorServletTest.java b/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartAppSelectorServletTest.java index 7dcb399..22c8900 100644 --- a/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartAppSelectorServletTest.java +++ b/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartAppSelectorServletTest.java @@ -14,22 +14,21 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.notNullValue; import static org.mockito.Mockito.when; -import static org.powermock.api.mockito.PowerMockito.whenNew; import java.io.IOException; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Mock; +import org.mockito.MockedConstruction; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; import org.openmrs.module.smartonfhir.util.FhirBaseAddressStrategy; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; -@RunWith(PowerMockRunner.class) -@PrepareForTest({ SmartAppSelectorServlet.class, FhirBaseAddressStrategy.class }) +@RunWith(MockitoJUnitRunner.class) public class SmartAppSelectorServletTest { private static final String BASE_LAUNCH_ADDRESS_R4 = "http://127.0.0.1:9090/launch-standalone.html?iss=http://demo.org/openmrs/ws/fhir2/R4&launch="; @@ -44,21 +43,26 @@ public class SmartAppSelectorServletTest { private SmartAppSelectorServlet smartAppSelectorServlet; - @Mock - private FhirBaseAddressStrategy fhirBaseAddressStrategy; + private MockedConstruction fhirBaseAddressStrategyMockedConstruction; @Before public void setup() throws Exception { response = new MockHttpServletResponse(); request = new MockHttpServletRequest(); smartAppSelectorServlet = new SmartAppSelectorServlet(); - - whenNew(FhirBaseAddressStrategy.class).withNoArguments().thenReturn(fhirBaseAddressStrategy); + } + + @After + public void close() { + fhirBaseAddressStrategyMockedConstruction.close(); } @Test public void shouldReturnCorrectSMARTAppBaseURLForR4() throws IOException { - when(fhirBaseAddressStrategy.getBaseSmartLaunchAddress(request)).thenReturn(BASE_LAUNCH_ADDRESS_R4); + fhirBaseAddressStrategyMockedConstruction = Mockito.mockConstruction(FhirBaseAddressStrategy.class, + (mock, context) -> { + when(mock.getBaseSmartLaunchAddress(request)).thenReturn(BASE_LAUNCH_ADDRESS_R4); + }); smartAppSelectorServlet.doGet(request, response); @@ -70,7 +74,10 @@ public void shouldReturnCorrectSMARTAppBaseURLForR4() throws IOException { @Test public void shouldReturnCorrectSMARTAppBaseURLForR3() throws IOException { - when(fhirBaseAddressStrategy.getBaseSmartLaunchAddress(request)).thenReturn(BASE_LAUNCH_ADDRESS_R3); + fhirBaseAddressStrategyMockedConstruction = Mockito.mockConstruction(FhirBaseAddressStrategy.class, + (mock, context) -> { + when(mock.getBaseSmartLaunchAddress(request)).thenReturn(BASE_LAUNCH_ADDRESS_R3); + }); smartAppSelectorServlet.doGet(request, response); @@ -82,7 +89,10 @@ public void shouldReturnCorrectSMARTAppBaseURLForR3() throws IOException { @Test public void shouldContainsEveryQuery() throws IOException { - when(fhirBaseAddressStrategy.getBaseSmartLaunchAddress(request)).thenReturn(BASE_LAUNCH_ADDRESS_R4); + fhirBaseAddressStrategyMockedConstruction = Mockito.mockConstruction(FhirBaseAddressStrategy.class, + (mock, context) -> { + when(mock.getBaseSmartLaunchAddress(request)).thenReturn(BASE_LAUNCH_ADDRESS_R4); + }); smartAppSelectorServlet.doGet(request, response); diff --git a/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartEhrLaunchServletTest.java b/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartEhrLaunchServletTest.java index 51613f6..5c68589 100644 --- a/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartEhrLaunchServletTest.java +++ b/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartEhrLaunchServletTest.java @@ -13,22 +13,21 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.notNullValue; import static org.mockito.Mockito.when; -import static org.powermock.api.mockito.PowerMockito.whenNew; import java.io.IOException; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Mock; +import org.mockito.MockedConstruction; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; import org.openmrs.module.smartonfhir.util.FhirBaseAddressStrategy; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; -@RunWith(PowerMockRunner.class) -@PrepareForTest({ SmartEhrLaunchServlet.class, FhirBaseAddressStrategy.class }) +@RunWith(MockitoJUnitRunner.class) public class SmartEhrLaunchServletTest { private static final String BASE_LAUNCH_ADDRESS = "http://127.0.0.1:9090/launch-standalone.html?iss=http://demo.org/openmrs/ws/fhir2/R4&launch="; @@ -41,15 +40,14 @@ public class SmartEhrLaunchServletTest { private static final String VISIT_LAUNCH_CONTEXT = "encounter"; - @Mock - private FhirBaseAddressStrategy fhirBaseAddressStrategy; - private MockHttpServletResponse response; private MockHttpServletRequest request; private SmartEhrLaunchServlet servlet; + private MockedConstruction fhirBaseAddressStrategyMockedConstruction; + @Before public void setup() throws Exception { request = new MockHttpServletRequest(); @@ -58,13 +56,19 @@ public void setup() throws Exception { request.setParameter("patientId", PATIENT_UUID); request.setParameter("visitId", VISIT_UUID); - - whenNew(FhirBaseAddressStrategy.class).withNoArguments().thenReturn(fhirBaseAddressStrategy); + } + + @After + public void close() { + fhirBaseAddressStrategyMockedConstruction.close(); } @Test public void shouldReturnCorrectURLForPatientContext() throws IOException { - when(fhirBaseAddressStrategy.getBaseSmartLaunchAddress(request)).thenReturn(BASE_LAUNCH_ADDRESS); + fhirBaseAddressStrategyMockedConstruction = Mockito.mockConstruction(FhirBaseAddressStrategy.class, + (mock, context) -> { + when(mock.getBaseSmartLaunchAddress(request)).thenReturn(BASE_LAUNCH_ADDRESS); + }); request.setParameter("launchContext", PATIENT_LAUNCH_CONTEXT); servlet.doGet(request, response); @@ -74,8 +78,12 @@ public void shouldReturnCorrectURLForPatientContext() throws IOException { assertThat(response.getRedirectedUrl().equals(BASE_LAUNCH_ADDRESS + PATIENT_UUID), equalTo(true)); } + @Test public void shouldReturnCorrectURLForEncounterContext() throws IOException { - when(fhirBaseAddressStrategy.getBaseSmartLaunchAddress(request)).thenReturn(BASE_LAUNCH_ADDRESS); + fhirBaseAddressStrategyMockedConstruction = Mockito.mockConstruction(FhirBaseAddressStrategy.class, + (mock, context) -> { + when(mock.getBaseSmartLaunchAddress(request)).thenReturn(BASE_LAUNCH_ADDRESS); + }); request.setParameter("launchContext", VISIT_LAUNCH_CONTEXT); servlet.doGet(request, response); @@ -85,12 +93,17 @@ public void shouldReturnCorrectURLForEncounterContext() throws IOException { assertThat(response.getRedirectedUrl().equals(BASE_LAUNCH_ADDRESS + VISIT_UUID), equalTo(true)); } - public void shouldReturnErrorWhenURLNotPresent() throws IOException { - when(fhirBaseAddressStrategy.getBaseSmartLaunchAddress(request)).thenReturn(""); + @Test + public void shouldReturnErrorWhenLaunchContextNotPresent() throws IOException { + fhirBaseAddressStrategyMockedConstruction = Mockito.mockConstruction(FhirBaseAddressStrategy.class, + (mock, context) -> { + when(mock.getBaseSmartLaunchAddress(request)).thenReturn(BASE_LAUNCH_ADDRESS); + }); servlet.doGet(request, response); assertThat(response, notNullValue()); - assertThat(response.getErrorMessage(), equalTo("A url must be provided")); + assertThat(response.getErrorMessage(), equalTo("launchContext must be provided")); } + } diff --git a/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartLaunchOptionSelectedTest.java b/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartLaunchOptionSelectedTest.java index f4a9fac..15d3e2d 100644 --- a/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartLaunchOptionSelectedTest.java +++ b/omod/src/test/java/org.openmrs.module.smartonfhir/web/servlet/SmartLaunchOptionSelectedTest.java @@ -13,25 +13,22 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.notNullValue; -import static org.powermock.api.mockito.PowerMockito.doReturn; -import static org.powermock.api.mockito.PowerMockito.mockStatic; import java.io.IOException; import java.nio.charset.StandardCharsets; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; import org.openmrs.module.smartonfhir.util.SmartSecretKeyHolder; -import org.powermock.core.classloader.annotations.PowerMockIgnore; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; -@RunWith(PowerMockRunner.class) -@PowerMockIgnore("javax.crypto.*") -@PrepareForTest({ SmartLaunchOptionSelected.class, SmartSecretKeyHolder.class }) +@RunWith(MockitoJUnitRunner.class) public class SmartLaunchOptionSelectedTest { private static final String TOKEN_ENCOUNTER = "http://localhost:8180/auth/realms/openmrs/login-actions/action-token?key=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIzNGQzMTk4Ny0zYjI0LTQ4MzMtOWUwZi1hMWExYTIxYzc5NDUifQ.eyJleHAiOjE2NDEwMTQ0NzAsImlhdCI6MTY0MTAxNDE3MCwianRpIjoiMTVjZDgxYzItMGM5Ni00MGI2LTkyZTUtNGM2Y2MyMWEzZDQ4IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MTgwL2F1dGgvcmVhbG1zL29wZW5tcnMiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjgxODAvYXV0aC9yZWFsbXMvb3Blbm1ycyIsInN1YiI6ImY6ZDllNTk0ZDItMWE5NC00YjNjLTkwZTQtODBhYmI5ODAzOTY4OjEiLCJ0eXAiOiJzbWFydC1wYXRpZW50LXNlbGVjdGlvbiIsIm5vbmNlIjoiMTVjZDgxYzItMGM5Ni00MGI2LTkyZTUtNGM2Y2MyMWEzZDQ4IiwiYXNpZCI6ImRmZTUwMTczLWE1NjQtNDE1ZS1hOGQzLTBiYjNmZDY4MGFkNy5VZDhUS2x2amJoNC45MzBkM2JkYS1iNTY4LTQ1YTItODgyZS05MGQxMTNjNjMxNzciLCJhc2lkIjoiZGZlNTAxNzMtYTU2NC00MTVlLWE4ZDMtMGJiM2ZkNjgwYWQ3LlVkOFRLbHZqYmg0LjkzMGQzYmRhLWI1NjgtNDVhMi04ODJlLTkwZDExM2M2MzE3NyIsInVzZXIiOiJleUpoYkdjaU9pSklVekkxTmlJc0luUjVjQ0lnT2lBaVNsZFVJbjAuZXlKbGVIQWlPakUyTkRFd01UUTBOekFzSW1semN5STZJbWgwZEhBNkx5OXNiMk5oYkdodmMzUTZPREU0TUM5aGRYUm9MM0psWVd4dGN5OXZjR1Z1YlhKeklpd2lZWFZrSWpvaWFIUjBjRG92TDJ4dlkyRnNhRzl6ZERvNE1EZ3dJaXdpYzNWaUlqb2lZV1J0YVc0aUxDSjBlWEFpT2lKemJXRnlkQzExYzJWeWJtRnRaUzEwYjJ0bGJpSXNJbUZ6YVdRaU9pSnpiV0Z5ZEVOc2FXVnVkQ0o5LmV0Wm5BN2JPZEpWWGR5dEhha1VCVEJPZ1BzLWg4WVBkV3hyUDRWZl9fbWMiLCJsYXVuY2hUeXBlIjoiL3BhdGllbnQgL2VuY291bnRlciJ9.SyloT1oqNdLGCPdFTb4CjKQMrvO0Pjhv1vOp5YLaSrI&client_id=smartClient&tab_id=Ud8TKlvjbh4&execution=9e89e1f3-41cd-4d92-946c-d8f56e9af62a&app-token=%7BAPP_TOKEN%7D"; @@ -50,15 +47,21 @@ public class SmartLaunchOptionSelectedTest { private SmartLaunchOptionSelected smartLaunchOptionSelected; + private MockedStatic smartSecretKeyHolderMockedStatic; + @Before public void setup() throws Exception { request = new MockHttpServletRequest(); response = new MockHttpServletResponse(); smartLaunchOptionSelected = new SmartLaunchOptionSelected(); + smartSecretKeyHolderMockedStatic = Mockito.mockStatic(SmartSecretKeyHolder.class); - mockStatic(SmartSecretKeyHolder.class); - - doReturn(SMART_SECRET_KEY_HOLDER).when(SmartSecretKeyHolder.class, "getSecretKey"); + smartSecretKeyHolderMockedStatic.when(SmartSecretKeyHolder::getSecretKey).thenReturn(SMART_SECRET_KEY_HOLDER); + } + + @After + public void close() { + smartSecretKeyHolderMockedStatic.close(); } @Test