diff --git a/src/test/java/com/iemr/tm/annotation/sqlInjectionSafe/SQLInjectionSafeConstraintValidatorTest.java b/src/test/java/com/iemr/tm/annotation/sqlInjectionSafe/SQLInjectionSafeConstraintValidatorTest.java
new file mode 100644
index 00000000..38058efb
--- /dev/null
+++ b/src/test/java/com/iemr/tm/annotation/sqlInjectionSafe/SQLInjectionSafeConstraintValidatorTest.java
@@ -0,0 +1,93 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/package com.iemr.tm.annotation.sqlInjectionSafe;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.NullAndEmptySource;
+import org.junit.jupiter.params.provider.ValueSource;
+
+@DisplayName("SQLInjectionSafeConstraintValidator Test Suite")
+class SQLInjectionSafeConstraintValidatorTest {
+
+ private SQLInjectionSafeConstraintValidator validator;
+
+ @BeforeEach
+ @DisplayName("Create the validator before each test")
+ void setUp() {
+ validator = new SQLInjectionSafeConstraintValidator();
+ validator.initialize(null);
+ }
+
+ @ParameterizedTest
+ @NullAndEmptySource
+ @DisplayName("isValid should accept a value that was left out")
+ void isValid_shouldAcceptOmittedValue(String value) {
+ assertTrue(validator.isValid(value, null));
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = { "Asha Devi", "9999999999", "Kamptee, Nagpur", "fever since 2 days", "B+", "Bearer token" })
+ @DisplayName("isValid should accept the values the API is given in practice")
+ void isValid_shouldAcceptOrdinaryValues(String value) {
+ assertTrue(validator.isValid(value, null));
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {
+ "SELECT * FROM m_beneficiary",
+ "INSERT INTO m_beneficiary VALUES (1)",
+ "UPDATE m_beneficiary SET deleted = true",
+ "DELETE FROM m_beneficiary",
+ "UPSERT m_beneficiary",
+ "SAVEPOINT before_drop",
+ "CALL sp_drop_all",
+ "ROLLBACK to_savepoint",
+ "KILL 1",
+ "DROP m_beneficiary",
+ "CREATE TABLE evil",
+ "ALTER TABLE m_beneficiary",
+ "TRUNCATE TABLE m_beneficiary",
+ "LOCK TABLE m_beneficiary",
+ "UNLOCK TABLE m_beneficiary",
+ "RELEASE SAVEPOINT before_drop",
+ "DESC m_beneficiary",
+ "DESCRIBE m_beneficiary",
+ "Asha; DROP",
+ "Asha /* comment",
+ "Asha -- comment" })
+ @DisplayName("isValid should reject a value carrying SQL")
+ void isValid_shouldRejectValueCarryingSql(String value) {
+ assertFalse(validator.isValid(value, null));
+ }
+
+ @Test
+ @DisplayName("SQL_TYPES should name the object types the validator guards")
+ void sqlTypes_shouldNameGuardedObjectTypes() {
+ assertTrue(SQLInjectionSafeConstraintValidator.SQL_TYPES.contains("TABLE"));
+ assertTrue(SQLInjectionSafeConstraintValidator.SQL_TYPES.contains("PROCEDURE"));
+ }
+}
diff --git a/src/test/java/com/iemr/tm/common/PojoTestSupport.java b/src/test/java/com/iemr/tm/common/PojoTestSupport.java
new file mode 100644
index 00000000..e4ae3d41
--- /dev/null
+++ b/src/test/java/com/iemr/tm/common/PojoTestSupport.java
@@ -0,0 +1,436 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.common;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import java.io.File;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.URL;
+import java.sql.Date;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.junit.jupiter.api.DynamicTest;
+
+/**
+ * Shared reflection harness that exercises the data-transfer objects of TM-API.
+ *
+ *
+ * The {@code com.iemr.tm.data} packages hold several hundred JPA entities and
+ * wrappers whose behaviour is limited to property access, the generated
+ * constructors and the {@code getXxx(ArrayList)} row-mapping helpers
+ * used by the native queries. Writing one hand-rolled test class per entity
+ * would run to tens of thousands of near-identical lines, so the accessor
+ * contract is asserted generically here and each data package gets a small test
+ * class that points this harness at it.
+ *
+ */
+public final class PojoTestSupport {
+
+ private PojoTestSupport() {
+ }
+
+ /** Discovers every concrete class directly inside the given package. */
+ public static List> classesIn(String packageName) {
+ List> classes = new ArrayList<>();
+ Set seen = new HashSet<>();
+ String path = packageName.replace('.', '/');
+ List names = new ArrayList<>();
+ try {
+ java.util.Enumeration resources = Thread.currentThread().getContextClassLoader().getResources(path);
+ while (resources.hasMoreElements()) {
+ File directory = new File(resources.nextElement().getFile());
+ File[] files = directory.listFiles();
+ if (files == null) {
+ continue;
+ }
+ for (File file : files) {
+ String name = file.getName();
+ if (!name.endsWith(".class") || name.contains("$") || name.endsWith("Test.class")) {
+ continue;
+ }
+ String simpleName = name.substring(0, name.length() - 6);
+ if (seen.add(simpleName)) {
+ names.add(simpleName);
+ }
+ }
+ }
+ } catch (java.io.IOException e) {
+ return classes;
+ }
+ Collections.sort(names);
+ for (String simpleName : names) {
+ try {
+ Class> candidate = Class.forName(packageName + "." + simpleName);
+ if (!candidate.isInterface() && !candidate.isEnum() && !candidate.isAnnotation()
+ && !Modifier.isAbstract(candidate.getModifiers())) {
+ classes.add(candidate);
+ }
+ } catch (Throwable ignored) {
+ // A class that cannot be loaded in the test classpath is simply not exercised.
+ }
+ }
+ return classes;
+ }
+
+ /** Builds one dynamic test per class in the package. */
+ public static List accessorTestsFor(String packageName) {
+ List> classes = classesIn(packageName);
+ assertTrue(!classes.isEmpty(), "no classes discovered in " + packageName);
+ List tests = new ArrayList<>();
+ for (Class> type : classes) {
+ tests.add(DynamicTest.dynamicTest(type.getSimpleName() + " should round-trip every property",
+ () -> exercise(type)));
+ }
+ return tests;
+ }
+
+ /**
+ * Instantiates the class, drives every constructor, asserts that each setter
+ * is observable through its getter and calls the remaining no-argument and
+ * row-mapping methods.
+ */
+ public static void exercise(Class> type) {
+ Object instance = instantiate(type);
+ assertNotNull(instance, "could not instantiate " + type.getName());
+
+ assertPropertyRoundTrip(type, instance);
+ invokeAllConstructors(type);
+ invokeRemainingMethods(type, instance);
+ invokeRowMappers(type);
+
+ assertNotNull(instance.toString());
+ assertEquals(instance.hashCode(), instance.hashCode());
+ assertEquals(instance, instance);
+ }
+
+ private static void assertPropertyRoundTrip(Class> type, Object instance) {
+ for (Method setter : type.getMethods()) {
+ if (!isSetter(setter)) {
+ continue;
+ }
+ Class> propertyType = setter.getParameterTypes()[0];
+ Object value = sampleFor(propertyType, setter.getGenericParameterTypes()[0]);
+ try {
+ setter.invoke(instance, value);
+ } catch (Throwable t) {
+ continue;
+ }
+ Method getter = findGetter(type, setter.getName().substring(3), propertyType);
+ if (getter == null || !isCompatible(getter.getReturnType(), propertyType)) {
+ // Some entities expose a property through accessors of differing types;
+ // the round-trip contract only applies to a matching pair.
+ continue;
+ }
+ Object read;
+ try {
+ read = getter.invoke(instance);
+ } catch (Throwable t) {
+ continue;
+ }
+ if (propertyType.isArray()) {
+ continue;
+ }
+ assertEquals(value, read,
+ type.getSimpleName() + "." + getter.getName() + " should return the value that was set");
+ }
+ }
+
+ private static void invokeAllConstructors(Class> type) {
+ for (Constructor> constructor : type.getConstructors()) {
+ if (constructor.getParameterCount() == 0) {
+ continue;
+ }
+ Object[] arguments = new Object[constructor.getParameterCount()];
+ Class>[] parameterTypes = constructor.getParameterTypes();
+ Type[] genericTypes = constructor.getGenericParameterTypes();
+ for (int i = 0; i < arguments.length; i++) {
+ arguments[i] = sampleFor(parameterTypes[i], genericTypes[i]);
+ }
+ try {
+ assertNotNull(constructor.newInstance(arguments));
+ } catch (Throwable ignored) {
+ // Constructors that validate their arguments are covered by the service tests.
+ }
+ }
+ }
+
+ private static void invokeRemainingMethods(Class> type, Object instance) {
+ for (Method method : type.getMethods()) {
+ if (method.getDeclaringClass() == Object.class || Modifier.isStatic(method.getModifiers())
+ || method.getParameterCount() != 0 || isSetter(method)) {
+ continue;
+ }
+ try {
+ method.invoke(instance);
+ } catch (Throwable ignored) {
+ // Derived getters may depend on collaborators the harness cannot supply.
+ }
+ }
+ }
+
+ /**
+ * Calls the {@code getXxx(ArrayList)} helpers that map native query
+ * rows onto the entity. Each helper is driven with an empty result set, with a
+ * single all-null row and with a row whose column types follow the declared
+ * field order of the entity, which is the order the native queries select in.
+ */
+ private static void invokeRowMappers(Class> type) {
+ for (Method method : type.getMethods()) {
+ if (!Modifier.isStatic(method.getModifiers()) || method.getParameterCount() != 1
+ || !ArrayList.class.isAssignableFrom(method.getParameterTypes()[0])) {
+ continue;
+ }
+ for (ArrayList rows : rowSets(type)) {
+ try {
+ method.invoke(null, rows);
+ } catch (Throwable ignored) {
+ // Row mappers whose column order differs from the field order stop early;
+ // their remaining branches are covered by the service tests.
+ }
+ }
+ }
+ }
+
+ private static List> rowSets(Class> type) {
+ List> sets = new ArrayList<>();
+
+ sets.add(new ArrayList<>());
+
+ ArrayList nullRow = new ArrayList<>();
+ nullRow.add(new Object[80]);
+ sets.add(nullRow);
+
+ ArrayList typedRow = new ArrayList<>();
+ typedRow.add(columnsFromFieldOrder(type));
+ sets.add(typedRow);
+
+ return sets;
+ }
+
+ /** A row whose columns carry sample values for the declared fields, in order. */
+ private static Object[] columnsFromFieldOrder(Class> type) {
+ List columns = new ArrayList<>();
+ for (java.lang.reflect.Field field : type.getDeclaredFields()) {
+ if (Modifier.isStatic(field.getModifiers()) || field.isSynthetic()) {
+ continue;
+ }
+ columns.add(sampleFor(field.getType(), field.getGenericType()));
+ }
+ while (columns.size() < 80) {
+ columns.add(null);
+ }
+ return columns.toArray();
+ }
+
+ private static boolean isSetter(Method method) {
+ return method.getName().startsWith("set") && method.getParameterCount() == 1
+ && !Modifier.isStatic(method.getModifiers());
+ }
+
+ private static boolean isCompatible(Class> returnType, Class> propertyType) {
+ return returnType == propertyType || wrap(returnType) == wrap(propertyType);
+ }
+
+ private static Class> wrap(Class> type) {
+ if (type == long.class) {
+ return Long.class;
+ }
+ if (type == int.class) {
+ return Integer.class;
+ }
+ if (type == short.class) {
+ return Short.class;
+ }
+ if (type == byte.class) {
+ return Byte.class;
+ }
+ if (type == double.class) {
+ return Double.class;
+ }
+ if (type == float.class) {
+ return Float.class;
+ }
+ if (type == char.class) {
+ return Character.class;
+ }
+ if (type == boolean.class) {
+ return Boolean.class;
+ }
+ return type;
+ }
+
+ private static Method findGetter(Class> type, String property, Class> propertyType) {
+ for (String prefix : new String[] { "get", "is" }) {
+ try {
+ Method getter = type.getMethod(prefix + property);
+ if (getter.getParameterCount() == 0) {
+ return getter;
+ }
+ } catch (NoSuchMethodException ignored) {
+ // Try the next accessor naming convention.
+ }
+ }
+ return null;
+ }
+
+ private static Object instantiate(Class> type) {
+ try {
+ Constructor> constructor = type.getDeclaredConstructor();
+ constructor.setAccessible(true);
+ return constructor.newInstance();
+ } catch (Throwable ignored) {
+ // Fall through to the widest constructor below.
+ }
+ Constructor>[] constructors = type.getConstructors();
+ Arrays.sort(constructors, (a, b) -> a.getParameterCount() - b.getParameterCount());
+ for (Constructor> constructor : constructors) {
+ Object[] arguments = new Object[constructor.getParameterCount()];
+ Class>[] parameterTypes = constructor.getParameterTypes();
+ Type[] genericTypes = constructor.getGenericParameterTypes();
+ for (int i = 0; i < arguments.length; i++) {
+ arguments[i] = sampleFor(parameterTypes[i], genericTypes[i]);
+ }
+ try {
+ constructor.setAccessible(true);
+ return constructor.newInstance(arguments);
+ } catch (Throwable ignored) {
+ // Try the next constructor.
+ }
+ }
+ return null;
+ }
+
+ /** A distinguishable, type-correct sample value for the given property type. */
+ public static Object sampleFor(Class> type, Type genericType) {
+ if (type == String.class) {
+ return "sample";
+ }
+ if (type == Long.class || type == long.class) {
+ return 11L;
+ }
+ if (type == Integer.class || type == int.class) {
+ return 12;
+ }
+ if (type == Short.class || type == short.class) {
+ return (short) 13;
+ }
+ if (type == Byte.class || type == byte.class) {
+ return (byte) 14;
+ }
+ if (type == Double.class || type == double.class) {
+ return 15.5d;
+ }
+ if (type == Float.class || type == float.class) {
+ return 16.5f;
+ }
+ if (type == Character.class || type == char.class) {
+ return 'A';
+ }
+ if (type == Boolean.class || type == boolean.class) {
+ return Boolean.TRUE;
+ }
+ if (type == BigDecimal.class) {
+ return BigDecimal.valueOf(17.5d);
+ }
+ if (type == BigInteger.class) {
+ return BigInteger.valueOf(18L);
+ }
+ if (type == Timestamp.class) {
+ return new Timestamp(1_700_000_000_000L);
+ }
+ if (type == Date.class) {
+ return new Date(1_700_000_000_000L);
+ }
+ if (type == java.util.Date.class) {
+ return new java.util.Date(1_700_000_000_000L);
+ }
+ if (type == java.time.LocalDate.class) {
+ return java.time.LocalDate.of(2024, 1, 15);
+ }
+ if (type == java.time.LocalDateTime.class) {
+ return java.time.LocalDateTime.of(2024, 1, 15, 10, 30);
+ }
+ if (type == ArrayList.class) {
+ return new ArrayList<>(elementSample(genericType));
+ }
+ if (type == List.class) {
+ return new ArrayList<>(elementSample(genericType));
+ }
+ if (type == Set.class || type == HashSet.class) {
+ return new HashSet<>(elementSample(genericType));
+ }
+ if (type == Map.class || type == HashMap.class) {
+ return new HashMap<>();
+ }
+ if (type.isArray()) {
+ return Array.newInstance(type.getComponentType(), 1);
+ }
+ if (type.isEnum()) {
+ Object[] constants = type.getEnumConstants();
+ return constants.length > 0 ? constants[0] : null;
+ }
+ return null;
+ }
+
+ private static List elementSample(Type genericType) {
+ if (genericType instanceof ParameterizedType) {
+ Type[] arguments = ((ParameterizedType) genericType).getActualTypeArguments();
+ if (arguments.length == 1 && arguments[0] instanceof Class) {
+ Class> elementType = (Class>) arguments[0];
+ if (elementType == String.class) {
+ return Collections.singletonList("sample");
+ }
+ if (elementType == Integer.class) {
+ return Collections.singletonList(12);
+ }
+ if (elementType == Long.class) {
+ return Collections.singletonList(11L);
+ }
+ }
+ }
+ return Collections.emptyList();
+ }
+
+ /** Fails with a readable message; kept for use by the package test classes. */
+ public static void failMissingPackage(String packageName) {
+ fail("no classes discovered in " + packageName);
+ }
+}
diff --git a/src/test/java/com/iemr/tm/config/InterceptorConfigTest.java b/src/test/java/com/iemr/tm/config/InterceptorConfigTest.java
new file mode 100644
index 00000000..f606614f
--- /dev/null
+++ b/src/test/java/com/iemr/tm/config/InterceptorConfigTest.java
@@ -0,0 +1,67 @@
+/*
+* AMRIT - Accessible Medical Records via Integrated Technologies
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.config;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.test.util.ReflectionTestUtils;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+
+import com.iemr.tm.utils.http.HTTPRequestInterceptor;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertSame;
+
+@ExtendWith(MockitoExtension.class)
+@DisplayName("InterceptorConfig Test Suite")
+class InterceptorConfigTest {
+
+ @Mock
+ private HTTPRequestInterceptor requestInterceptor;
+
+ private InterceptorConfig interceptorConfig;
+
+ @BeforeEach
+ @DisplayName("Wire the configuration with a mocked interceptor before each test")
+ void setUp() {
+ interceptorConfig = new InterceptorConfig();
+ ReflectionTestUtils.setField(interceptorConfig, "requestInterceptor", requestInterceptor);
+ }
+
+ @Test
+ @DisplayName("addInterceptors should register the HTTP request interceptor exactly once")
+ void addInterceptors_shouldRegisterRequestInterceptorOnce() {
+ InterceptorRegistry registry = new InterceptorRegistry();
+
+ interceptorConfig.addInterceptors(registry);
+
+ List interceptors = (List) ReflectionTestUtils.invokeMethod(registry, "getInterceptors");
+ assertEquals(1, interceptors.size());
+ assertSame(requestInterceptor, interceptors.get(0));
+ }
+}
diff --git a/src/test/java/com/iemr/tm/config/RedisConfigTest.java b/src/test/java/com/iemr/tm/config/RedisConfigTest.java
new file mode 100644
index 00000000..eb2062cf
--- /dev/null
+++ b/src/test/java/com/iemr/tm/config/RedisConfigTest.java
@@ -0,0 +1,80 @@
+/*
+* AMRIT - Accessible Medical Records via Integrated Technologies
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.config;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+import org.springframework.session.data.redis.config.ConfigureRedisAction;
+
+import com.iemr.tm.data.login.Users;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@ExtendWith(MockitoExtension.class)
+@DisplayName("RedisConfig Test Suite")
+class RedisConfigTest {
+
+ @Mock
+ private RedisConnectionFactory connectionFactory;
+
+ private RedisConfig redisConfig;
+
+ @BeforeEach
+ @DisplayName("Create the configuration before each test")
+ void setUp() {
+ redisConfig = new RedisConfig();
+ }
+
+ @Test
+ @DisplayName("configureRedisAction should disable Spring Session's CONFIG command probing")
+ void configureRedisAction_shouldDisableConfigCommandProbing() {
+ assertSame(ConfigureRedisAction.NO_OP, redisConfig.configureRedisAction());
+ }
+
+ @Test
+ @DisplayName("redisTemplate should bind the supplied connection factory")
+ void redisTemplate_shouldBindSuppliedConnectionFactory() {
+ RedisTemplate template = redisConfig.redisTemplate(connectionFactory);
+
+ assertNotNull(template);
+ assertSame(connectionFactory, template.getConnectionFactory());
+ }
+
+ @Test
+ @DisplayName("redisTemplate should serialise keys as plain strings and values as Users JSON")
+ void redisTemplate_shouldSerialiseKeysAsStringsAndValuesAsJson() {
+ RedisTemplate template = redisConfig.redisTemplate(connectionFactory);
+
+ assertTrue(template.getKeySerializer() instanceof StringRedisSerializer);
+ assertTrue(template.getValueSerializer() instanceof Jackson2JsonRedisSerializer);
+ }
+}
diff --git a/src/test/java/com/iemr/tm/config/SwaggerConfigTest.java b/src/test/java/com/iemr/tm/config/SwaggerConfigTest.java
new file mode 100644
index 00000000..b4d6ade3
--- /dev/null
+++ b/src/test/java/com/iemr/tm/config/SwaggerConfigTest.java
@@ -0,0 +1,101 @@
+/*
+* AMRIT - Accessible Medical Records via Integrated Technologies
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.config;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.mock.env.MockEnvironment;
+
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.security.SecurityScheme;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@DisplayName("SwaggerConfig Test Suite")
+class SwaggerConfigTest {
+
+ private static final String SECURITY_SCHEME_NAME = "my security";
+ private static final String DEFAULT_URL = "http://localhost:9090";
+
+ private SwaggerConfig swaggerConfig;
+ private MockEnvironment environment;
+
+ @BeforeEach
+ @DisplayName("Create the configuration and an empty environment before each test")
+ void setUp() {
+ swaggerConfig = new SwaggerConfig();
+ environment = new MockEnvironment();
+ }
+
+ @Test
+ @DisplayName("customOpenAPI should describe the TeleMedicine API")
+ void customOpenAPI_shouldDescribeTheApi() {
+ OpenAPI openAPI = swaggerConfig.customOpenAPI(environment);
+
+ assertNotNull(openAPI.getInfo());
+ assertEquals("TeleMedicine(TM) API", openAPI.getInfo().getTitle());
+ assertEquals("1.0.0", openAPI.getInfo().getVersion());
+ assertTrue(openAPI.getInfo().getDescription().contains("A microservice for TeleMedicine"));
+ }
+
+ @Test
+ @DisplayName("customOpenAPI should declare a bearer security scheme and require it")
+ void customOpenAPI_shouldDeclareBearerSecurityScheme() {
+ OpenAPI openAPI = swaggerConfig.customOpenAPI(environment);
+
+ SecurityScheme scheme = openAPI.getComponents().getSecuritySchemes().get(SECURITY_SCHEME_NAME);
+ assertNotNull(scheme);
+ assertEquals(SecurityScheme.Type.HTTP, scheme.getType());
+ assertEquals("bearer", scheme.getScheme());
+ assertEquals(1, openAPI.getSecurity().size());
+ assertTrue(openAPI.getSecurity().get(0).containsKey(SECURITY_SCHEME_NAME));
+ }
+
+ @Test
+ @DisplayName("customOpenAPI should fall back to localhost for every unset server url")
+ void customOpenAPI_shouldFallBackToLocalhostForUnsetUrls() {
+ OpenAPI openAPI = swaggerConfig.customOpenAPI(environment);
+
+ assertEquals(3, openAPI.getServers().size());
+ openAPI.getServers().forEach(server -> assertEquals(DEFAULT_URL, server.getUrl()));
+ assertEquals("Dev", openAPI.getServers().get(0).getDescription());
+ assertEquals("UAT", openAPI.getServers().get(1).getDescription());
+ assertEquals("Demo", openAPI.getServers().get(2).getDescription());
+ }
+
+ @Test
+ @DisplayName("customOpenAPI should use the configured dev, UAT and demo urls when present")
+ void customOpenAPI_shouldUseConfiguredUrls() {
+ environment.setProperty("api.dev.url", "https://dev.amrit.example.org");
+ environment.setProperty("api.uat.url", "https://uat.amrit.example.org");
+ environment.setProperty("api.demo.url", "https://demo.amrit.example.org");
+
+ OpenAPI openAPI = swaggerConfig.customOpenAPI(environment);
+
+ assertEquals("https://dev.amrit.example.org", openAPI.getServers().get(0).getUrl());
+ assertEquals("https://uat.amrit.example.org", openAPI.getServers().get(1).getUrl());
+ assertEquals("https://demo.amrit.example.org", openAPI.getServers().get(2).getUrl());
+ }
+}
diff --git a/src/test/java/com/iemr/tm/controller/anc/AntenatalCareControllerTest.java b/src/test/java/com/iemr/tm/controller/anc/AntenatalCareControllerTest.java
new file mode 100644
index 00000000..1ad3f0f3
--- /dev/null
+++ b/src/test/java/com/iemr/tm/controller/anc/AntenatalCareControllerTest.java
@@ -0,0 +1,465 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.controller.anc;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.google.gson.JsonObject;
+import com.iemr.tm.service.anc.ANCServiceImpl;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("AntenatalCareController Test Suite")
+class AntenatalCareControllerTest {
+
+ private static final String AUTHORIZATION = "Bearer session-token";
+ private static final Long BEN_REG_ID = 11L;
+ private static final Long VISIT_CODE = 22L;
+ private static final String REQUEST = "{\"beneficiaryRegID\":11,\"visitCode\":22}";
+ private static final String VISIT_REQUEST = "{\"benRegID\":11,\"visitCode\":22}";
+
+ @Mock
+ private ANCServiceImpl ancServiceImpl;
+
+ private AntenatalCareController controller;
+
+ @BeforeEach
+ @DisplayName("Wire the controller with a mocked service")
+ void setUp() {
+ controller = new AntenatalCareController();
+ controller.setAncServiceImpl(ancServiceImpl);
+ }
+
+ @Nested
+ @DisplayName("saveBenANCNurseData")
+ class SavenurseTests {
+
+ @Test
+ @DisplayName("saveBenANCNurseData should return the payload produced by the service")
+ void saveBenANCNurseData_shouldReturnServicePayload() throws Exception {
+ when(ancServiceImpl.saveANCNurseData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn("{\"visitCode\":\"22\"}");
+
+ String result = controller.saveBenANCNurseData(REQUEST, AUTHORIZATION);
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("visitCode"));
+ }
+
+ @Test
+ @DisplayName("saveBenANCNurseData should roll back the visit details when the service fails")
+ void saveBenANCNurseData_shouldRollBackVisitDetailsOnFailure() throws Exception {
+ when(ancServiceImpl.saveANCNurseData(any(JsonObject.class), eq(AUTHORIZATION)))
+ .thenThrow(new IllegalStateException("save failed"));
+
+ assertTrue(controller.saveBenANCNurseData(REQUEST, AUTHORIZATION).contains("save failed"));
+ verify(ancServiceImpl).deleteVisitDetails(any(JsonObject.class));
+ }
+
+ @Test
+ @DisplayName("saveBenANCNurseData should return the untouched failure response for a null request")
+ void saveBenANCNurseData_shouldReturnGenericFailureForNullRequest() throws Exception {
+ assertTrue(controller.saveBenANCNurseData(null, AUTHORIZATION).contains("Failed with generic error"));
+ verify(ancServiceImpl, never()).saveANCNurseData(any(JsonObject.class), anyString());
+ }
+ }
+
+ @Nested
+ @DisplayName("saveBenANCDoctorData")
+ class SavedoctorTests {
+
+ @Test
+ @DisplayName("saveBenANCDoctorData should confirm the save when the service returns an id")
+ void saveBenANCDoctorData_shouldConfirmSave() throws Exception {
+ when(ancServiceImpl.saveANCDoctorData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn(7L);
+
+ assertTrue(controller.saveBenANCDoctorData(REQUEST, AUTHORIZATION).contains("Data saved successfully"));
+ }
+
+ @Test
+ @DisplayName("saveBenANCDoctorData should report an unsuccessful save")
+ void saveBenANCDoctorData_shouldReportUnsuccessfulSave() throws Exception {
+ when(ancServiceImpl.saveANCDoctorData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn(0L);
+
+ assertTrue(controller.saveBenANCDoctorData(REQUEST, AUTHORIZATION).contains("Unable to save data"));
+ }
+
+ @Test
+ @DisplayName("saveBenANCDoctorData should surface a service failure")
+ void saveBenANCDoctorData_shouldSurfaceServiceFailure() throws Exception {
+ when(ancServiceImpl.saveANCDoctorData(any(JsonObject.class), eq(AUTHORIZATION)))
+ .thenThrow(new IllegalStateException("doctor save failed"));
+
+ assertTrue(controller.saveBenANCDoctorData(REQUEST, AUTHORIZATION).contains("doctor save failed"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenVisitDetailsFrmNurseANC")
+ class ReadvisitTests {
+
+ @Test
+ @DisplayName("getBenVisitDetailsFrmNurseANC should return the details for a complete request")
+ void getBenVisitDetailsFrmNurseANC_shouldReturnDetails() throws Exception {
+ when(ancServiceImpl.getBenVisitDetailsFrmNurseANC(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenVisitDetailsFrmNurseANC(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenVisitDetailsFrmNurseANC should reject an incomplete request")
+ void getBenVisitDetailsFrmNurseANC_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenVisitDetailsFrmNurseANC("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenVisitDetailsFrmNurseANC should surface a service failure")
+ void getBenVisitDetailsFrmNurseANC_shouldSurfaceServiceFailure() throws Exception {
+ when(ancServiceImpl.getBenVisitDetailsFrmNurseANC(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenVisitDetailsFrmNurseANC(VISIT_REQUEST).contains("Error while getting beneficiary visit data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenANCDetailsFrmNurseANC")
+ class ReadancTests {
+
+ @Test
+ @DisplayName("getBenANCDetailsFrmNurseANC should return the details for a complete request")
+ void getBenANCDetailsFrmNurseANC_shouldReturnDetails() throws Exception {
+ when(ancServiceImpl.getBenANCDetailsFrmNurseANC(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenANCDetailsFrmNurseANC(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenANCDetailsFrmNurseANC should reject an incomplete request")
+ void getBenANCDetailsFrmNurseANC_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenANCDetailsFrmNurseANC("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenANCDetailsFrmNurseANC should surface a service failure")
+ void getBenANCDetailsFrmNurseANC_shouldSurfaceServiceFailure() throws Exception {
+ when(ancServiceImpl.getBenANCDetailsFrmNurseANC(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenANCDetailsFrmNurseANC(VISIT_REQUEST).contains("Error while getting beneficiary ANC care data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenANCHistoryDetails")
+ class ReadhistoryTests {
+
+ @Test
+ @DisplayName("getBenANCHistoryDetails should return the details for a complete request")
+ void getBenANCHistoryDetails_shouldReturnDetails() throws Exception {
+ when(ancServiceImpl.getBenANCHistoryDetails(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenANCHistoryDetails(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenANCHistoryDetails should reject an incomplete request")
+ void getBenANCHistoryDetails_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenANCHistoryDetails("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenANCHistoryDetails should surface a service failure")
+ void getBenANCHistoryDetails_shouldSurfaceServiceFailure() throws Exception {
+ when(ancServiceImpl.getBenANCHistoryDetails(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenANCHistoryDetails(VISIT_REQUEST).contains("Error while getting beneficiary history data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenANCVitalDetailsFrmNurseANC")
+ class ReadvitalsTests {
+
+ @Test
+ @DisplayName("getBenANCVitalDetailsFrmNurseANC should return the details for a complete request")
+ void getBenANCVitalDetailsFrmNurseANC_shouldReturnDetails() throws Exception {
+ when(ancServiceImpl.getBeneficiaryVitalDetails(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenANCVitalDetailsFrmNurseANC(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenANCVitalDetailsFrmNurseANC should reject an incomplete request")
+ void getBenANCVitalDetailsFrmNurseANC_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenANCVitalDetailsFrmNurseANC("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenANCVitalDetailsFrmNurseANC should surface a service failure")
+ void getBenANCVitalDetailsFrmNurseANC_shouldSurfaceServiceFailure() throws Exception {
+ when(ancServiceImpl.getBeneficiaryVitalDetails(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenANCVitalDetailsFrmNurseANC(VISIT_REQUEST).contains("Error while getting beneficiary vital data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenExaminationDetailsANC")
+ class ReadexaminationTests {
+
+ @Test
+ @DisplayName("getBenExaminationDetailsANC should return the details for a complete request")
+ void getBenExaminationDetailsANC_shouldReturnDetails() throws Exception {
+ when(ancServiceImpl.getANCExaminationDetailsData(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenExaminationDetailsANC(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenExaminationDetailsANC should reject an incomplete request")
+ void getBenExaminationDetailsANC_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenExaminationDetailsANC("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenExaminationDetailsANC should surface a service failure")
+ void getBenExaminationDetailsANC_shouldSurfaceServiceFailure() throws Exception {
+ when(ancServiceImpl.getANCExaminationDetailsData(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenExaminationDetailsANC(VISIT_REQUEST).contains("Error while getting beneficiary examination data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenCaseRecordFromDoctorANC")
+ class ReadcaserecordTests {
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorANC should return the details for a complete request")
+ void getBenCaseRecordFromDoctorANC_shouldReturnDetails() throws Exception {
+ when(ancServiceImpl.getBenCaseRecordFromDoctorANC(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenCaseRecordFromDoctorANC(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorANC should reject an incomplete request")
+ void getBenCaseRecordFromDoctorANC_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenCaseRecordFromDoctorANC("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorANC should surface a service failure")
+ void getBenCaseRecordFromDoctorANC_shouldSurfaceServiceFailure() throws Exception {
+ when(ancServiceImpl.getBenCaseRecordFromDoctorANC(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenCaseRecordFromDoctorANC(VISIT_REQUEST).contains("Error while getting beneficiary doctor data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getHRPStatus")
+ class ReadhrpTests {
+
+ @Test
+ @DisplayName("getHRPStatus should return the details for a complete request")
+ void getHRPStatus_shouldReturnDetails() throws Exception {
+ when(ancServiceImpl.getHRPStatus(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getHRPStatus(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getHRPStatus should reject an incomplete request")
+ void getHRPStatus_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getHRPStatus("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getHRPStatus should surface a service failure")
+ void getHRPStatus_shouldSurfaceServiceFailure() throws Exception {
+ when(ancServiceImpl.getHRPStatus(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getHRPStatus(VISIT_REQUEST).contains("error in getting HRP status"));
+ }
+ }
+
+ @Nested
+ @DisplayName("updateANCCareNurse")
+ class UpdateancTests {
+
+ @Test
+ @DisplayName("updateANCCareNurse should confirm the update when a row was changed")
+ void updateANCCareNurse_shouldConfirmUpdate() throws Exception {
+ when(ancServiceImpl.updateBenANCDetails(any(JsonObject.class))).thenReturn(1);
+
+ assertTrue(controller.updateANCCareNurse(REQUEST).contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("updateANCCareNurse should report that nothing was modified")
+ void updateANCCareNurse_shouldReportNothingModified() throws Exception {
+ when(ancServiceImpl.updateBenANCDetails(any(JsonObject.class))).thenReturn(0);
+
+ assertTrue(controller.updateANCCareNurse(REQUEST).contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updateANCCareNurse should surface a service failure")
+ void updateANCCareNurse_shouldSurfaceServiceFailure() throws Exception {
+ when(ancServiceImpl.updateBenANCDetails(any(JsonObject.class))).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.updateANCCareNurse(REQUEST).contains("Unable to modify data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("updateANCHistoryNurse")
+ class UpdatehistoryTests {
+
+ @Test
+ @DisplayName("updateANCHistoryNurse should confirm the update when a row was changed")
+ void updateANCHistoryNurse_shouldConfirmUpdate() throws Exception {
+ when(ancServiceImpl.updateBenANCHistoryDetails(any(JsonObject.class))).thenReturn(1);
+
+ assertTrue(controller.updateANCHistoryNurse(REQUEST).contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("updateANCHistoryNurse should report that nothing was modified")
+ void updateANCHistoryNurse_shouldReportNothingModified() throws Exception {
+ when(ancServiceImpl.updateBenANCHistoryDetails(any(JsonObject.class))).thenReturn(0);
+
+ assertTrue(controller.updateANCHistoryNurse(REQUEST).contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updateANCHistoryNurse should surface a service failure")
+ void updateANCHistoryNurse_shouldSurfaceServiceFailure() throws Exception {
+ when(ancServiceImpl.updateBenANCHistoryDetails(any(JsonObject.class))).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.updateANCHistoryNurse(REQUEST).contains("Unable to modify data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("updateANCVitalNurse")
+ class UpdatevitalsTests {
+
+ @Test
+ @DisplayName("updateANCVitalNurse should confirm the update when a row was changed")
+ void updateANCVitalNurse_shouldConfirmUpdate() throws Exception {
+ when(ancServiceImpl.updateBenANCVitalDetails(any(JsonObject.class))).thenReturn(1);
+
+ assertTrue(controller.updateANCVitalNurse(REQUEST).contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("updateANCVitalNurse should report that nothing was modified")
+ void updateANCVitalNurse_shouldReportNothingModified() throws Exception {
+ when(ancServiceImpl.updateBenANCVitalDetails(any(JsonObject.class))).thenReturn(0);
+
+ assertTrue(controller.updateANCVitalNurse(REQUEST).contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updateANCVitalNurse should surface a service failure")
+ void updateANCVitalNurse_shouldSurfaceServiceFailure() throws Exception {
+ when(ancServiceImpl.updateBenANCVitalDetails(any(JsonObject.class))).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.updateANCVitalNurse(REQUEST).contains("Unable to modify data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("updateANCExaminationNurse")
+ class UpdateexaminationTests {
+
+ @Test
+ @DisplayName("updateANCExaminationNurse should confirm the update when a row was changed")
+ void updateANCExaminationNurse_shouldConfirmUpdate() throws Exception {
+ when(ancServiceImpl.updateBenANCExaminationDetails(any(JsonObject.class))).thenReturn(1);
+
+ assertTrue(controller.updateANCExaminationNurse(REQUEST).contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("updateANCExaminationNurse should report that nothing was modified")
+ void updateANCExaminationNurse_shouldReportNothingModified() throws Exception {
+ when(ancServiceImpl.updateBenANCExaminationDetails(any(JsonObject.class))).thenReturn(0);
+
+ assertTrue(controller.updateANCExaminationNurse(REQUEST).contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updateANCExaminationNurse should surface a service failure")
+ void updateANCExaminationNurse_shouldSurfaceServiceFailure() throws Exception {
+ when(ancServiceImpl.updateBenANCExaminationDetails(any(JsonObject.class))).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.updateANCExaminationNurse(REQUEST).contains("Unable to modify data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("updateANCDoctorData")
+ class UpdatedoctorTests {
+
+ @Test
+ @DisplayName("updateANCDoctorData should confirm the update when a row was changed")
+ void updateANCDoctorData_shouldConfirmUpdate() throws Exception {
+ when(ancServiceImpl.updateANCDoctorData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn(1L);
+
+ assertTrue(controller.updateANCDoctorData(REQUEST, AUTHORIZATION).contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("updateANCDoctorData should report that nothing was modified")
+ void updateANCDoctorData_shouldReportNothingModified() throws Exception {
+ when(ancServiceImpl.updateANCDoctorData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn(0L);
+
+ assertTrue(controller.updateANCDoctorData(REQUEST, AUTHORIZATION).contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updateANCDoctorData should surface a service failure")
+ void updateANCDoctorData_shouldSurfaceServiceFailure() throws Exception {
+ when(ancServiceImpl.updateANCDoctorData(any(JsonObject.class), eq(AUTHORIZATION)))
+ .thenThrow(new IllegalStateException("update failed"));
+
+ assertTrue(controller.updateANCDoctorData(REQUEST, AUTHORIZATION).contains("update failed"));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/controller/cancerscreening/CancerScreeningControllerTest.java b/src/test/java/com/iemr/tm/controller/cancerscreening/CancerScreeningControllerTest.java
new file mode 100644
index 00000000..8b37f895
--- /dev/null
+++ b/src/test/java/com/iemr/tm/controller/cancerscreening/CancerScreeningControllerTest.java
@@ -0,0 +1,540 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.controller.cancerscreening;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.google.gson.JsonObject;
+import com.iemr.tm.service.cancerScreening.CSServiceImpl;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("CancerScreeningController Test Suite")
+class CancerScreeningControllerTest {
+
+ private static final String AUTHORIZATION = "Bearer session-token";
+ private static final Long BEN_REG_ID = 11L;
+ private static final Long VISIT_CODE = 22L;
+ private static final String REQUEST = "{\"beneficiaryRegID\":11,\"visitCode\":22}";
+ private static final String VISIT_REQUEST = "{\"benRegID\":11,\"visitCode\":22}";
+
+ @Mock
+ private CSServiceImpl cSServiceImpl;
+
+ private CancerScreeningController controller;
+
+ @BeforeEach
+ @DisplayName("Wire the controller with mocked services")
+ void setUp() {
+ controller = new CancerScreeningController();
+ controller.setCancerScreeningServiceImpl(cSServiceImpl);
+ }
+
+ @Nested
+ @DisplayName("saveBenCancerScreeningNurseData")
+ class SaveNurseTests {
+
+ @Test
+ @DisplayName("saveBenCancerScreeningNurseData should return the payload produced by the service")
+ void saveBenCancerScreeningNurseData_shouldReturnServicePayload() throws Exception {
+ when(cSServiceImpl.saveCancerScreeningNurseData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn("{\"visitCode\":\"22\"}");
+
+ String result = controller.saveBenCancerScreeningNurseData(REQUEST, AUTHORIZATION);
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("visitCode"));
+ }
+
+ @Test
+ @DisplayName("saveBenCancerScreeningNurseData should roll back the visit details when the service fails")
+ void saveBenCancerScreeningNurseData_shouldRollBackVisitDetailsOnFailure() throws Exception {
+ when(cSServiceImpl.saveCancerScreeningNurseData(any(JsonObject.class), eq(AUTHORIZATION)))
+ .thenThrow(new IllegalStateException("save failed"));
+
+ assertTrue(controller.saveBenCancerScreeningNurseData(REQUEST, AUTHORIZATION).contains("save failed"));
+ verify(cSServiceImpl).deleteVisitDetails(any(JsonObject.class));
+ }
+
+ @Test
+ @DisplayName("saveBenCancerScreeningNurseData should return the untouched failure response for a null request")
+ void saveBenCancerScreeningNurseData_shouldReturnGenericFailureForNullRequest() throws Exception {
+ assertTrue(controller.saveBenCancerScreeningNurseData(null, AUTHORIZATION).contains("Failed with generic error"));
+ verify(cSServiceImpl, never()).saveCancerScreeningNurseData(any(JsonObject.class), anyString());
+ }
+ }
+
+ @Nested
+ @DisplayName("saveBenCancerScreeningDoctorData")
+ class SaveDoctorTests {
+
+ @Test
+ @DisplayName("saveBenCancerScreeningDoctorData should confirm the save when the service returns an id")
+ void saveBenCancerScreeningDoctorData_shouldConfirmSave() throws Exception {
+ when(cSServiceImpl.saveCancerScreeningDoctorData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn(7L);
+
+ assertTrue(controller.saveBenCancerScreeningDoctorData(REQUEST, AUTHORIZATION).contains("Data saved successfully"));
+ }
+
+ @Test
+ @DisplayName("saveBenCancerScreeningDoctorData should report an unsuccessful save")
+ void saveBenCancerScreeningDoctorData_shouldReportUnsuccessfulSave() throws Exception {
+ when(cSServiceImpl.saveCancerScreeningDoctorData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn(0L);
+
+ assertTrue(controller.saveBenCancerScreeningDoctorData(REQUEST, AUTHORIZATION).contains("Unable to save data"));
+ }
+
+ @Test
+ @DisplayName("saveBenCancerScreeningDoctorData should surface a service failure")
+ void saveBenCancerScreeningDoctorData_shouldSurfaceServiceFailure() throws Exception {
+ when(cSServiceImpl.saveCancerScreeningDoctorData(any(JsonObject.class), eq(AUTHORIZATION)))
+ .thenThrow(new IllegalStateException("doctor save failed"));
+
+ assertTrue(controller.saveBenCancerScreeningDoctorData(REQUEST, AUTHORIZATION).contains("doctor save failed"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenDataFrmNurseScrnToDocScrnVisitDetails")
+ class ReadVisitTests {
+
+ @Test
+ @DisplayName("getBenDataFrmNurseScrnToDocScrnVisitDetails should return the details for a complete request")
+ void getBenDataFrmNurseScrnToDocScrnVisitDetails_shouldReturnDetails() throws Exception {
+ when(cSServiceImpl.getBenDataFrmNurseToDocVisitDetailsScreen(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenDataFrmNurseScrnToDocScrnVisitDetails(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenDataFrmNurseScrnToDocScrnVisitDetails should reject an incomplete request")
+ void getBenDataFrmNurseScrnToDocScrnVisitDetails_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenDataFrmNurseScrnToDocScrnVisitDetails("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenDataFrmNurseScrnToDocScrnVisitDetails should surface a service failure")
+ void getBenDataFrmNurseScrnToDocScrnVisitDetails_shouldSurfaceServiceFailure() throws Exception {
+ when(cSServiceImpl.getBenDataFrmNurseToDocVisitDetailsScreen(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenDataFrmNurseScrnToDocScrnVisitDetails(VISIT_REQUEST).contains("Error while getting beneficiary visit data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenDataFrmNurseScrnToDocScrnHistory")
+ class ReadHistoryTests {
+
+ @Test
+ @DisplayName("getBenDataFrmNurseScrnToDocScrnHistory should return the details for a complete request")
+ void getBenDataFrmNurseScrnToDocScrnHistory_shouldReturnDetails() throws Exception {
+ when(cSServiceImpl.getBenDataFrmNurseToDocHistoryScreen(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenDataFrmNurseScrnToDocScrnHistory(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenDataFrmNurseScrnToDocScrnHistory should reject an incomplete request")
+ void getBenDataFrmNurseScrnToDocScrnHistory_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenDataFrmNurseScrnToDocScrnHistory("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenDataFrmNurseScrnToDocScrnHistory should surface a service failure")
+ void getBenDataFrmNurseScrnToDocScrnHistory_shouldSurfaceServiceFailure() throws Exception {
+ when(cSServiceImpl.getBenDataFrmNurseToDocHistoryScreen(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenDataFrmNurseScrnToDocScrnHistory(VISIT_REQUEST).contains("Error while getting beneficiary history data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenDataFrmNurseScrnToDocScrnVital")
+ class ReadVitalsTests {
+
+ @Test
+ @DisplayName("getBenDataFrmNurseScrnToDocScrnVital should return the details for a complete request")
+ void getBenDataFrmNurseScrnToDocScrnVital_shouldReturnDetails() throws Exception {
+ when(cSServiceImpl.getBenDataFrmNurseToDocVitalScreen(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenDataFrmNurseScrnToDocScrnVital(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenDataFrmNurseScrnToDocScrnVital should reject an incomplete request")
+ void getBenDataFrmNurseScrnToDocScrnVital_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenDataFrmNurseScrnToDocScrnVital("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenDataFrmNurseScrnToDocScrnVital should surface a service failure")
+ void getBenDataFrmNurseScrnToDocScrnVital_shouldSurfaceServiceFailure() throws Exception {
+ when(cSServiceImpl.getBenDataFrmNurseToDocVitalScreen(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenDataFrmNurseScrnToDocScrnVital(VISIT_REQUEST).contains("Error while getting beneficiary vital data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenDataFrmNurseScrnToDocScrnExamination")
+ class ReadExaminationTests {
+
+ @Test
+ @DisplayName("getBenDataFrmNurseScrnToDocScrnExamination should return the details for a complete request")
+ void getBenDataFrmNurseScrnToDocScrnExamination_shouldReturnDetails() throws Exception {
+ when(cSServiceImpl.getBenDataFrmNurseToDocExaminationScreen(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenDataFrmNurseScrnToDocScrnExamination(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenDataFrmNurseScrnToDocScrnExamination should reject an incomplete request")
+ void getBenDataFrmNurseScrnToDocScrnExamination_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenDataFrmNurseScrnToDocScrnExamination("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenDataFrmNurseScrnToDocScrnExamination should surface a service failure")
+ void getBenDataFrmNurseScrnToDocScrnExamination_shouldSurfaceServiceFailure() throws Exception {
+ when(cSServiceImpl.getBenDataFrmNurseToDocExaminationScreen(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenDataFrmNurseScrnToDocScrnExamination(VISIT_REQUEST).contains("Error while getting beneficiary examination data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenCaseRecordFromDoctorCS")
+ class ReadCaseRecordTests {
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorCS should return the details for a complete request")
+ void getBenCaseRecordFromDoctorCS_shouldReturnDetails() throws Exception {
+ when(cSServiceImpl.getBenCaseRecordFromDoctorCS(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenCaseRecordFromDoctorCS(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorCS should reject an incomplete request")
+ void getBenCaseRecordFromDoctorCS_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenCaseRecordFromDoctorCS("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorCS should surface a service failure")
+ void getBenCaseRecordFromDoctorCS_shouldSurfaceServiceFailure() throws Exception {
+ when(cSServiceImpl.getBenCaseRecordFromDoctorCS(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenCaseRecordFromDoctorCS(VISIT_REQUEST).contains("Error while getting beneficiary doctor data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("upodateBenExaminationDetail")
+ class UpdateExaminationTests {
+
+ @Test
+ @DisplayName("upodateBenExaminationDetail should confirm the update when a row was changed")
+ void upodateBenExaminationDetail_shouldConfirmUpdate() throws Exception {
+ when(cSServiceImpl.updateBenExaminationDetail(any(JsonObject.class))).thenReturn(1);
+
+ assertTrue(controller.upodateBenExaminationDetail(REQUEST).contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("upodateBenExaminationDetail should report that nothing was modified")
+ void upodateBenExaminationDetail_shouldReportNothingModified() throws Exception {
+ when(cSServiceImpl.updateBenExaminationDetail(any(JsonObject.class))).thenReturn(0);
+
+ assertTrue(controller.upodateBenExaminationDetail(REQUEST).contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("upodateBenExaminationDetail should surface a service failure")
+ void upodateBenExaminationDetail_shouldSurfaceServiceFailure() throws Exception {
+ when(cSServiceImpl.updateBenExaminationDetail(any(JsonObject.class))).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.upodateBenExaminationDetail(REQUEST).contains("Unable to modify data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("updateCancerScreeningDoctorData")
+ class UpdateDoctorTests {
+
+ @Test
+ @DisplayName("updateCancerScreeningDoctorData should confirm the update when a row was changed")
+ void updateCancerScreeningDoctorData_shouldConfirmUpdate() throws Exception {
+ when(cSServiceImpl.updateCancerScreeningDoctorData(any(JsonObject.class))).thenReturn(1);
+
+ assertTrue(controller.updateCancerScreeningDoctorData(REQUEST).contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("updateCancerScreeningDoctorData should report that nothing was modified")
+ void updateCancerScreeningDoctorData_shouldReportNothingModified() throws Exception {
+ when(cSServiceImpl.updateCancerScreeningDoctorData(any(JsonObject.class))).thenReturn(0);
+
+ assertTrue(controller.updateCancerScreeningDoctorData(REQUEST).contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updateCancerScreeningDoctorData should surface a service failure")
+ void updateCancerScreeningDoctorData_shouldSurfaceServiceFailure() throws Exception {
+ when(cSServiceImpl.updateCancerScreeningDoctorData(any(JsonObject.class)))
+ .thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.updateCancerScreeningDoctorData(REQUEST).contains("db down"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenCancerFamilyHistory")
+ class ReadFamilyHistoryTests {
+
+ @Test
+ @DisplayName("getBenCancerFamilyHistory should return the recorded family history")
+ void getBenCancerFamilyHistory_shouldReturnRecordedHistory() throws Exception {
+ when(cSServiceImpl.getBenFamilyHistoryData(BEN_REG_ID)).thenReturn("{\"columns\":[]}");
+
+ String result = controller.getBenCancerFamilyHistory("{\"benRegID\":11}");
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("columns"));
+ }
+
+ @Test
+ @DisplayName("getBenCancerFamilyHistory should reject a request with no beneficiary")
+ void getBenCancerFamilyHistory_shouldRejectRequestWithoutBeneficiary() throws Exception {
+ assertTrue(controller.getBenCancerFamilyHistory("{}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenCancerFamilyHistory should surface a service failure")
+ void getBenCancerFamilyHistory_shouldSurfaceServiceFailure() throws Exception {
+ when(cSServiceImpl.getBenFamilyHistoryData(BEN_REG_ID)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenCancerFamilyHistory("{\"benRegID\":11}")
+ .contains("Error while getting beneficiary family history data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenCancerPersonalHistory")
+ class ReadPersonalHistoryTests {
+
+ @Test
+ @DisplayName("getBenCancerPersonalHistory should return the recorded personal history")
+ void getBenCancerPersonalHistory_shouldReturnRecordedHistory() throws Exception {
+ when(cSServiceImpl.getBenPersonalHistoryData(BEN_REG_ID)).thenReturn("{\"columns\":[]}");
+
+ String result = controller.getBenCancerPersonalHistory("{\"benRegID\":11}");
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("columns"));
+ }
+
+ @Test
+ @DisplayName("getBenCancerPersonalHistory should reject a request with no beneficiary")
+ void getBenCancerPersonalHistory_shouldRejectRequestWithoutBeneficiary() throws Exception {
+ assertTrue(controller.getBenCancerPersonalHistory("{}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenCancerPersonalHistory should surface a service failure")
+ void getBenCancerPersonalHistory_shouldSurfaceServiceFailure() throws Exception {
+ when(cSServiceImpl.getBenPersonalHistoryData(BEN_REG_ID)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenCancerPersonalHistory("{\"benRegID\":11}")
+ .contains("Error while getting beneficiary personal history data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenCancerPersonalDietHistory")
+ class ReadPersonalDietHistoryTests {
+
+ @Test
+ @DisplayName("getBenCancerPersonalDietHistory should return the recorded personal diet history")
+ void getBenCancerPersonalDietHistory_shouldReturnRecordedHistory() throws Exception {
+ when(cSServiceImpl.getBenPersonalDietHistoryData(BEN_REG_ID)).thenReturn("{\"columns\":[]}");
+
+ String result = controller.getBenCancerPersonalDietHistory("{\"benRegID\":11}");
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("columns"));
+ }
+
+ @Test
+ @DisplayName("getBenCancerPersonalDietHistory should reject a request with no beneficiary")
+ void getBenCancerPersonalDietHistory_shouldRejectRequestWithoutBeneficiary() throws Exception {
+ assertTrue(controller.getBenCancerPersonalDietHistory("{}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenCancerPersonalDietHistory should surface a service failure")
+ void getBenCancerPersonalDietHistory_shouldSurfaceServiceFailure() throws Exception {
+ when(cSServiceImpl.getBenPersonalDietHistoryData(BEN_REG_ID)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenCancerPersonalDietHistory("{\"benRegID\":11}")
+ .contains("Error while getting beneficiary personal diet history data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenCancerObstetricHistory")
+ class ReadObstetricHistoryTests {
+
+ @Test
+ @DisplayName("getBenCancerObstetricHistory should return the recorded obstetric history")
+ void getBenCancerObstetricHistory_shouldReturnRecordedHistory() throws Exception {
+ when(cSServiceImpl.getBenObstetricHistoryData(BEN_REG_ID)).thenReturn("{\"columns\":[]}");
+
+ String result = controller.getBenCancerObstetricHistory("{\"benRegID\":11}");
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("columns"));
+ }
+
+ @Test
+ @DisplayName("getBenCancerObstetricHistory should reject a request with no beneficiary")
+ void getBenCancerObstetricHistory_shouldRejectRequestWithoutBeneficiary() throws Exception {
+ assertTrue(controller.getBenCancerObstetricHistory("{}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenCancerObstetricHistory should surface a service failure")
+ void getBenCancerObstetricHistory_shouldSurfaceServiceFailure() throws Exception {
+ when(cSServiceImpl.getBenObstetricHistoryData(BEN_REG_ID)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenCancerObstetricHistory("{\"benRegID\":11}")
+ .contains("Error while getting beneficiary obstetric history data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("updateCSHistoryNurse")
+ class UpdateHistoryTests {
+
+ @Test
+ @DisplayName("updateCSHistoryNurse should confirm the updated history")
+ void updateCSHistoryNurse_shouldConfirmUpdate() throws Exception {
+ when(cSServiceImpl.UpdateCSHistoryNurseData(any(JsonObject.class))).thenReturn(1);
+
+ assertTrue(controller.updateCSHistoryNurse(REQUEST).contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("updateCSHistoryNurse should report history it could not modify")
+ void updateCSHistoryNurse_shouldReportUnmodifiedHistory() throws Exception {
+ when(cSServiceImpl.UpdateCSHistoryNurseData(any(JsonObject.class))).thenReturn(0);
+
+ assertTrue(controller.updateCSHistoryNurse(REQUEST).contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updateCSHistoryNurse should surface a service failure")
+ void updateCSHistoryNurse_shouldSurfaceServiceFailure() throws Exception {
+ when(cSServiceImpl.UpdateCSHistoryNurseData(any(JsonObject.class)))
+ .thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.updateCSHistoryNurse(REQUEST).contains("Unable to modify data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("upodateBenVitalDetail")
+ class UpdateVitalsTests {
+
+ @Test
+ @DisplayName("upodateBenVitalDetail should confirm the updated vitals")
+ void upodateBenVitalDetail_shouldConfirmUpdate() throws Exception {
+ when(cSServiceImpl.updateBenVitalDetail(any())).thenReturn(1);
+
+ assertTrue(controller.upodateBenVitalDetail(REQUEST).contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("upodateBenVitalDetail should report vitals it could not modify")
+ void upodateBenVitalDetail_shouldReportUnmodifiedVitals() throws Exception {
+ when(cSServiceImpl.updateBenVitalDetail(any())).thenReturn(0);
+
+ assertTrue(controller.upodateBenVitalDetail(REQUEST).contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("upodateBenVitalDetail should surface a service failure")
+ void upodateBenVitalDetail_shouldSurfaceServiceFailure() throws Exception {
+ when(cSServiceImpl.updateBenVitalDetail(any())).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.upodateBenVitalDetail(REQUEST).contains("Unable to modify data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("updateCancerDiagnosisDetailsByOncologist")
+ class UpdateOncologistDiagnosisTests {
+
+ @Test
+ @DisplayName("updateCancerDiagnosisDetailsByOncologist should confirm the updated diagnosis")
+ void updateOncologistDiagnosis_shouldConfirmUpdate() throws Exception {
+ when(cSServiceImpl.updateCancerDiagnosisDetailsByOncologist(any())).thenReturn(1);
+
+ assertTrue(controller.updateCancerDiagnosisDetailsByOncologist(REQUEST)
+ .contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("updateCancerDiagnosisDetailsByOncologist should report a diagnosis it could not modify")
+ void updateOncologistDiagnosis_shouldReportUnmodifiedDiagnosis() throws Exception {
+ when(cSServiceImpl.updateCancerDiagnosisDetailsByOncologist(any())).thenReturn(0);
+
+ assertTrue(controller.updateCancerDiagnosisDetailsByOncologist(REQUEST)
+ .contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updateCancerDiagnosisDetailsByOncologist should surface a service failure")
+ void updateOncologistDiagnosis_shouldSurfaceServiceFailure() throws Exception {
+ when(cSServiceImpl.updateCancerDiagnosisDetailsByOncologist(any()))
+ .thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.updateCancerDiagnosisDetailsByOncologist(REQUEST)
+ .contains("Unable to modify data"));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/controller/common/main/WorklistControllerTest.java b/src/test/java/com/iemr/tm/controller/common/main/WorklistControllerTest.java
new file mode 100644
index 00000000..5e0441a9
--- /dev/null
+++ b/src/test/java/com/iemr/tm/controller/common/main/WorklistControllerTest.java
@@ -0,0 +1,923 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.controller.common.main;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+import org.springframework.security.core.Authentication;
+
+import com.iemr.tm.service.common.transaction.CommonDoctorServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonNurseServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonServiceImpl;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("WorklistController Test Suite")
+class WorklistControllerTest {
+
+ private static final String AUTHORIZATION = "Bearer session-token";
+ private static final Long BEN_REG_ID = 11L;
+ private static final String BEN_REQUEST = "{\"benRegID\":11,\"beneficiaryRegID\":11}";
+
+ @Mock
+ private CommonServiceImpl commonServiceImpl;
+ @Mock
+ private CommonDoctorServiceImpl commonDoctorServiceImpl;
+ @Mock
+ private CommonNurseServiceImpl commonNurseServiceImpl;
+ @Mock
+ private Authentication authentication;
+
+ private WorklistController controller;
+
+ @BeforeEach
+ @DisplayName("Wire the controller with mocked services")
+ void setUp() {
+ controller = new WorklistController();
+ controller.setCommonServiceImpl(commonServiceImpl);
+ controller.setCommonDoctorServiceImpl(commonDoctorServiceImpl);
+ controller.setCommonNurseServiceImpl(commonNurseServiceImpl);
+ }
+
+ @Nested
+ @DisplayName("getNurseWorkListNew")
+ class GetNurseWorkListNewTests {
+
+ @Test
+ @DisplayName("getNurseWorkListNew should return the worklist for the provider and van")
+ void getNurseWorkListNew_shouldReturnWorklist() {
+ when(commonNurseServiceImpl.getNurseWorkListNew(9, 7)).thenReturn("[]");
+
+ assertTrue(controller.getNurseWorkListNew(9, 7).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getNurseWorkListNew should surface a service failure")
+ void getNurseWorkListNew_shouldSurfaceServiceFailure() {
+ when(commonNurseServiceImpl.getNurseWorkListNew(9, 7)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getNurseWorkListNew(9, 7).contains("\"statusCode\":5000"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getNurseWorkListTcCurrentDateNew")
+ class GetNurseWorkListTcCurrentDateNewTests {
+
+ @Test
+ @DisplayName("getNurseWorkListTcCurrentDateNew should return the worklist for the provider and van")
+ void getNurseWorkListTcCurrentDateNew_shouldReturnWorklist() {
+ when(commonNurseServiceImpl.getNurseWorkListTcCurrentDate(9, 7)).thenReturn("[]");
+
+ assertTrue(controller.getNurseWorkListTcCurrentDateNew(9, 7).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getNurseWorkListTcCurrentDateNew should surface a service failure")
+ void getNurseWorkListTcCurrentDateNew_shouldSurfaceServiceFailure() {
+ when(commonNurseServiceImpl.getNurseWorkListTcCurrentDate(9, 7)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getNurseWorkListTcCurrentDateNew(9, 7).contains("\"statusCode\":5000"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getNurseWorkListTcFutureDateNew")
+ class GetNurseWorkListTcFutureDateNewTests {
+
+ @Test
+ @DisplayName("getNurseWorkListTcFutureDateNew should return the worklist for the provider and van")
+ void getNurseWorkListTcFutureDateNew_shouldReturnWorklist() {
+ when(commonNurseServiceImpl.getNurseWorkListTcFutureDate(9, 7)).thenReturn("[]");
+
+ assertTrue(controller.getNurseWorkListTcFutureDateNew(9, 7).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getNurseWorkListTcFutureDateNew should surface a service failure")
+ void getNurseWorkListTcFutureDateNew_shouldSurfaceServiceFailure() {
+ when(commonNurseServiceImpl.getNurseWorkListTcFutureDate(9, 7)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getNurseWorkListTcFutureDateNew(9, 7).contains("\"statusCode\":5000"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getLabWorkListNew")
+ class GetLabWorkListNewTests {
+
+ @Test
+ @DisplayName("getLabWorkListNew should return the worklist for the provider and van")
+ void getLabWorkListNew_shouldReturnWorklist() {
+ when(commonNurseServiceImpl.getLabWorkListNew(9, 7)).thenReturn("[]");
+
+ assertTrue(controller.getLabWorkListNew(9, 7).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getLabWorkListNew should surface a service failure")
+ void getLabWorkListNew_shouldSurfaceServiceFailure() {
+ when(commonNurseServiceImpl.getLabWorkListNew(9, 7)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getLabWorkListNew(9, 7).contains("\"statusCode\":5000"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getRadiologistWorklistNew")
+ class GetRadiologistWorklistNewTests {
+
+ @Test
+ @DisplayName("getRadiologistWorklistNew should return the worklist for the provider and van")
+ void getRadiologistWorklistNew_shouldReturnWorklist() {
+ when(commonNurseServiceImpl.getRadiologistWorkListNew(9, 7)).thenReturn("[]");
+
+ assertTrue(controller.getRadiologistWorklistNew(9, 7).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getRadiologistWorklistNew should surface a service failure")
+ void getRadiologistWorklistNew_shouldSurfaceServiceFailure() {
+ when(commonNurseServiceImpl.getRadiologistWorkListNew(9, 7)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getRadiologistWorklistNew(9, 7).contains("\"statusCode\":5000"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getOncologistWorklistNew")
+ class GetOncologistWorklistNewTests {
+
+ @Test
+ @DisplayName("getOncologistWorklistNew should return the worklist for the provider and van")
+ void getOncologistWorklistNew_shouldReturnWorklist() {
+ when(commonNurseServiceImpl.getOncologistWorkListNew(9, 7)).thenReturn("[]");
+
+ assertTrue(controller.getOncologistWorklistNew(9, 7).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getOncologistWorklistNew should surface a service failure")
+ void getOncologistWorklistNew_shouldSurfaceServiceFailure() {
+ when(commonNurseServiceImpl.getOncologistWorkListNew(9, 7)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getOncologistWorklistNew(9, 7).contains("\"statusCode\":5000"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getPharmaWorklistNew")
+ class GetPharmaWorklistNewTests {
+
+ @Test
+ @DisplayName("getPharmaWorklistNew should return the worklist for the provider and van")
+ void getPharmaWorklistNew_shouldReturnWorklist() {
+ when(commonNurseServiceImpl.getPharmaWorkListNew(9, 7)).thenReturn("[]");
+
+ assertTrue(controller.getPharmaWorklistNew(9, 7).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getPharmaWorklistNew should surface a service failure")
+ void getPharmaWorklistNew_shouldSurfaceServiceFailure() {
+ when(commonNurseServiceImpl.getPharmaWorkListNew(9, 7)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getPharmaWorklistNew(9, 7).contains("\"statusCode\":5000"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getMmuNurseWorklistNew")
+ class GetMmuNurseWorklistNewTests {
+
+ @Test
+ @DisplayName("getMmuNurseWorklistNew should return the worklist for the provider and van")
+ void getMmuNurseWorklistNew_shouldReturnWorklist() {
+ when(commonNurseServiceImpl.getMmuNurseWorkListNew(9, 7)).thenReturn("[]");
+
+ assertTrue(controller.getMmuNurseWorklistNew(9, 7).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getMmuNurseWorklistNew should surface a service failure")
+ void getMmuNurseWorklistNew_shouldSurfaceServiceFailure() {
+ when(commonNurseServiceImpl.getMmuNurseWorkListNew(9, 7)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getMmuNurseWorklistNew(9, 7).contains("\"statusCode\":5000"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getDocWorkListNew")
+ class GetDocWorkListNewTests {
+
+ @Test
+ @DisplayName("getDocWorkListNew should return the worklist for the provider and service")
+ void getDocWorkListNew_shouldReturnWorklist() {
+ when(commonDoctorServiceImpl.getDocWorkListNew(9, 2, 7)).thenReturn("[]");
+
+ assertTrue(controller.getDocWorkListNew(9, 2, 7).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getDocWorkListNew should reject a request without a service id")
+ void getDocWorkListNew_shouldRejectRequestWithoutServiceId() {
+ assertTrue(controller.getDocWorkListNew(9, null, 7).contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getDocWorkListNew should surface a service failure")
+ void getDocWorkListNew_shouldSurfaceServiceFailure() {
+ when(commonDoctorServiceImpl.getDocWorkListNew(9, 2, 7)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getDocWorkListNew(9, 2, 7).contains("\"statusCode\":5000"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getDocWorkListNewFutureScheduledForTM")
+ class GetDocWorkListNewFutureScheduledForTMTests {
+
+ @Test
+ @DisplayName("getDocWorkListNewFutureScheduledForTM should return the worklist for the provider and service")
+ void getDocWorkListNewFutureScheduledForTM_shouldReturnWorklist() {
+ when(commonDoctorServiceImpl.getDocWorkListNewFutureScheduledForTM(9, 2, 7)).thenReturn("[]");
+
+ assertTrue(controller.getDocWorkListNewFutureScheduledForTM(9, 2, 7).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getDocWorkListNewFutureScheduledForTM should reject a request without a service id")
+ void getDocWorkListNewFutureScheduledForTM_shouldRejectRequestWithoutServiceId() {
+ assertTrue(controller.getDocWorkListNewFutureScheduledForTM(9, null, 7).contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getDocWorkListNewFutureScheduledForTM should surface a service failure")
+ void getDocWorkListNewFutureScheduledForTM_shouldSurfaceServiceFailure() {
+ when(commonDoctorServiceImpl.getDocWorkListNewFutureScheduledForTM(9, 2, 7)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getDocWorkListNewFutureScheduledForTM(9, 2, 7).contains("\"statusCode\":5000"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenPastHistory")
+ class GetBenPastHistoryTests {
+
+ @Test
+ @DisplayName("getBenPastHistory should return the stored history for the beneficiary")
+ void getBenPastHistory_shouldReturnStoredHistory() throws Exception {
+ when(commonServiceImpl.getBenPastHistoryData(BEN_REG_ID)).thenReturn("{\"columns\":[]}");
+
+ assertTrue(controller.getBenPastHistory(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenPastHistory should reject a request without the beneficiary id")
+ void getBenPastHistory_shouldRejectRequestWithoutBeneficiaryId() throws Exception {
+ assertTrue(controller.getBenPastHistory("{}").contains("\"statusCode\":5000"));
+ }
+
+ @Test
+ @DisplayName("getBenPastHistory should surface a service failure")
+ void getBenPastHistory_shouldSurfaceServiceFailure() throws Exception {
+ when(commonServiceImpl.getBenPastHistoryData(BEN_REG_ID)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenPastHistory(BEN_REQUEST).contains("\"statusCode\":5000"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenTobaccoHistory")
+ class GetBenTobaccoHistoryTests {
+
+ @Test
+ @DisplayName("getBenTobaccoHistory should return the stored history for the beneficiary")
+ void getBenTobaccoHistory_shouldReturnStoredHistory() throws Exception {
+ when(commonServiceImpl.getPersonalTobaccoHistoryData(BEN_REG_ID)).thenReturn("{\"columns\":[]}");
+
+ assertTrue(controller.getBenTobaccoHistory(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenTobaccoHistory should reject a request without the beneficiary id")
+ void getBenTobaccoHistory_shouldRejectRequestWithoutBeneficiaryId() throws Exception {
+ assertTrue(controller.getBenTobaccoHistory("{}").contains("\"statusCode\":5000"));
+ }
+
+ @Test
+ @DisplayName("getBenTobaccoHistory should surface a service failure")
+ void getBenTobaccoHistory_shouldSurfaceServiceFailure() throws Exception {
+ when(commonServiceImpl.getPersonalTobaccoHistoryData(BEN_REG_ID)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenTobaccoHistory(BEN_REQUEST).contains("\"statusCode\":5000"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenAlcoholHistory")
+ class GetBenAlcoholHistoryTests {
+
+ @Test
+ @DisplayName("getBenAlcoholHistory should return the stored history for the beneficiary")
+ void getBenAlcoholHistory_shouldReturnStoredHistory() throws Exception {
+ when(commonServiceImpl.getPersonalAlcoholHistoryData(BEN_REG_ID)).thenReturn("{\"columns\":[]}");
+
+ assertTrue(controller.getBenAlcoholHistory(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenAlcoholHistory should reject a request without the beneficiary id")
+ void getBenAlcoholHistory_shouldRejectRequestWithoutBeneficiaryId() throws Exception {
+ assertTrue(controller.getBenAlcoholHistory("{}").contains("\"statusCode\":5000"));
+ }
+
+ @Test
+ @DisplayName("getBenAlcoholHistory should surface a service failure")
+ void getBenAlcoholHistory_shouldSurfaceServiceFailure() throws Exception {
+ when(commonServiceImpl.getPersonalAlcoholHistoryData(BEN_REG_ID)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenAlcoholHistory(BEN_REQUEST).contains("\"statusCode\":5000"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenANCAllergyHistory")
+ class GetBenANCAllergyHistoryTests {
+
+ @Test
+ @DisplayName("getBenANCAllergyHistory should return the stored history for the beneficiary")
+ void getBenANCAllergyHistory_shouldReturnStoredHistory() throws Exception {
+ when(commonServiceImpl.getPersonalAllergyHistoryData(BEN_REG_ID)).thenReturn("{\"columns\":[]}");
+
+ assertTrue(controller.getBenANCAllergyHistory(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenANCAllergyHistory should reject a request without the beneficiary id")
+ void getBenANCAllergyHistory_shouldRejectRequestWithoutBeneficiaryId() throws Exception {
+ assertTrue(controller.getBenANCAllergyHistory("{}").contains("\"statusCode\":5000"));
+ }
+
+ @Test
+ @DisplayName("getBenANCAllergyHistory should surface a service failure")
+ void getBenANCAllergyHistory_shouldSurfaceServiceFailure() throws Exception {
+ when(commonServiceImpl.getPersonalAllergyHistoryData(BEN_REG_ID)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenANCAllergyHistory(BEN_REQUEST).contains("\"statusCode\":5000"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenMedicationHistory")
+ class GetBenMedicationHistoryTests {
+
+ @Test
+ @DisplayName("getBenMedicationHistory should return the stored history for the beneficiary")
+ void getBenMedicationHistory_shouldReturnStoredHistory() throws Exception {
+ when(commonServiceImpl.getMedicationHistoryData(BEN_REG_ID)).thenReturn("{\"columns\":[]}");
+
+ assertTrue(controller.getBenMedicationHistory(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenMedicationHistory should reject a request without the beneficiary id")
+ void getBenMedicationHistory_shouldRejectRequestWithoutBeneficiaryId() throws Exception {
+ assertTrue(controller.getBenMedicationHistory("{}").contains("\"statusCode\":5000"));
+ }
+
+ @Test
+ @DisplayName("getBenMedicationHistory should surface a service failure")
+ void getBenMedicationHistory_shouldSurfaceServiceFailure() throws Exception {
+ when(commonServiceImpl.getMedicationHistoryData(BEN_REG_ID)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenMedicationHistory(BEN_REQUEST).contains("\"statusCode\":5000"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenFamilyHistory")
+ class GetBenFamilyHistoryTests {
+
+ @Test
+ @DisplayName("getBenFamilyHistory should return the stored history for the beneficiary")
+ void getBenFamilyHistory_shouldReturnStoredHistory() throws Exception {
+ when(commonServiceImpl.getFamilyHistoryData(BEN_REG_ID)).thenReturn("{\"columns\":[]}");
+
+ assertTrue(controller.getBenFamilyHistory(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenFamilyHistory should reject a request without the beneficiary id")
+ void getBenFamilyHistory_shouldRejectRequestWithoutBeneficiaryId() throws Exception {
+ assertTrue(controller.getBenFamilyHistory("{}").contains("\"statusCode\":5000"));
+ }
+
+ @Test
+ @DisplayName("getBenFamilyHistory should surface a service failure")
+ void getBenFamilyHistory_shouldSurfaceServiceFailure() throws Exception {
+ when(commonServiceImpl.getFamilyHistoryData(BEN_REG_ID)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenFamilyHistory(BEN_REQUEST).contains("\"statusCode\":5000"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenMenstrualHistory")
+ class GetBenMenstrualHistoryTests {
+
+ @Test
+ @DisplayName("getBenMenstrualHistory should return the stored history for the beneficiary")
+ void getBenMenstrualHistory_shouldReturnStoredHistory() throws Exception {
+ when(commonServiceImpl.getMenstrualHistoryData(BEN_REG_ID)).thenReturn("{\"columns\":[]}");
+
+ assertTrue(controller.getBenMenstrualHistory(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenMenstrualHistory should reject a request without the beneficiary id")
+ void getBenMenstrualHistory_shouldRejectRequestWithoutBeneficiaryId() throws Exception {
+ assertTrue(controller.getBenMenstrualHistory("{}").contains("\"statusCode\":5000"));
+ }
+
+ @Test
+ @DisplayName("getBenMenstrualHistory should surface a service failure")
+ void getBenMenstrualHistory_shouldSurfaceServiceFailure() throws Exception {
+ when(commonServiceImpl.getMenstrualHistoryData(BEN_REG_ID)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenMenstrualHistory(BEN_REQUEST).contains("\"statusCode\":5000"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenPastObstetricHistory")
+ class GetBenPastObstetricHistoryTests {
+
+ @Test
+ @DisplayName("getBenPastObstetricHistory should return the stored history for the beneficiary")
+ void getBenPastObstetricHistory_shouldReturnStoredHistory() throws Exception {
+ when(commonServiceImpl.getObstetricHistoryData(BEN_REG_ID)).thenReturn("{\"columns\":[]}");
+
+ assertTrue(controller.getBenPastObstetricHistory(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenPastObstetricHistory should reject a request without the beneficiary id")
+ void getBenPastObstetricHistory_shouldRejectRequestWithoutBeneficiaryId() throws Exception {
+ assertTrue(controller.getBenPastObstetricHistory("{}").contains("\"statusCode\":5000"));
+ }
+
+ @Test
+ @DisplayName("getBenPastObstetricHistory should surface a service failure")
+ void getBenPastObstetricHistory_shouldSurfaceServiceFailure() throws Exception {
+ when(commonServiceImpl.getObstetricHistoryData(BEN_REG_ID)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenPastObstetricHistory(BEN_REQUEST).contains("\"statusCode\":5000"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenANCComorbidityConditionHistory")
+ class GetBenANCComorbidityConditionHistoryTests {
+
+ @Test
+ @DisplayName("getBenANCComorbidityConditionHistory should return the stored history for the beneficiary")
+ void getBenANCComorbidityConditionHistory_shouldReturnStoredHistory() throws Exception {
+ when(commonServiceImpl.getComorbidHistoryData(BEN_REG_ID)).thenReturn("{\"columns\":[]}");
+
+ assertTrue(controller.getBenANCComorbidityConditionHistory(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenANCComorbidityConditionHistory should reject a request without the beneficiary id")
+ void getBenANCComorbidityConditionHistory_shouldRejectRequestWithoutBeneficiaryId() throws Exception {
+ assertTrue(controller.getBenANCComorbidityConditionHistory("{}").contains("\"statusCode\":5000"));
+ }
+
+ @Test
+ @DisplayName("getBenANCComorbidityConditionHistory should surface a service failure")
+ void getBenANCComorbidityConditionHistory_shouldSurfaceServiceFailure() throws Exception {
+ when(commonServiceImpl.getComorbidHistoryData(BEN_REG_ID)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenANCComorbidityConditionHistory(BEN_REQUEST).contains("\"statusCode\":5000"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenOptionalVaccineHistory")
+ class GetBenOptionalVaccineHistoryTests {
+
+ @Test
+ @DisplayName("getBenOptionalVaccineHistory should return the stored history for the beneficiary")
+ void getBenOptionalVaccineHistory_shouldReturnStoredHistory() throws Exception {
+ when(commonServiceImpl.getChildVaccineHistoryData(BEN_REG_ID)).thenReturn("{\"columns\":[]}");
+
+ assertTrue(controller.getBenOptionalVaccineHistory(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenOptionalVaccineHistory should reject a request without the beneficiary id")
+ void getBenOptionalVaccineHistory_shouldRejectRequestWithoutBeneficiaryId() throws Exception {
+ assertTrue(controller.getBenOptionalVaccineHistory("{}").contains("\"statusCode\":5000"));
+ }
+
+ @Test
+ @DisplayName("getBenOptionalVaccineHistory should surface a service failure")
+ void getBenOptionalVaccineHistory_shouldSurfaceServiceFailure() throws Exception {
+ when(commonServiceImpl.getChildVaccineHistoryData(BEN_REG_ID)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenOptionalVaccineHistory(BEN_REQUEST).contains("\"statusCode\":5000"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenImmunizationHistory")
+ class GetBenImmunizationHistoryTests {
+
+ @Test
+ @DisplayName("getBenImmunizationHistory should return the stored history for the beneficiary")
+ void getBenImmunizationHistory_shouldReturnStoredHistory() throws Exception {
+ when(commonServiceImpl.getImmunizationHistoryData(BEN_REG_ID)).thenReturn("{\"columns\":[]}");
+
+ assertTrue(controller.getBenImmunizationHistory(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenImmunizationHistory should reject a request without the beneficiary id")
+ void getBenImmunizationHistory_shouldRejectRequestWithoutBeneficiaryId() throws Exception {
+ assertTrue(controller.getBenImmunizationHistory("{}").contains("\"statusCode\":5000"));
+ }
+
+ @Test
+ @DisplayName("getBenImmunizationHistory should surface a service failure")
+ void getBenImmunizationHistory_shouldSurfaceServiceFailure() throws Exception {
+ when(commonServiceImpl.getImmunizationHistoryData(BEN_REG_ID)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenImmunizationHistory(BEN_REQUEST).contains("\"statusCode\":5000"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenPerinatalHistory")
+ class GetBenPerinatalHistoryTests {
+
+ @Test
+ @DisplayName("getBenPerinatalHistory should return the stored history for the beneficiary")
+ void getBenPerinatalHistory_shouldReturnStoredHistory() throws Exception {
+ when(commonServiceImpl.getBenPerinatalHistoryData(BEN_REG_ID)).thenReturn("{\"columns\":[]}");
+
+ assertTrue(controller.getBenPerinatalHistory(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenPerinatalHistory should reject a request without the beneficiary id")
+ void getBenPerinatalHistory_shouldRejectRequestWithoutBeneficiaryId() throws Exception {
+ assertTrue(controller.getBenPerinatalHistory("{}").contains("\"statusCode\":5000"));
+ }
+
+ @Test
+ @DisplayName("getBenPerinatalHistory should surface a service failure")
+ void getBenPerinatalHistory_shouldSurfaceServiceFailure() throws Exception {
+ when(commonServiceImpl.getBenPerinatalHistoryData(BEN_REG_ID)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenPerinatalHistory(BEN_REQUEST).contains("\"statusCode\":5000"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenFeedingHistory")
+ class GetBenFeedingHistoryTests {
+
+ @Test
+ @DisplayName("getBenFeedingHistory should return the stored history for the beneficiary")
+ void getBenFeedingHistory_shouldReturnStoredHistory() throws Exception {
+ when(commonServiceImpl.getBenFeedingHistoryData(BEN_REG_ID)).thenReturn("{\"columns\":[]}");
+
+ assertTrue(controller.getBenFeedingHistory(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenFeedingHistory should reject a request without the beneficiary id")
+ void getBenFeedingHistory_shouldRejectRequestWithoutBeneficiaryId() throws Exception {
+ assertTrue(controller.getBenFeedingHistory("{}").contains("\"statusCode\":5000"));
+ }
+
+ @Test
+ @DisplayName("getBenFeedingHistory should surface a service failure")
+ void getBenFeedingHistory_shouldSurfaceServiceFailure() throws Exception {
+ when(commonServiceImpl.getBenFeedingHistoryData(BEN_REG_ID)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenFeedingHistory(BEN_REQUEST).contains("\"statusCode\":5000"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenDevelopmentHistory")
+ class GetBenDevelopmentHistoryTests {
+
+ @Test
+ @DisplayName("getBenDevelopmentHistory should return the stored history for the beneficiary")
+ void getBenDevelopmentHistory_shouldReturnStoredHistory() throws Exception {
+ when(commonServiceImpl.getBenDevelopmentHistoryData(BEN_REG_ID)).thenReturn("{\"columns\":[]}");
+
+ assertTrue(controller.getBenDevelopmentHistory(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenDevelopmentHistory should reject a request without the beneficiary id")
+ void getBenDevelopmentHistory_shouldRejectRequestWithoutBeneficiaryId() throws Exception {
+ assertTrue(controller.getBenDevelopmentHistory("{}").contains("\"statusCode\":5000"));
+ }
+
+ @Test
+ @DisplayName("getBenDevelopmentHistory should surface a service failure")
+ void getBenDevelopmentHistory_shouldSurfaceServiceFailure() throws Exception {
+ when(commonServiceImpl.getBenDevelopmentHistoryData(BEN_REG_ID)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenDevelopmentHistory(BEN_REQUEST).contains("\"statusCode\":5000"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenPhysicalHistory")
+ class GetBenPhysicalHistoryTests {
+
+ @Test
+ @DisplayName("getBenPhysicalHistory should return the stored history for the beneficiary")
+ void getBenPhysicalHistory_shouldReturnStoredHistory() throws Exception {
+ when(commonServiceImpl.getBenPhysicalHistory(BEN_REG_ID)).thenReturn("{\"columns\":[]}");
+
+ assertTrue(controller.getBenPhysicalHistory(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenPhysicalHistory should reject a request without the beneficiary id")
+ void getBenPhysicalHistory_shouldRejectRequestWithoutBeneficiaryId() throws Exception {
+ assertTrue(controller.getBenPhysicalHistory("{}").contains("\"statusCode\":5000"));
+ }
+
+ @Test
+ @DisplayName("getBenPhysicalHistory should surface a service failure")
+ void getBenPhysicalHistory_shouldSurfaceServiceFailure() throws Exception {
+ when(commonServiceImpl.getBenPhysicalHistory(BEN_REG_ID)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenPhysicalHistory(BEN_REQUEST).contains("\"statusCode\":5000"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getDoctorPreviousSignificantFindings")
+ class PreviousFindingsTests {
+
+ @Test
+ @DisplayName("getDoctorPreviousSignificantFindings should return the earlier findings")
+ void getPreviousFindings_shouldReturnEarlierFindings() {
+ when(commonDoctorServiceImpl.fetchBenPreviousSignificantFindings(BEN_REG_ID)).thenReturn("{}");
+
+ assertTrue(controller.getDoctorPreviousSignificantFindings("{\"beneficiaryRegID\":11}")
+ .contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getDoctorPreviousSignificantFindings should reject a request without the beneficiary id")
+ void getPreviousFindings_shouldRejectRequestWithoutBeneficiaryId() {
+ assertTrue(controller.getDoctorPreviousSignificantFindings("{}").contains("\"statusCode\":5000"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBeneficiaryCaseSheetHistory")
+ class CaseSheetHistoryTests {
+
+ @Test
+ @DisplayName("getBeneficiaryCaseSheetHistory should return the earlier visit history")
+ void getCaseSheetHistory_shouldReturnEarlierVisitHistory() throws Exception {
+ when(commonServiceImpl.getBenPreviousVisitDataForCaseRecord(BEN_REQUEST)).thenReturn("{}");
+
+ assertTrue(controller.getBeneficiaryCaseSheetHistory(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryCaseSheetHistory should report a failure when nothing comes back")
+ void getCaseSheetHistory_shouldReportFailureWhenNothingReturned() throws Exception {
+ when(commonServiceImpl.getBenPreviousVisitDataForCaseRecord(BEN_REQUEST)).thenReturn(null);
+
+ assertTrue(controller.getBeneficiaryCaseSheetHistory(BEN_REQUEST)
+ .contains("Error while fetching beneficiary previous visit history details"));
+ }
+ }
+
+ @Nested
+ @DisplayName("teleconsultation specialist worklists")
+ class SpecialistWorklistTests {
+
+ @Test
+ @DisplayName("getTCSpecialistWorkListNew should return the specialist worklist for an authenticated user")
+ void getSpecialistWorklist_shouldReturnWorklist() {
+ when(authentication.isAuthenticated()).thenReturn(true);
+ when(authentication.getPrincipal()).thenReturn("42");
+ when(commonDoctorServiceImpl.getTCSpecialistWorkListNewForTM(9, 42, 4)).thenReturn("[]");
+
+ assertTrue(controller.getTCSpecialistWorkListNew(9, 4, authentication).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getTCSpecialistWorkListNew should reject a missing authentication")
+ void getSpecialistWorklist_shouldRejectMissingAuthentication() {
+ assertTrue(controller.getTCSpecialistWorkListNew(9, 4, null).contains("Unauthorized access"));
+ }
+
+ @Test
+ @DisplayName("getTCSpecialistWorkListNewPatientApp should return the patient app worklist")
+ void getSpecialistWorklistPatientApp_shouldReturnWorklist() {
+ when(authentication.isAuthenticated()).thenReturn(true);
+ when(authentication.getPrincipal()).thenReturn("42");
+ when(commonDoctorServiceImpl.getTCSpecialistWorkListNewForTMPatientApp(9, 42, 4, 7)).thenReturn("[]");
+
+ assertTrue(controller.getTCSpecialistWorkListNewPatientApp(9, 4, 7, authentication)
+ .contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getTCSpecialistWorkListNewPatientApp should reject a missing authentication")
+ void getSpecialistWorklistPatientApp_shouldRejectMissingAuthentication() {
+ assertTrue(controller.getTCSpecialistWorkListNewPatientApp(9, 4, 7, null)
+ .contains("Unauthorized access"));
+ }
+
+ @Test
+ @DisplayName("getTCSpecialistWorklistFutureScheduled should return the future scheduled worklist")
+ void getSpecialistWorklistFutureScheduled_shouldReturnWorklist() {
+ when(authentication.isAuthenticated()).thenReturn(true);
+ when(authentication.getPrincipal()).thenReturn("42");
+ when(commonDoctorServiceImpl.getTCSpecialistWorkListNewFutureScheduledForTM(9, 42, 4)).thenReturn("[]");
+
+ assertTrue(controller.getTCSpecialistWorklistFutureScheduled(9, 4, authentication)
+ .contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getTCSpecialistWorklistFutureScheduled should reject a missing authentication")
+ void getSpecialistWorklistFutureScheduled_shouldRejectMissingAuthentication() {
+ assertTrue(controller.getTCSpecialistWorklistFutureScheduled(9, 4, null).contains("Unauthorized access"));
+ }
+ }
+
+ @Nested
+ @DisplayName("miscellaneous endpoints")
+ class MiscellaneousTests {
+
+ @Test
+ @DisplayName("getKMFile should return the document url")
+ void getKMFile_shouldReturnDocumentUrl() throws Exception {
+ when(commonServiceImpl.getOpenKMDocURL(BEN_REQUEST, AUTHORIZATION)).thenReturn("https://km/doc");
+
+ assertTrue(controller.getKMFile(BEN_REQUEST, AUTHORIZATION).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getKMFile should report a failure when no url comes back")
+ void getKMFile_shouldReportFailureWithoutUrl() throws Exception {
+ when(commonServiceImpl.getOpenKMDocURL(BEN_REQUEST, AUTHORIZATION)).thenReturn(null);
+
+ assertTrue(controller.getKMFile(BEN_REQUEST, AUTHORIZATION).contains("\"statusCode\":5000"));
+ }
+
+ @Test
+ @DisplayName("getBenSymptomaticQuestionnaireDetails should return the screening questionnaire")
+ void getSymptomaticQuestionnaire_shouldReturnQuestionnaire() throws Exception {
+ when(commonServiceImpl.getBenSymptomaticQuestionnaireDetailsData(BEN_REG_ID)).thenReturn("{}");
+
+ assertTrue(controller.getBenSymptomaticQuestionnaireDetails(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenPreviousDiabetesHistoryDetails should return the earlier diabetes screening")
+ void getPreviousDiabetes_shouldReturnEarlierScreening() throws Exception {
+ when(commonServiceImpl.getBenPreviousDiabetesData(BEN_REG_ID)).thenReturn("{}");
+
+ assertTrue(controller.getBenPreviousDiabetesHistoryDetails(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenPreviousReferralHistoryDetails should return the earlier referrals")
+ void getPreviousReferral_shouldReturnEarlierReferrals() throws Exception {
+ when(commonServiceImpl.getBenPreviousReferralData(BEN_REG_ID)).thenReturn("{}");
+
+ assertTrue(controller.getBenPreviousReferralHistoryDetails(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getProviderSpecificData should return the MMU data for the request")
+ void getProviderSpecificData_shouldReturnMmuData() throws Exception {
+ when(commonServiceImpl.getProviderSpecificData(BEN_REQUEST)).thenReturn("{}");
+
+ assertTrue(controller.getProviderSpecificData(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getProviderSpecificData should surface a service failure")
+ void getProviderSpecificData_shouldSurfaceServiceFailure() throws Exception {
+ when(commonServiceImpl.getProviderSpecificData(BEN_REQUEST))
+ .thenThrow(new IllegalStateException("mmu down"));
+
+ assertTrue(controller.getProviderSpecificData(BEN_REQUEST).contains("mmu down"));
+ }
+
+ @Test
+ @DisplayName("calculateBMIStatus should return the BMI classification")
+ void calculateBMIStatus_shouldReturnClassification() throws Exception {
+ when(commonNurseServiceImpl.calculateBMIStatus(BEN_REQUEST)).thenReturn("{\"bmiStatus\":\"Normal\"}");
+
+ assertTrue(controller.calculateBMIStatus(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("calculateBMIStatus should surface a service failure")
+ void calculateBMIStatus_shouldSurfaceServiceFailure() throws Exception {
+ when(commonNurseServiceImpl.calculateBMIStatus(BEN_REQUEST))
+ .thenThrow(new IllegalStateException("bmi failed"));
+
+ assertTrue(controller.calculateBMIStatus(BEN_REQUEST).contains("bmi failed"));
+ }
+
+ @Test
+ @DisplayName("saveBeneficiaryVisitDetail should confirm the submission to the nurse worklist")
+ void saveVisitDetail_shouldConfirmSubmission() {
+ when(commonNurseServiceImpl.updateBeneficiaryStatus('R', BEN_REG_ID)).thenReturn(1);
+
+ assertTrue(controller.saveBeneficiaryVisitDetail("{\"beneficiaryRegID\":11}")
+ .contains("Beneficiary Successfully Submitted to Nurse Work-List."));
+ }
+
+ @Test
+ @DisplayName("saveBeneficiaryVisitDetail should report a failure when the status was not changed")
+ void saveVisitDetail_shouldReportFailureWhenStatusUnchanged() {
+ when(commonNurseServiceImpl.updateBeneficiaryStatus('R', BEN_REG_ID)).thenReturn(0);
+
+ assertTrue(controller.saveBeneficiaryVisitDetail("{\"beneficiaryRegID\":11}")
+ .contains("Something went Wrong"));
+ }
+
+ @Test
+ @DisplayName("saveBeneficiaryVisitDetail should reject a request without the beneficiary id")
+ void saveVisitDetail_shouldRejectRequestWithoutBeneficiaryId() {
+ assertTrue(controller.saveBeneficiaryVisitDetail("{}")
+ .contains("Beneficiary Registration ID is Not valid !!!"));
+ }
+
+ @Test
+ @DisplayName("extendRedisSession should confirm the extended session")
+ void extendRedisSession_shouldConfirmExtendedSession() {
+ assertTrue(controller.extendRedisSession().contains("Session extended for 30 mins"));
+ }
+
+ @Test
+ @DisplayName("deletePrescribedMedicine should confirm the deletion")
+ void deletePrescribedMedicine_shouldConfirmDeletion() {
+ when(commonDoctorServiceImpl.deletePrescribedMedicine(any(org.json.JSONObject.class)))
+ .thenReturn("record deleted successfully");
+
+ assertTrue(controller.deletePrescribedMedicine("{\"id\":4}").contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("deletePrescribedMedicine should report a failure when nothing was deleted")
+ void deletePrescribedMedicine_shouldReportFailureWhenNothingDeleted() {
+ when(commonDoctorServiceImpl.deletePrescribedMedicine(any(org.json.JSONObject.class))).thenReturn(null);
+
+ assertTrue(controller.deletePrescribedMedicine("{\"id\":4}").contains("error while deleting record"));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/controller/common/master/CommonMasterControllerTest.java b/src/test/java/com/iemr/tm/controller/common/master/CommonMasterControllerTest.java
new file mode 100644
index 00000000..d48a7a84
--- /dev/null
+++ b/src/test/java/com/iemr/tm/controller/common/master/CommonMasterControllerTest.java
@@ -0,0 +1,95 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.controller.common.master;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import com.iemr.tm.service.common.master.CommonMasterServiceImpl;
+
+@ExtendWith(MockitoExtension.class)
+@DisplayName("CommonMasterController Test Suite")
+class CommonMasterControllerTest {
+
+ @Mock
+ private CommonMasterServiceImpl commonMasterServiceImpl;
+
+ private CommonMasterController controller;
+
+ @BeforeEach
+ @DisplayName("Wire the controller with a mocked master data service")
+ void setUp() {
+ controller = new CommonMasterController();
+ controller.setCommonMasterServiceImpl(commonMasterServiceImpl);
+ }
+
+ @Test
+ @DisplayName("getVisitReasonAndCategories should return the master data produced by the service")
+ void getVisitReasonAndCategories_shouldReturnMasterData() {
+ when(commonMasterServiceImpl.getVisitReasonAndCategories()).thenReturn("{\"visitCategories\":[]}");
+
+ String result = controller.getVisitReasonAndCategories();
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("visitCategories"));
+ }
+
+ @Test
+ @DisplayName("NurseMasterData should return the nurse master data for the requested category")
+ void nurseMasterData_shouldReturnNurseMasterData() {
+ when(commonMasterServiceImpl.getMasterDataForNurse(1, 2, "Female")).thenReturn("{\"nurseMaster\":[]}");
+
+ String result = controller.NurseMasterData(1, 2, "Female");
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("nurseMaster"));
+ }
+
+ @Test
+ @DisplayName("DoctorMasterData should return the doctor master data for the requested category")
+ void doctorMasterData_shouldReturnDoctorMasterData() {
+ when(commonMasterServiceImpl.getMasterDataForDoctor(1, 2, "Male", 3, 4)).thenReturn("{\"doctorMaster\":[]}");
+
+ String result = controller.DoctorMasterData(1, 2, "Male", 3, 4);
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("doctorMaster"));
+ }
+
+ @Test
+ @DisplayName("getECGAbnormalFindings should return the ECG findings master data")
+ void getECGAbnormalFindings_shouldReturnEcgFindings() {
+ when(commonMasterServiceImpl.getECGAbnormalFindings()).thenReturn("{\"ecgFindings\":[]}");
+
+ String result = controller.getECGAbnormalFindings();
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("ecgFindings"));
+ }
+}
diff --git a/src/test/java/com/iemr/tm/controller/covid19/CovidControllerTest.java b/src/test/java/com/iemr/tm/controller/covid19/CovidControllerTest.java
new file mode 100644
index 00000000..a5bf9af6
--- /dev/null
+++ b/src/test/java/com/iemr/tm/controller/covid19/CovidControllerTest.java
@@ -0,0 +1,320 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.controller.covid19;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.google.gson.JsonObject;
+import com.iemr.tm.service.covid19.Covid19ServiceImpl;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("CovidController Test Suite")
+class CovidControllerTest {
+
+ private static final String AUTHORIZATION = "Bearer session-token";
+ private static final Long BEN_REG_ID = 11L;
+ private static final Long VISIT_CODE = 22L;
+ private static final String REQUEST = "{\"beneficiaryRegID\":11,\"visitCode\":22}";
+ private static final String VISIT_REQUEST = "{\"benRegID\":11,\"visitCode\":22}";
+
+ @Mock
+ private Covid19ServiceImpl covid19ServiceImpl;
+
+ @InjectMocks
+ private CovidController controller;
+
+ @Nested
+ @DisplayName("saveBenNCDCareNurseData")
+ class SaveNurseTests {
+
+ @Test
+ @DisplayName("saveBenNCDCareNurseData should return the payload produced by the service")
+ void saveBenNCDCareNurseData_shouldReturnServicePayload() throws Exception {
+ when(covid19ServiceImpl.saveCovid19NurseData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn("{\"visitCode\":\"22\"}");
+
+ String result = controller.saveBenNCDCareNurseData(REQUEST, AUTHORIZATION);
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("visitCode"));
+ }
+
+ @Test
+ @DisplayName("saveBenNCDCareNurseData should roll back the visit details when the service fails")
+ void saveBenNCDCareNurseData_shouldRollBackVisitDetailsOnFailure() throws Exception {
+ when(covid19ServiceImpl.saveCovid19NurseData(any(JsonObject.class), eq(AUTHORIZATION)))
+ .thenThrow(new IllegalStateException("save failed"));
+
+ assertTrue(controller.saveBenNCDCareNurseData(REQUEST, AUTHORIZATION).contains("save failed"));
+ verify(covid19ServiceImpl).deleteVisitDetails(any(JsonObject.class));
+ }
+
+ @Test
+ @DisplayName("saveBenNCDCareNurseData should return the untouched failure response for a null request")
+ void saveBenNCDCareNurseData_shouldReturnGenericFailureForNullRequest() throws Exception {
+ assertTrue(controller.saveBenNCDCareNurseData(null, AUTHORIZATION).contains("Failed with generic error"));
+ verify(covid19ServiceImpl, never()).saveCovid19NurseData(any(JsonObject.class), anyString());
+ }
+ }
+
+ @Nested
+ @DisplayName("saveBenCovidDoctorData")
+ class SaveDoctorTests {
+
+ @Test
+ @DisplayName("saveBenCovidDoctorData should confirm the save when the service returns an id")
+ void saveBenCovidDoctorData_shouldConfirmSave() throws Exception {
+ when(covid19ServiceImpl.saveDoctorData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn(7L);
+
+ assertTrue(controller.saveBenCovidDoctorData(REQUEST, AUTHORIZATION).contains("Data saved successfully"));
+ }
+
+ @Test
+ @DisplayName("saveBenCovidDoctorData should report an unsuccessful save")
+ void saveBenCovidDoctorData_shouldReportUnsuccessfulSave() throws Exception {
+ when(covid19ServiceImpl.saveDoctorData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn(0L);
+
+ assertTrue(controller.saveBenCovidDoctorData(REQUEST, AUTHORIZATION).contains("Unable to save data"));
+ }
+
+ @Test
+ @DisplayName("saveBenCovidDoctorData should surface a service failure")
+ void saveBenCovidDoctorData_shouldSurfaceServiceFailure() throws Exception {
+ when(covid19ServiceImpl.saveDoctorData(any(JsonObject.class), eq(AUTHORIZATION)))
+ .thenThrow(new IllegalStateException("doctor save failed"));
+
+ assertTrue(controller.saveBenCovidDoctorData(REQUEST, AUTHORIZATION).contains("doctor save failed"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenVisitDetailsFrmNurseCovid")
+ class ReadVisitTests {
+
+ @Test
+ @DisplayName("getBenVisitDetailsFrmNurseCovid should return the details for a complete request")
+ void getBenVisitDetailsFrmNurseCovid19_shouldReturnDetails() throws Exception {
+ when(covid19ServiceImpl.getBenVisitDetailsFrmNurseCovid19(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenVisitDetailsFrmNurseCovid19(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenVisitDetailsFrmNurseCovid should reject an incomplete request")
+ void getBenVisitDetailsFrmNurseCovid19_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenVisitDetailsFrmNurseCovid19("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenVisitDetailsFrmNurseCovid should surface a service failure")
+ void getBenVisitDetailsFrmNurseCovid19_shouldSurfaceServiceFailure() throws Exception {
+ when(covid19ServiceImpl.getBenVisitDetailsFrmNurseCovid19(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenVisitDetailsFrmNurseCovid19(VISIT_REQUEST).contains("Error while getting beneficiary visit data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenCovidHistoryDetails")
+ class ReadHistoryTests {
+
+ @Test
+ @DisplayName("getBenCovidHistoryDetails should return the details for a complete request")
+ void getBenCovid19HistoryDetails_shouldReturnDetails() throws Exception {
+ when(covid19ServiceImpl.getBenCovid19HistoryDetails(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenCovid19HistoryDetails(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenCovidHistoryDetails should reject an incomplete request")
+ void getBenCovid19HistoryDetails_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenCovid19HistoryDetails("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenCovidHistoryDetails should surface a service failure")
+ void getBenCovid19HistoryDetails_shouldSurfaceServiceFailure() throws Exception {
+ when(covid19ServiceImpl.getBenCovid19HistoryDetails(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenCovid19HistoryDetails(VISIT_REQUEST).contains("Error while getting beneficiary history data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenVitalDetailsFrmNurseNCDCare")
+ class ReadVitalsTests {
+
+ @Test
+ @DisplayName("getBenVitalDetailsFrmNurseNCDCare should return the details for a complete request")
+ void getBenVitalDetailsFrmNurseNCDCare_shouldReturnDetails() throws Exception {
+ when(covid19ServiceImpl.getBeneficiaryVitalDetails(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenVitalDetailsFrmNurseNCDCare(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenVitalDetailsFrmNurseNCDCare should reject an incomplete request")
+ void getBenVitalDetailsFrmNurseNCDCare_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenVitalDetailsFrmNurseNCDCare("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenVitalDetailsFrmNurseNCDCare should surface a service failure")
+ void getBenVitalDetailsFrmNurseNCDCare_shouldSurfaceServiceFailure() throws Exception {
+ when(covid19ServiceImpl.getBeneficiaryVitalDetails(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenVitalDetailsFrmNurseNCDCare(VISIT_REQUEST).contains("Error while getting beneficiary vital data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenCaseRecordFromDoctorCovid")
+ class ReadCaseRecordTests {
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorCovid should return the details for a complete request")
+ void getBenCaseRecordFromDoctorCovid19_shouldReturnDetails() throws Exception {
+ when(covid19ServiceImpl.getBenCaseRecordFromDoctorCovid19(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenCaseRecordFromDoctorCovid19(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorCovid should reject an incomplete request")
+ void getBenCaseRecordFromDoctorCovid19_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenCaseRecordFromDoctorCovid19("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorCovid should surface a service failure")
+ void getBenCaseRecordFromDoctorCovid19_shouldSurfaceServiceFailure() throws Exception {
+ when(covid19ServiceImpl.getBenCaseRecordFromDoctorCovid19(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenCaseRecordFromDoctorCovid19(VISIT_REQUEST).contains("Error while getting beneficiary doctor data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("updateHistoryNurse")
+ class UpdateHistoryTests {
+
+ @Test
+ @DisplayName("updateHistoryNurse should confirm the update when a row was changed")
+ void updateHistoryNurse_shouldConfirmUpdate() throws Exception {
+ when(covid19ServiceImpl.updateBenHistoryDetails(any(JsonObject.class))).thenReturn(1);
+
+ assertTrue(controller.updateHistoryNurse(REQUEST).contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("updateHistoryNurse should report that nothing was modified")
+ void updateHistoryNurse_shouldReportNothingModified() throws Exception {
+ when(covid19ServiceImpl.updateBenHistoryDetails(any(JsonObject.class))).thenReturn(0);
+
+ assertTrue(controller.updateHistoryNurse(REQUEST).contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updateHistoryNurse should surface a service failure")
+ void updateHistoryNurse_shouldSurfaceServiceFailure() throws Exception {
+ when(covid19ServiceImpl.updateBenHistoryDetails(any(JsonObject.class))).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.updateHistoryNurse(REQUEST).contains("Unable to modify data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("updateVitalNurse")
+ class UpdateVitalsTests {
+
+ @Test
+ @DisplayName("updateVitalNurse should confirm the update when a row was changed")
+ void updateVitalNurse_shouldConfirmUpdate() throws Exception {
+ when(covid19ServiceImpl.updateBenVitalDetails(any(JsonObject.class))).thenReturn(1);
+
+ assertTrue(controller.updateVitalNurse(REQUEST).contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("updateVitalNurse should report that nothing was modified")
+ void updateVitalNurse_shouldReportNothingModified() throws Exception {
+ when(covid19ServiceImpl.updateBenVitalDetails(any(JsonObject.class))).thenReturn(0);
+
+ assertTrue(controller.updateVitalNurse(REQUEST).contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updateVitalNurse should surface a service failure")
+ void updateVitalNurse_shouldSurfaceServiceFailure() throws Exception {
+ when(covid19ServiceImpl.updateBenVitalDetails(any(JsonObject.class))).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.updateVitalNurse(REQUEST).contains("Unable to modify data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("updateCovidDoctorData")
+ class UpdateDoctorTests {
+
+ @Test
+ @DisplayName("updateCovidDoctorData should confirm the update when a row was changed")
+ void updateCovid19DoctorData_shouldConfirmUpdate() throws Exception {
+ when(covid19ServiceImpl.updateCovid19DoctorData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn(1L);
+
+ assertTrue(controller.updateCovid19DoctorData(REQUEST, AUTHORIZATION).contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("updateCovidDoctorData should report that nothing was modified")
+ void updateCovid19DoctorData_shouldReportNothingModified() throws Exception {
+ when(covid19ServiceImpl.updateCovid19DoctorData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn(0L);
+
+ assertTrue(controller.updateCovid19DoctorData(REQUEST, AUTHORIZATION).contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updateCovidDoctorData should surface a service failure")
+ void updateCovid19DoctorData_shouldSurfaceServiceFailure() throws Exception {
+ when(covid19ServiceImpl.updateCovid19DoctorData(any(JsonObject.class), eq(AUTHORIZATION)))
+ .thenThrow(new IllegalStateException("update failed"));
+
+ assertTrue(controller.updateCovid19DoctorData(REQUEST, AUTHORIZATION).contains("update failed"));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/controller/dataSyncActivity/StartSyncActivityTest.java b/src/test/java/com/iemr/tm/controller/dataSyncActivity/StartSyncActivityTest.java
new file mode 100644
index 00000000..afb65daa
--- /dev/null
+++ b/src/test/java/com/iemr/tm/controller/dataSyncActivity/StartSyncActivityTest.java
@@ -0,0 +1,216 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/package com.iemr.tm.controller.dataSyncActivity;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.service.dataSyncActivity.DownloadDataFromServerImpl;
+import com.iemr.tm.service.dataSyncActivity.UploadDataToServerImpl;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("StartSyncActivity Test Suite")
+class StartSyncActivityTest {
+
+ private static final String AUTHORIZATION = "Bearer session-token";
+ private static final String SERVER_AUTHORIZATION = "Bearer server-token";
+
+ @Mock
+ private UploadDataToServerImpl uploadDataToServerImpl;
+ @Mock
+ private DownloadDataFromServerImpl downloadDataFromServerImpl;
+
+ @InjectMocks
+ private StartSyncActivity controller;
+
+ @Nested
+ @DisplayName("van to server sync")
+ class VanToServerTests {
+
+ private static final String REQUEST = "{\"groupID\":3,\"user\":\"syncuser\"}";
+
+ @Test
+ @DisplayName("dataSyncToServer should return the uploaded payload")
+ void dataSyncToServer_shouldReturnUploadedPayload() throws Exception {
+ when(uploadDataToServerImpl.getDataToSyncToServer(3, "syncuser", SERVER_AUTHORIZATION))
+ .thenReturn("{\"synced\":true}");
+
+ String result = controller.dataSyncToServer(REQUEST, AUTHORIZATION, SERVER_AUTHORIZATION);
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("synced"));
+ }
+
+ @Test
+ @DisplayName("dataSyncToServer should report a sync the service could not complete")
+ void dataSyncToServer_shouldReportIncompleteSync() throws Exception {
+ when(uploadDataToServerImpl.getDataToSyncToServer(3, "syncuser", SERVER_AUTHORIZATION)).thenReturn(null);
+
+ assertTrue(controller.dataSyncToServer(REQUEST, AUTHORIZATION, SERVER_AUTHORIZATION)
+ .contains("Error in data sync"));
+ }
+
+ @Test
+ @DisplayName("dataSyncToServer should reject a request without a sync group or user")
+ void dataSyncToServer_shouldRejectRequestWithoutGroupOrUser() {
+ assertTrue(controller.dataSyncToServer("{}", AUTHORIZATION, SERVER_AUTHORIZATION)
+ .contains("Either of groupID or user is invalid or null"));
+ }
+
+ @Test
+ @DisplayName("dataSyncToServer should report a request it cannot act on")
+ void dataSyncToServer_shouldReportRequestItCannotActOn() {
+ assertTrue(controller.dataSyncToServer("not json", AUTHORIZATION, SERVER_AUTHORIZATION)
+ .contains("\"statusCode\""));
+ }
+
+ @Test
+ @DisplayName("getSyncGroupDetails should return the configured sync groups")
+ void getSyncGroupDetails_shouldReturnConfiguredGroups() throws Exception {
+ when(uploadDataToServerImpl.getDataSyncGroupDetails()).thenReturn("{\"groups\":[]}");
+
+ assertTrue(controller.getSyncGroupDetails().contains("groups"));
+ }
+
+ @Test
+ @DisplayName("getSyncGroupDetails should report groups the service could not read")
+ void getSyncGroupDetails_shouldReportUnreadableGroups() throws Exception {
+ when(uploadDataToServerImpl.getDataSyncGroupDetails()).thenReturn(null);
+
+ assertTrue(controller.getSyncGroupDetails().contains("Error in getting data sync group details"));
+ }
+
+ @Test
+ @DisplayName("getSyncGroupDetails should report a lookup it cannot complete")
+ void getSyncGroupDetails_shouldReportFailedLookup() throws Exception {
+ when(uploadDataToServerImpl.getDataSyncGroupDetails())
+ .thenThrow(new IllegalStateException("sync group table unavailable"));
+
+ assertTrue(controller.getSyncGroupDetails().contains("\"statusCode\""));
+ }
+ }
+
+ @Nested
+ @DisplayName("master download")
+ class MasterDownloadTests {
+
+ private static final String REQUEST = "{\"vanID\":7,\"providerServiceMapID\":9}";
+
+ @Test
+ @DisplayName("startMasterDownload should return the downloaded master payload")
+ void startMasterDownload_shouldReturnDownloadedPayload() throws Exception {
+ when(downloadDataFromServerImpl.downloadMasterDataFromServer(SERVER_AUTHORIZATION, 7, 9))
+ .thenReturn("done");
+
+ String result = controller.startMasterDownload(REQUEST, AUTHORIZATION, SERVER_AUTHORIZATION);
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("done"));
+ }
+
+ @Test
+ @DisplayName("startMasterDownload should report a download already running on another device")
+ void startMasterDownload_shouldReportDownloadAlreadyRunning() throws Exception {
+ when(downloadDataFromServerImpl.downloadMasterDataFromServer(SERVER_AUTHORIZATION, 7, 9))
+ .thenReturn("inProgress");
+
+ assertTrue(controller.startMasterDownload(REQUEST, AUTHORIZATION, SERVER_AUTHORIZATION)
+ .contains("Download is already in progress"));
+ }
+
+ @Test
+ @DisplayName("startMasterDownload should report a download the service could not start")
+ void startMasterDownload_shouldReportUnstartedDownload() throws Exception {
+ when(downloadDataFromServerImpl.downloadMasterDataFromServer(SERVER_AUTHORIZATION, 7, 9))
+ .thenReturn(null);
+
+ assertTrue(controller.startMasterDownload(REQUEST, AUTHORIZATION, SERVER_AUTHORIZATION)
+ .contains("\"statusCode\""));
+ }
+
+ @Test
+ @DisplayName("startMasterDownload should reject a request without a van or provider")
+ void startMasterDownload_shouldRejectRequestWithoutVanOrProvider() {
+ assertTrue(controller.startMasterDownload("{}", AUTHORIZATION, SERVER_AUTHORIZATION)
+ .contains("Kindly contact the administrator"));
+ }
+
+ @Test
+ @DisplayName("startMasterDownload should report a request it cannot act on")
+ void startMasterDownload_shouldReportRequestItCannotActOn() {
+ assertTrue(controller.startMasterDownload("not json", AUTHORIZATION, SERVER_AUTHORIZATION)
+ .contains("\"statusCode\""));
+ }
+
+ @Test
+ @DisplayName("checkMastersDownloadProgress should return the download status")
+ void checkMastersDownloadProgress_shouldReturnStatus() {
+ when(downloadDataFromServerImpl.getDownloadStatus()).thenReturn(new java.util.HashMap<>());
+
+ assertTrue(controller.checkMastersDownloadProgress().contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("checkMastersDownloadProgress should report a status it cannot read")
+ void checkMastersDownloadProgress_shouldReportUnreadableStatus() {
+ when(downloadDataFromServerImpl.getDownloadStatus())
+ .thenThrow(new IllegalStateException("status unavailable"));
+
+ assertTrue(controller.checkMastersDownloadProgress().contains("\"statusCode\""));
+ }
+
+ @Test
+ @DisplayName("getVanDetailsForMasterDownload should return the vans available to sync")
+ void getVanDetails_shouldReturnAvailableVans() throws Exception {
+ when(downloadDataFromServerImpl.getVanDetailsForMasterDownload()).thenReturn("{\"vans\":[]}");
+
+ assertTrue(controller.getVanDetailsForMasterDownload().contains("vans"));
+ }
+
+ @Test
+ @DisplayName("getVanDetailsForMasterDownload should report vans the service could not read")
+ void getVanDetails_shouldReportUnreadableVans() throws Exception {
+ when(downloadDataFromServerImpl.getVanDetailsForMasterDownload()).thenReturn(null);
+
+ assertTrue(controller.getVanDetailsForMasterDownload().contains("Error while getting van details"));
+ }
+
+ @Test
+ @DisplayName("getVanDetailsForMasterDownload should report a lookup it cannot complete")
+ void getVanDetails_shouldReportFailedLookup() throws Exception {
+ when(downloadDataFromServerImpl.getVanDetailsForMasterDownload())
+ .thenThrow(new IllegalStateException("van table unavailable"));
+
+ assertTrue(controller.getVanDetailsForMasterDownload().contains("\"statusCode\""));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/controller/dataSyncLayerCentral/MMUDataSyncVanToServerTest.java b/src/test/java/com/iemr/tm/controller/dataSyncLayerCentral/MMUDataSyncVanToServerTest.java
new file mode 100644
index 00000000..15c7672f
--- /dev/null
+++ b/src/test/java/com/iemr/tm/controller/dataSyncLayerCentral/MMUDataSyncVanToServerTest.java
@@ -0,0 +1,126 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/package com.iemr.tm.controller.dataSyncLayerCentral;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.data.syncActivity_syncLayer.SyncDownloadMaster;
+import com.iemr.tm.service.dataSyncLayerCentral.GetDataFromVanAndSyncToDBImpl;
+import com.iemr.tm.service.dataSyncLayerCentral.GetMasterDataFromCentralForVanImpl;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("MMUDataSyncVanToServer Test Suite")
+class MMUDataSyncVanToServerTest {
+
+ private static final String AUTHORIZATION = "Bearer session-token";
+ private static final String REQUEST = "{\"schemaName\":\"db_iemr\",\"tableName\":\"m_gender\"}";
+
+ @Mock
+ private GetDataFromVanAndSyncToDBImpl getDataFromVanAndSyncToDBImpl;
+ @Mock
+ private GetMasterDataFromCentralForVanImpl getMasterDataFromCentralForVanImpl;
+
+ @InjectMocks
+ private MMUDataSyncVanToServer controller;
+
+ private SyncDownloadMaster downloadRequest() {
+ SyncDownloadMaster request = new SyncDownloadMaster();
+ request.setSchemaName("db_iemr");
+ request.setTableName("m_gender");
+ return request;
+ }
+
+ @Test
+ @DisplayName("dataSyncToServer should return the synced payload")
+ void dataSyncToServer_shouldReturnSyncedPayload() throws Exception {
+ when(getDataFromVanAndSyncToDBImpl.syncDataToServer(REQUEST, AUTHORIZATION)).thenReturn("{\"synced\":true}");
+
+ String result = controller.dataSyncToServer(REQUEST, AUTHORIZATION);
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("synced"));
+ }
+
+ @Test
+ @DisplayName("dataSyncToServer should report a sync the service could not complete")
+ void dataSyncToServer_shouldReportIncompleteSync() throws Exception {
+ when(getDataFromVanAndSyncToDBImpl.syncDataToServer(REQUEST, AUTHORIZATION)).thenReturn(null);
+
+ assertTrue(controller.dataSyncToServer(REQUEST, AUTHORIZATION).contains("data dync failed"));
+ }
+
+ @Test
+ @DisplayName("dataSyncToServer should report a request it cannot act on")
+ void dataSyncToServer_shouldReportRequestItCannotActOn() throws Exception {
+ when(getDataFromVanAndSyncToDBImpl.syncDataToServer(REQUEST, AUTHORIZATION))
+ .thenThrow(new IllegalStateException("sync failed"));
+
+ assertTrue(controller.dataSyncToServer(REQUEST, AUTHORIZATION).contains("\"statusCode\""));
+ }
+
+ @Test
+ @DisplayName("dataDownloadFromServer should return the requested master table")
+ void dataDownloadFromServer_shouldReturnRequestedTable() throws Exception {
+ when(getMasterDataFromCentralForVanImpl.getMasterDataForVan(org.mockito.ArgumentMatchers.any()))
+ .thenReturn("{\"rows\":[]}");
+
+ String result = controller.dataDownloadFromServer(downloadRequest(), AUTHORIZATION);
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("rows"));
+ }
+
+ @Test
+ @DisplayName("dataDownloadFromServer should name the table it could not download")
+ void dataDownloadFromServer_shouldNameUndownloadableTable() throws Exception {
+ when(getMasterDataFromCentralForVanImpl.getMasterDataForVan(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(null);
+
+ assertTrue(controller.dataDownloadFromServer(downloadRequest(), AUTHORIZATION)
+ .contains("db_iemr.m_gender"));
+ }
+
+ @Test
+ @DisplayName("dataDownloadFromServer should reject a request with no table to download")
+ void dataDownloadFromServer_shouldRejectEmptyRequest() {
+ assertTrue(controller.dataDownloadFromServer(null, AUTHORIZATION).contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("dataDownloadFromServer should report a download it cannot complete")
+ void dataDownloadFromServer_shouldReportFailedDownload() throws Exception {
+ when(getMasterDataFromCentralForVanImpl.getMasterDataForVan(org.mockito.ArgumentMatchers.any()))
+ .thenThrow(new IllegalStateException("central database unavailable"));
+
+ assertTrue(controller.dataDownloadFromServer(downloadRequest(), AUTHORIZATION).contains("\"statusCode\""));
+ }
+}
diff --git a/src/test/java/com/iemr/tm/controller/foetalmonitor/FoetalMonitorControllerTest.java b/src/test/java/com/iemr/tm/controller/foetalmonitor/FoetalMonitorControllerTest.java
new file mode 100644
index 00000000..00b974e2
--- /dev/null
+++ b/src/test/java/com/iemr/tm/controller/foetalmonitor/FoetalMonitorControllerTest.java
@@ -0,0 +1,239 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.controller.foetalmonitor;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+
+import com.iemr.tm.data.foetalmonitor.FoetalMonitor;
+import com.iemr.tm.service.foetalmonitor.FoetalMonitorService;
+import com.iemr.tm.utils.exception.IEMRException;
+
+@ExtendWith(MockitoExtension.class)
+@DisplayName("FoetalMonitorController Test Suite")
+class FoetalMonitorControllerTest {
+
+ private static final String AUTHORIZATION = "Bearer session-token";
+ private static final String TEST_REQUEST = "{\"beneficiaryRegID\":11,\"motherName\":\"Asha\"}";
+
+ @Mock
+ private FoetalMonitorService foetalMonitorService;
+
+ @InjectMocks
+ private FoetalMonitorController controller;
+
+ @Nested
+ @DisplayName("sendANCMotherTestDetailsToFoetalMonitor")
+ class SendTestDetailsTests {
+
+ @Test
+ @DisplayName("sendANCMotherTestDetailsToFoetalMonitor should return 200 with the device response")
+ void sendTestDetails_shouldReturnDeviceResponse() throws Exception {
+ when(foetalMonitorService.sendFoetalMonitorTestDetails(any(FoetalMonitor.class), eq(AUTHORIZATION)))
+ .thenReturn("{\"fetosenseTestId\":9}");
+
+ ResponseEntity result = controller.sendANCMotherTestDetailsToFoetalMonitor(TEST_REQUEST,
+ AUTHORIZATION);
+
+ assertEquals(HttpStatus.OK, result.getStatusCode());
+ assertTrue(result.getBody().contains("fetosenseTestId"));
+ }
+
+ @Test
+ @DisplayName("sendANCMotherTestDetailsToFoetalMonitor should reject a null request")
+ void sendTestDetails_shouldRejectNullRequest() throws Exception {
+ ResponseEntity result = controller.sendANCMotherTestDetailsToFoetalMonitor(null, AUTHORIZATION);
+
+ assertEquals(HttpStatus.BAD_REQUEST, result.getStatusCode());
+ assertTrue(result.getBody().contains("Invalid request"));
+ verify(foetalMonitorService, never()).sendFoetalMonitorTestDetails(any(FoetalMonitor.class), anyString());
+ }
+
+ @Test
+ @DisplayName("sendANCMotherTestDetailsToFoetalMonitor should surface a service failure")
+ void sendTestDetails_shouldSurfaceServiceFailure() throws Exception {
+ when(foetalMonitorService.sendFoetalMonitorTestDetails(any(FoetalMonitor.class), eq(AUTHORIZATION)))
+ .thenThrow(new IllegalStateException("device unreachable"));
+
+ ResponseEntity result = controller.sendANCMotherTestDetailsToFoetalMonitor(TEST_REQUEST,
+ AUTHORIZATION);
+
+ assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, result.getStatusCode());
+ assertTrue(result.getBody().contains("device unreachable"));
+ }
+ }
+
+ @Test
+ @DisplayName("saveMother should acknowledge that the device test is in progress")
+ void saveMother_shouldAcknowledgeTestInProgress() {
+ assertTrue(controller.saveMother(TEST_REQUEST, AUTHORIZATION).contains("Test in progress"));
+ }
+
+ @Nested
+ @DisplayName("getFoetalMonitorDetails")
+ class GetDetailsTests {
+
+ @Test
+ @DisplayName("getFoetalMonitorDetails should return the monitor details for the flow")
+ void getFoetalMonitorDetails_shouldReturnDetails() throws Exception {
+ when(foetalMonitorService.getFoetalMonitorDetails(11L)).thenReturn("{\"benFlowID\":11}");
+
+ assertTrue(controller.getFoetalMonitorDetails(11L).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getFoetalMonitorDetails should report a failure when nothing comes back")
+ void getFoetalMonitorDetails_shouldReportFailureWhenNothingFound() throws Exception {
+ when(foetalMonitorService.getFoetalMonitorDetails(11L)).thenReturn(null);
+
+ assertTrue(controller.getFoetalMonitorDetails(11L).contains("Error in fetching the details"));
+ }
+
+ @Test
+ @DisplayName("getFoetalMonitorDetails should surface a service failure")
+ void getFoetalMonitorDetails_shouldSurfaceServiceFailure() throws Exception {
+ when(foetalMonitorService.getFoetalMonitorDetails(11L)).thenThrow(new IEMRException("db down"));
+
+ assertTrue(controller.getFoetalMonitorDetails(11L).contains("db down"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getFoetalMonitorDetails report graph")
+ class ReportGraphTests {
+
+ private FoetalMonitor request() {
+ FoetalMonitor request = new FoetalMonitor();
+ request.setaMRITFilePath("/reports/test.pdf");
+ return request;
+ }
+
+ @Test
+ @DisplayName("the report endpoint should return the base64 encoded report")
+ void reportGraph_shouldReturnBase64Report() throws Exception {
+ when(foetalMonitorService.readPDFANDGetBase64("/reports/test.pdf")).thenReturn("base64-report");
+
+ ResponseEntity result = controller.getFoetalMonitorDetails(request());
+
+ assertEquals(HttpStatus.OK, result.getStatusCode());
+ assertTrue(result.getBody().contains("base64-report"));
+ }
+
+ @Test
+ @DisplayName("the report endpoint should report a failure when no report comes back")
+ void reportGraph_shouldReportFailureWhenNoReport() throws Exception {
+ when(foetalMonitorService.readPDFANDGetBase64("/reports/test.pdf")).thenReturn(null);
+
+ assertTrue(controller.getFoetalMonitorDetails(request()).getBody()
+ .contains("Error in fetching the details"));
+ }
+
+ @Test
+ @DisplayName("the report endpoint should report a missing report file")
+ void reportGraph_shouldReportMissingFile() throws Exception {
+ when(foetalMonitorService.readPDFANDGetBase64("/reports/test.pdf"))
+ .thenThrow(new FileNotFoundException("test.pdf"));
+
+ assertTrue(controller.getFoetalMonitorDetails(request()).getBody().contains("File not found"));
+ }
+
+ @Test
+ @DisplayName("the report endpoint should report a read failure")
+ void reportGraph_shouldReportReadFailure() throws Exception {
+ when(foetalMonitorService.readPDFANDGetBase64("/reports/test.pdf")).thenThrow(new IOException("disk error"));
+
+ assertTrue(controller.getFoetalMonitorDetails(request()).getBody().contains("File not found"));
+ }
+
+ @Test
+ @DisplayName("the report endpoint should surface a service failure")
+ void reportGraph_shouldSurfaceServiceFailure() throws Exception {
+ when(foetalMonitorService.readPDFANDGetBase64("/reports/test.pdf")).thenThrow(new IEMRException("db down"));
+
+ assertTrue(controller.getFoetalMonitorDetails(request()).getBody().contains("db down"));
+ }
+ }
+
+ @Nested
+ @DisplayName("updateFoetalMonitorData")
+ class UpdateTests {
+
+ @Test
+ @DisplayName("updateFoetalMonitorData should confirm the update when a row was changed")
+ void updateFoetalMonitorData_shouldConfirmUpdate() throws Exception {
+ when(foetalMonitorService.updateFoetalMonitorData(any(FoetalMonitor.class))).thenReturn(1);
+
+ ResponseEntity result = controller.updateFoetalMonitorData(TEST_REQUEST, AUTHORIZATION);
+
+ assertEquals(HttpStatus.OK, result.getStatusCode());
+ assertTrue(result.getBody().contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("updateFoetalMonitorData should leave the generic failure when no row was changed")
+ void updateFoetalMonitorData_shouldLeaveGenericFailureWhenNothingChanged() throws Exception {
+ when(foetalMonitorService.updateFoetalMonitorData(any(FoetalMonitor.class))).thenReturn(0);
+
+ ResponseEntity result = controller.updateFoetalMonitorData(TEST_REQUEST, AUTHORIZATION);
+
+ assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, result.getStatusCode());
+ }
+
+ @Test
+ @DisplayName("updateFoetalMonitorData should reject a null request")
+ void updateFoetalMonitorData_shouldRejectNullRequest() throws Exception {
+ ResponseEntity result = controller.updateFoetalMonitorData(null, AUTHORIZATION);
+
+ assertEquals(HttpStatus.BAD_REQUEST, result.getStatusCode());
+ assertTrue(result.getBody().contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("updateFoetalMonitorData should surface a service failure")
+ void updateFoetalMonitorData_shouldSurfaceServiceFailure() throws Exception {
+ when(foetalMonitorService.updateFoetalMonitorData(any(FoetalMonitor.class)))
+ .thenThrow(new IEMRException("update failed"));
+
+ assertTrue(controller.updateFoetalMonitorData(TEST_REQUEST, AUTHORIZATION).getBody()
+ .contains("update failed"));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/controller/generalOPD/GeneralOPDControllerTest.java b/src/test/java/com/iemr/tm/controller/generalOPD/GeneralOPDControllerTest.java
new file mode 100644
index 00000000..8b54c5f2
--- /dev/null
+++ b/src/test/java/com/iemr/tm/controller/generalOPD/GeneralOPDControllerTest.java
@@ -0,0 +1,405 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.controller.generalOPD;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.google.gson.JsonObject;
+import com.iemr.tm.service.generalOPD.GeneralOPDService;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("GeneralOPDController Test Suite")
+class GeneralOPDControllerTest {
+
+ private static final String AUTHORIZATION = "Bearer session-token";
+ private static final Long BEN_REG_ID = 11L;
+ private static final Long VISIT_CODE = 22L;
+ private static final String REQUEST = "{\"beneficiaryRegID\":11,\"visitCode\":22}";
+ private static final String VISIT_REQUEST = "{\"benRegID\":11,\"visitCode\":22}";
+
+ @Mock
+ private GeneralOPDService generalOPDService;
+
+ @InjectMocks
+ private GeneralOPDController controller;
+
+ @Nested
+ @DisplayName("saveBenGenOPDNurseData")
+ class SaveNurseTests {
+
+ @Test
+ @DisplayName("saveBenGenOPDNurseData should return the payload produced by the service")
+ void saveBenGenOPDNurseData_shouldReturnServicePayload() throws Exception {
+ when(generalOPDService.saveNurseData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn("{\"visitCode\":\"22\"}");
+
+ String result = controller.saveBenGenOPDNurseData(REQUEST, AUTHORIZATION);
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("visitCode"));
+ }
+
+ @Test
+ @DisplayName("saveBenGenOPDNurseData should roll back the visit details when the service fails")
+ void saveBenGenOPDNurseData_shouldRollBackVisitDetailsOnFailure() throws Exception {
+ when(generalOPDService.saveNurseData(any(JsonObject.class), eq(AUTHORIZATION)))
+ .thenThrow(new IllegalStateException("save failed"));
+
+ assertTrue(controller.saveBenGenOPDNurseData(REQUEST, AUTHORIZATION).contains("save failed"));
+ verify(generalOPDService).deleteVisitDetails(any(JsonObject.class));
+ }
+
+ @Test
+ @DisplayName("saveBenGenOPDNurseData should return the untouched failure response for a null request")
+ void saveBenGenOPDNurseData_shouldReturnGenericFailureForNullRequest() throws Exception {
+ assertTrue(controller.saveBenGenOPDNurseData(null, AUTHORIZATION).contains("Failed with generic error"));
+ verify(generalOPDService, never()).saveNurseData(any(JsonObject.class), anyString());
+ }
+ }
+
+ @Nested
+ @DisplayName("saveBenGenOPDDoctorData")
+ class SaveDoctorTests {
+
+ @Test
+ @DisplayName("saveBenGenOPDDoctorData should confirm the save when the service returns an id")
+ void saveBenGenOPDDoctorData_shouldConfirmSave() throws Exception {
+ when(generalOPDService.saveDoctorData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn(7L);
+
+ assertTrue(controller.saveBenGenOPDDoctorData(REQUEST, AUTHORIZATION).contains("Data saved successfully"));
+ }
+
+ @Test
+ @DisplayName("saveBenGenOPDDoctorData should report an unsuccessful save")
+ void saveBenGenOPDDoctorData_shouldReportUnsuccessfulSave() throws Exception {
+ when(generalOPDService.saveDoctorData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn(0L);
+
+ assertTrue(controller.saveBenGenOPDDoctorData(REQUEST, AUTHORIZATION).contains("Unable to save data"));
+ }
+
+ @Test
+ @DisplayName("saveBenGenOPDDoctorData should surface a service failure")
+ void saveBenGenOPDDoctorData_shouldSurfaceServiceFailure() throws Exception {
+ when(generalOPDService.saveDoctorData(any(JsonObject.class), eq(AUTHORIZATION)))
+ .thenThrow(new IllegalStateException("doctor save failed"));
+
+ assertTrue(controller.saveBenGenOPDDoctorData(REQUEST, AUTHORIZATION).contains("doctor save failed"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenVisitDetailsFrmNurseGOPD")
+ class ReadVisitTests {
+
+ @Test
+ @DisplayName("getBenVisitDetailsFrmNurseGOPD should return the details for a complete request")
+ void getBenVisitDetailsFrmNurseGOPD_shouldReturnDetails() throws Exception {
+ when(generalOPDService.getBenVisitDetailsFrmNurseGOPD(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenVisitDetailsFrmNurseGOPD(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenVisitDetailsFrmNurseGOPD should reject an incomplete request")
+ void getBenVisitDetailsFrmNurseGOPD_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenVisitDetailsFrmNurseGOPD("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenVisitDetailsFrmNurseGOPD should surface a service failure")
+ void getBenVisitDetailsFrmNurseGOPD_shouldSurfaceServiceFailure() throws Exception {
+ when(generalOPDService.getBenVisitDetailsFrmNurseGOPD(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenVisitDetailsFrmNurseGOPD(VISIT_REQUEST).contains("Error while getting beneficiary visit data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenHistoryDetails")
+ class ReadHistoryTests {
+
+ @Test
+ @DisplayName("getBenHistoryDetails should return the details for a complete request")
+ void getBenHistoryDetails_shouldReturnDetails() throws Exception {
+ when(generalOPDService.getBenHistoryDetails(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenHistoryDetails(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenHistoryDetails should reject an incomplete request")
+ void getBenHistoryDetails_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenHistoryDetails("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenHistoryDetails should surface a service failure")
+ void getBenHistoryDetails_shouldSurfaceServiceFailure() throws Exception {
+ when(generalOPDService.getBenHistoryDetails(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenHistoryDetails(VISIT_REQUEST).contains("Error while getting beneficiary history data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenVitalDetailsFrmNurse")
+ class ReadVitalsTests {
+
+ @Test
+ @DisplayName("getBenVitalDetailsFrmNurse should return the details for a complete request")
+ void getBenVitalDetailsFrmNurse_shouldReturnDetails() throws Exception {
+ when(generalOPDService.getBeneficiaryVitalDetails(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenVitalDetailsFrmNurse(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenVitalDetailsFrmNurse should reject an incomplete request")
+ void getBenVitalDetailsFrmNurse_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenVitalDetailsFrmNurse("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenVitalDetailsFrmNurse should surface a service failure")
+ void getBenVitalDetailsFrmNurse_shouldSurfaceServiceFailure() throws Exception {
+ when(generalOPDService.getBeneficiaryVitalDetails(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenVitalDetailsFrmNurse(VISIT_REQUEST).contains("Error while getting beneficiary vital data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenExaminationDetails")
+ class ReadExaminationTests {
+
+ @Test
+ @DisplayName("getBenExaminationDetails should return the details for a complete request")
+ void getBenExaminationDetails_shouldReturnDetails() throws Exception {
+ when(generalOPDService.getExaminationDetailsData(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenExaminationDetails(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenExaminationDetails should reject an incomplete request")
+ void getBenExaminationDetails_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenExaminationDetails("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenExaminationDetails should surface a service failure")
+ void getBenExaminationDetails_shouldSurfaceServiceFailure() throws Exception {
+ when(generalOPDService.getExaminationDetailsData(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenExaminationDetails(VISIT_REQUEST).contains("Error while getting beneficiary examination data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenCaseRecordFromDoctorGeneralOPD")
+ class ReadCaseRecordTests {
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorGeneralOPD should return the details for a complete request")
+ void getBenCaseRecordFromDoctorGeneralOPD_shouldReturnDetails() throws Exception {
+ when(generalOPDService.getBenCaseRecordFromDoctorGeneralOPD(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenCaseRecordFromDoctorGeneralOPD(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorGeneralOPD should reject an incomplete request")
+ void getBenCaseRecordFromDoctorGeneralOPD_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenCaseRecordFromDoctorGeneralOPD("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorGeneralOPD should surface a service failure")
+ void getBenCaseRecordFromDoctorGeneralOPD_shouldSurfaceServiceFailure() throws Exception {
+ when(generalOPDService.getBenCaseRecordFromDoctorGeneralOPD(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenCaseRecordFromDoctorGeneralOPD(VISIT_REQUEST).contains("Error while getting beneficiary doctor data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("updateVisitNurse")
+ class UpdateVisitTests {
+
+ @Test
+ @DisplayName("updateVisitNurse should confirm the update when a row was changed")
+ void updateVisitNurse_shouldConfirmUpdate() throws Exception {
+ when(generalOPDService.UpdateVisitDetails(any(JsonObject.class))).thenReturn(1);
+
+ assertTrue(controller.updateVisitNurse(REQUEST).contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("updateVisitNurse should report that nothing was modified")
+ void updateVisitNurse_shouldReportNothingModified() throws Exception {
+ when(generalOPDService.UpdateVisitDetails(any(JsonObject.class))).thenReturn(0);
+
+ assertTrue(controller.updateVisitNurse(REQUEST).contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updateVisitNurse should surface a service failure")
+ void updateVisitNurse_shouldSurfaceServiceFailure() throws Exception {
+ when(generalOPDService.UpdateVisitDetails(any(JsonObject.class))).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.updateVisitNurse(REQUEST).contains("Unable to modify data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("updateHistoryNurse")
+ class UpdateHistoryTests {
+
+ @Test
+ @DisplayName("updateHistoryNurse should confirm the update when a row was changed")
+ void updateHistoryNurse_shouldConfirmUpdate() throws Exception {
+ when(generalOPDService.updateBenHistoryDetails(any(JsonObject.class))).thenReturn(1);
+
+ assertTrue(controller.updateHistoryNurse(REQUEST).contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("updateHistoryNurse should report that nothing was modified")
+ void updateHistoryNurse_shouldReportNothingModified() throws Exception {
+ when(generalOPDService.updateBenHistoryDetails(any(JsonObject.class))).thenReturn(0);
+
+ assertTrue(controller.updateHistoryNurse(REQUEST).contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updateHistoryNurse should surface a service failure")
+ void updateHistoryNurse_shouldSurfaceServiceFailure() throws Exception {
+ when(generalOPDService.updateBenHistoryDetails(any(JsonObject.class))).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.updateHistoryNurse(REQUEST).contains("Unable to modify data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("updateVitalNurse")
+ class UpdateVitalsTests {
+
+ @Test
+ @DisplayName("updateVitalNurse should confirm the update when a row was changed")
+ void updateVitalNurse_shouldConfirmUpdate() throws Exception {
+ when(generalOPDService.updateBenVitalDetails(any(JsonObject.class))).thenReturn(1);
+
+ assertTrue(controller.updateVitalNurse(REQUEST).contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("updateVitalNurse should report that nothing was modified")
+ void updateVitalNurse_shouldReportNothingModified() throws Exception {
+ when(generalOPDService.updateBenVitalDetails(any(JsonObject.class))).thenReturn(0);
+
+ assertTrue(controller.updateVitalNurse(REQUEST).contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updateVitalNurse should surface a service failure")
+ void updateVitalNurse_shouldSurfaceServiceFailure() throws Exception {
+ when(generalOPDService.updateBenVitalDetails(any(JsonObject.class))).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.updateVitalNurse(REQUEST).contains("Unable to modify data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("updateGeneralOPDExaminationNurse")
+ class UpdateExaminationTests {
+
+ @Test
+ @DisplayName("updateGeneralOPDExaminationNurse should confirm the update when a row was changed")
+ void updateGeneralOPDExaminationNurse_shouldConfirmUpdate() throws Exception {
+ when(generalOPDService.updateBenExaminationDetails(any(JsonObject.class))).thenReturn(1);
+
+ assertTrue(controller.updateGeneralOPDExaminationNurse(REQUEST).contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("updateGeneralOPDExaminationNurse should report that nothing was modified")
+ void updateGeneralOPDExaminationNurse_shouldReportNothingModified() throws Exception {
+ when(generalOPDService.updateBenExaminationDetails(any(JsonObject.class))).thenReturn(0);
+
+ assertTrue(controller.updateGeneralOPDExaminationNurse(REQUEST).contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updateGeneralOPDExaminationNurse should surface a service failure")
+ void updateGeneralOPDExaminationNurse_shouldSurfaceServiceFailure() throws Exception {
+ when(generalOPDService.updateBenExaminationDetails(any(JsonObject.class))).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.updateGeneralOPDExaminationNurse(REQUEST).contains("Unable to modify data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("updateGeneralOPDDoctorData")
+ class UpdateDoctorTests {
+
+ @Test
+ @DisplayName("updateGeneralOPDDoctorData should confirm the update when a row was changed")
+ void updateGeneralOPDDoctorData_shouldConfirmUpdate() throws Exception {
+ when(generalOPDService.updateGeneralOPDDoctorData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn(1L);
+
+ assertTrue(controller.updateGeneralOPDDoctorData(REQUEST, AUTHORIZATION).contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("updateGeneralOPDDoctorData should report that nothing was modified")
+ void updateGeneralOPDDoctorData_shouldReportNothingModified() throws Exception {
+ when(generalOPDService.updateGeneralOPDDoctorData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn(0L);
+
+ assertTrue(controller.updateGeneralOPDDoctorData(REQUEST, AUTHORIZATION).contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updateGeneralOPDDoctorData should surface a service failure")
+ void updateGeneralOPDDoctorData_shouldSurfaceServiceFailure() throws Exception {
+ when(generalOPDService.updateGeneralOPDDoctorData(any(JsonObject.class), eq(AUTHORIZATION)))
+ .thenThrow(new IllegalStateException("update failed"));
+
+ assertTrue(controller.updateGeneralOPDDoctorData(REQUEST, AUTHORIZATION).contains("update failed"));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/controller/health/HealthControllerTest.java b/src/test/java/com/iemr/tm/controller/health/HealthControllerTest.java
new file mode 100644
index 00000000..df0c1d2f
--- /dev/null
+++ b/src/test/java/com/iemr/tm/controller/health/HealthControllerTest.java
@@ -0,0 +1,106 @@
+/*
+* AMRIT - Accessible Medical Records via Integrated Technologies
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.controller.health;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import com.iemr.tm.service.health.HealthService;
+
+import static org.mockito.Mockito.when;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@ExtendWith(MockitoExtension.class)
+@DisplayName("HealthController Test Suite")
+class HealthControllerTest {
+
+ @Mock
+ private HealthService healthService;
+
+ private MockMvc mockMvc;
+
+ @BeforeEach
+ @DisplayName("Set up standalone MockMvc before each test")
+ void setUp() {
+ mockMvc = MockMvcBuilders.standaloneSetup(new HealthController(healthService)).build();
+ }
+
+ private Map healthResponse(String overallStatus) {
+ Map response = new LinkedHashMap<>();
+ response.put("status", overallStatus);
+ response.put("checkedAt", "2025-06-25T10:00:00Z");
+ return response;
+ }
+
+ @Test
+ @DisplayName("checkHealth should return 200 with the payload when all services are UP")
+ void checkHealth_shouldReturnOkWhenStatusIsUp() throws Exception {
+ when(healthService.checkHealth()).thenReturn(healthResponse("UP"));
+
+ mockMvc.perform(get("/health"))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$.status").value("UP"))
+ .andExpect(jsonPath("$.checkedAt").value("2025-06-25T10:00:00Z"));
+ }
+
+ @Test
+ @DisplayName("checkHealth should return 200 when DEGRADED, since the instance is still operational")
+ void checkHealth_shouldReturnOkWhenStatusIsDegraded() throws Exception {
+ when(healthService.checkHealth()).thenReturn(healthResponse("DEGRADED"));
+
+ mockMvc.perform(get("/health"))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$.status").value("DEGRADED"));
+ }
+
+ @Test
+ @DisplayName("checkHealth should return 503 when a critical service is DOWN")
+ void checkHealth_shouldReturnServiceUnavailableWhenStatusIsDown() throws Exception {
+ when(healthService.checkHealth()).thenReturn(healthResponse("DOWN"));
+
+ mockMvc.perform(get("/health"))
+ .andExpect(status().isServiceUnavailable())
+ .andExpect(jsonPath("$.status").value("DOWN"));
+ }
+
+ @Test
+ @DisplayName("checkHealth should return 503 with a DOWN payload when the service throws unexpectedly")
+ void checkHealth_shouldReturnServiceUnavailableWhenServiceThrows() throws Exception {
+ when(healthService.checkHealth()).thenThrow(new IllegalStateException("unexpected failure"));
+
+ mockMvc.perform(get("/health"))
+ .andExpect(status().isServiceUnavailable())
+ .andExpect(jsonPath("$.status").value("DOWN"))
+ .andExpect(jsonPath("$.timestamp").exists());
+ }
+}
diff --git a/src/test/java/com/iemr/tm/controller/labtechnician/LabtechnicianControllerTest.java b/src/test/java/com/iemr/tm/controller/labtechnician/LabtechnicianControllerTest.java
new file mode 100644
index 00000000..6b83c4aa
--- /dev/null
+++ b/src/test/java/com/iemr/tm/controller/labtechnician/LabtechnicianControllerTest.java
@@ -0,0 +1,196 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.controller.labtechnician;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import com.google.gson.JsonObject;
+import com.iemr.tm.service.labtechnician.LabTechnicianServiceImpl;
+
+@ExtendWith(MockitoExtension.class)
+@DisplayName("LabtechnicianController Test Suite")
+class LabtechnicianControllerTest {
+
+ private static final String VISIT_REQUEST = "{\"beneficiaryRegID\":11,\"visitCode\":22}";
+
+ @Mock
+ private LabTechnicianServiceImpl labTechnicianServiceImpl;
+
+ private LabtechnicianController controller;
+
+ @BeforeEach
+ @DisplayName("Wire the controller with a mocked lab technician service")
+ void setUp() {
+ controller = new LabtechnicianController();
+ controller.setLabTechnicianServiceImpl(labTechnicianServiceImpl);
+ }
+
+ @Nested
+ @DisplayName("saveLabTestResult")
+ class SaveLabTestResultTests {
+
+ @Test
+ @DisplayName("saveLabTestResult should confirm the save when rows were written")
+ void saveLabTestResult_shouldConfirmSave() throws Exception {
+ when(labTechnicianServiceImpl.saveLabTestResult(any(JsonObject.class))).thenReturn(1);
+
+ assertTrue(controller.saveLabTestResult("{\"visitCode\":22}").contains("Data saved successfully"));
+ }
+
+ @Test
+ @DisplayName("saveLabTestResult should report an unsuccessful save")
+ void saveLabTestResult_shouldReportUnsuccessfulSave() throws Exception {
+ when(labTechnicianServiceImpl.saveLabTestResult(any(JsonObject.class))).thenReturn(0);
+
+ assertTrue(controller.saveLabTestResult("{\"visitCode\":22}").contains("Unable to save data"));
+ }
+
+ @Test
+ @DisplayName("saveLabTestResult should report an unsuccessful save when no count comes back")
+ void saveLabTestResult_shouldReportUnsuccessfulSaveForNullCount() throws Exception {
+ when(labTechnicianServiceImpl.saveLabTestResult(any(JsonObject.class))).thenReturn(null);
+
+ assertTrue(controller.saveLabTestResult("{\"visitCode\":22}").contains("Unable to save data"));
+ }
+
+ @Test
+ @DisplayName("saveLabTestResult should surface a service failure")
+ void saveLabTestResult_shouldSurfaceServiceFailure() throws Exception {
+ when(labTechnicianServiceImpl.saveLabTestResult(any(JsonObject.class)))
+ .thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.saveLabTestResult("{\"visitCode\":22}").contains("Unable to save data"));
+ }
+
+ @Test
+ @DisplayName("saveLabTestResult should surface a malformed request")
+ void saveLabTestResult_shouldSurfaceMalformedRequest() {
+ assertTrue(controller.saveLabTestResult("not-json").contains("Unable to save data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBeneficiaryPrescribedProcedure")
+ class PrescribedProcedureTests {
+
+ @Test
+ @DisplayName("getBeneficiaryPrescribedProcedure should return the prescribed procedures")
+ void getBeneficiaryPrescribedProcedure_shouldReturnProcedures() throws Exception {
+ when(labTechnicianServiceImpl.getBenePrescribedProcedureDetails(11L, 22L)).thenReturn("[{\"procedure\":1}]");
+
+ assertTrue(controller.getBeneficiaryPrescribedProcedure(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryPrescribedProcedure should report a failure when nothing comes back")
+ void getBeneficiaryPrescribedProcedure_shouldReportFailureWhenNothingFound() throws Exception {
+ when(labTechnicianServiceImpl.getBenePrescribedProcedureDetails(11L, 22L)).thenReturn(null);
+
+ assertTrue(controller.getBeneficiaryPrescribedProcedure(VISIT_REQUEST)
+ .contains("Error in prescribed procedure details"));
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryPrescribedProcedure should reject a request without the visit code")
+ void getBeneficiaryPrescribedProcedure_shouldRejectIncompleteRequest() throws Exception {
+ String result = controller.getBeneficiaryPrescribedProcedure("{\"beneficiaryRegID\":11}");
+
+ assertTrue(result.contains("Invalid request"));
+ verify(labTechnicianServiceImpl, never()).getBenePrescribedProcedureDetails(anyLong(), anyLong());
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryPrescribedProcedure should surface a service failure")
+ void getBeneficiaryPrescribedProcedure_shouldSurfaceServiceFailure() throws Exception {
+ when(labTechnicianServiceImpl.getBenePrescribedProcedureDetails(11L, 22L))
+ .thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBeneficiaryPrescribedProcedure(VISIT_REQUEST)
+ .contains("Error while getting prescribed procedure data"));
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryPrescribedProcedure should surface a malformed request")
+ void getBeneficiaryPrescribedProcedure_shouldSurfaceMalformedRequest() {
+ assertTrue(controller.getBeneficiaryPrescribedProcedure("not-json")
+ .contains("Error while getting prescribed procedure data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getLabResultForVisitCode")
+ class LabResultTests {
+
+ @Test
+ @DisplayName("getLabResultForVisitCode should return the lab report for the visit")
+ void getLabResultForVisitCode_shouldReturnLabReport() throws Exception {
+ when(labTechnicianServiceImpl.getLabResultForVisitcode(11L, 22L)).thenReturn("[{\"result\":\"normal\"}]");
+
+ assertTrue(controller.getLabResultForVisitCode(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getLabResultForVisitCode should report a failure when no report comes back")
+ void getLabResultForVisitCode_shouldReportFailureWhenNoReport() throws Exception {
+ when(labTechnicianServiceImpl.getLabResultForVisitcode(11L, 22L)).thenReturn(null);
+
+ assertTrue(controller.getLabResultForVisitCode(VISIT_REQUEST).contains("Error while getting lab report"));
+ }
+
+ @Test
+ @DisplayName("getLabResultForVisitCode should reject a request without the visit code")
+ void getLabResultForVisitCode_shouldRejectIncompleteRequest() throws Exception {
+ String result = controller.getLabResultForVisitCode("{\"beneficiaryRegID\":11}");
+
+ assertTrue(result.contains("Invalid request"));
+ verify(labTechnicianServiceImpl, never()).getLabResultForVisitcode(anyLong(), anyLong());
+ }
+
+ @Test
+ @DisplayName("getLabResultForVisitCode should surface a service failure")
+ void getLabResultForVisitCode_shouldSurfaceServiceFailure() throws Exception {
+ when(labTechnicianServiceImpl.getLabResultForVisitcode(11L, 22L))
+ .thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getLabResultForVisitCode(VISIT_REQUEST).contains("Error while getting lab report"));
+ }
+
+ @Test
+ @DisplayName("getLabResultForVisitCode should surface a malformed request")
+ void getLabResultForVisitCode_shouldSurfaceMalformedRequest() {
+ assertTrue(controller.getLabResultForVisitCode("not-json").contains("Error while getting lab report"));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/controller/location/LocationControllerTest.java b/src/test/java/com/iemr/tm/controller/location/LocationControllerTest.java
new file mode 100644
index 00000000..ef20a07a
--- /dev/null
+++ b/src/test/java/com/iemr/tm/controller/location/LocationControllerTest.java
@@ -0,0 +1,197 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.controller.location;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import com.iemr.tm.service.location.LocationServiceImpl;
+
+@ExtendWith(MockitoExtension.class)
+@DisplayName("LocationController Test Suite")
+class LocationControllerTest {
+
+ @Mock
+ private LocationServiceImpl locationServiceImpl;
+
+ private LocationController controller;
+
+ @BeforeEach
+ @DisplayName("Wire the controller with a mocked location service")
+ void setUp() {
+ controller = new LocationController();
+ controller.setLocationServiceImpl(locationServiceImpl);
+ }
+
+ @Nested
+ @DisplayName("location master lookups")
+ class MasterLookupTests {
+
+ @Test
+ @DisplayName("getCountryMaster should return the country list")
+ void getCountryMaster_shouldReturnCountryList() {
+ when(locationServiceImpl.getCountryList()).thenReturn("[{\"countryID\":1}]");
+
+ assertTrue(controller.getCountryMaster().contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getCountryMaster should report a failure when no country list comes back")
+ void getCountryMaster_shouldReportFailureWhenNoList() {
+ when(locationServiceImpl.getCountryList()).thenReturn(null);
+
+ assertTrue(controller.getCountryMaster().contains("Error while getting country"));
+ }
+
+ @Test
+ @DisplayName("getCountryCityMaster should return the city list for the country")
+ void getCountryCityMaster_shouldReturnCityList() {
+ when(locationServiceImpl.getCountryCityList(1)).thenReturn("[{\"cityID\":9}]");
+
+ assertTrue(controller.getCountryCityMaster(1).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getCountryCityMaster should report a failure when no city list comes back")
+ void getCountryCityMaster_shouldReportFailureWhenNoList() {
+ when(locationServiceImpl.getCountryCityList(1)).thenReturn(null);
+
+ assertTrue(controller.getCountryCityMaster(1).contains("Error while getting country city"));
+ }
+
+ @Test
+ @DisplayName("getStateMaster should return the state list")
+ void getStateMaster_shouldReturnStateList() {
+ when(locationServiceImpl.getStateList()).thenReturn("[{\"stateID\":2}]");
+
+ assertTrue(controller.getStateMaster().contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getStateMaster should report a failure when no state list comes back")
+ void getStateMaster_shouldReportFailureWhenNoList() {
+ when(locationServiceImpl.getStateList()).thenReturn(null);
+
+ assertTrue(controller.getStateMaster().contains("Error while getting states"));
+ }
+
+ @Test
+ @DisplayName("getDistrictMaster should return the district list for the state")
+ void getDistrictMaster_shouldReturnDistrictList() {
+ when(locationServiceImpl.getDistrictList(2)).thenReturn("[{\"districtID\":3}]");
+
+ assertTrue(controller.getDistrictMaster(2).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getDistrictMaster should report a failure when no district list comes back")
+ void getDistrictMaster_shouldReportFailureWhenNoList() {
+ when(locationServiceImpl.getDistrictList(2)).thenReturn(null);
+
+ assertTrue(controller.getDistrictMaster(2).contains("Error while getting districts"));
+ }
+
+ @Test
+ @DisplayName("getDistrictBlockMaster should return the block list for the district")
+ void getDistrictBlockMaster_shouldReturnBlockList() {
+ when(locationServiceImpl.getDistrictBlockList(3)).thenReturn("[{\"blockID\":4}]");
+
+ assertTrue(controller.getDistrictBlockMaster(3).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getDistrictBlockMaster should report a failure when no block list comes back")
+ void getDistrictBlockMaster_shouldReportFailureWhenNoList() {
+ when(locationServiceImpl.getDistrictBlockList(3)).thenReturn(null);
+
+ assertTrue(controller.getDistrictBlockMaster(3).contains("Error while getting district blocks"));
+ }
+
+ @Test
+ @DisplayName("getVillageMaster should return the village list for the block")
+ void getVillageMaster_shouldReturnVillageList() {
+ when(locationServiceImpl.getVillageMasterFromBlockID(4)).thenReturn("[{\"villageID\":5}]");
+
+ assertTrue(controller.getVillageMaster(4).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getVillageMaster should report a failure when no village list comes back")
+ void getVillageMaster_shouldReportFailureWhenNoList() {
+ when(locationServiceImpl.getVillageMasterFromBlockID(4)).thenReturn(null);
+
+ assertTrue(controller.getVillageMaster(4).contains("Error while getting villages"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getLocDetailsBasedOnSpIDAndPsmIDNew")
+ class LocationDetailsTests {
+
+ @Test
+ @DisplayName("getLocDetailsBasedOnSpIDAndPsmIDNew should return the location details for a complete request")
+ void getLocDetails_shouldReturnLocationDetails() {
+ when(locationServiceImpl.getLocDetailsNew(7, 8)).thenReturn("{\"districtID\":3}");
+
+ String result = controller.getLocDetailsBasedOnSpIDAndPsmIDNew("{\"vanID\":7,\"spPSMID\":8}");
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("districtID"));
+ }
+
+ @Test
+ @DisplayName("getLocDetailsBasedOnSpIDAndPsmIDNew should reject a request without spPSMID")
+ void getLocDetails_shouldRejectRequestWithoutSpPsmId() {
+ String result = controller.getLocDetailsBasedOnSpIDAndPsmIDNew("{\"vanID\":7}");
+
+ assertTrue(result.contains("Invalid request"));
+ verify(locationServiceImpl, never()).getLocDetailsNew(anyInt(), anyInt());
+ }
+
+ @Test
+ @DisplayName("getLocDetailsBasedOnSpIDAndPsmIDNew should surface a service failure")
+ void getLocDetails_shouldSurfaceServiceFailure() {
+ when(locationServiceImpl.getLocDetailsNew(7, 8)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getLocDetailsBasedOnSpIDAndPsmIDNew("{\"vanID\":7,\"spPSMID\":8}")
+ .contains("Error while getting location data"));
+ }
+
+ @Test
+ @DisplayName("getLocDetailsBasedOnSpIDAndPsmIDNew should surface a malformed request")
+ void getLocDetails_shouldSurfaceMalformedRequest() {
+ assertTrue(controller.getLocDetailsBasedOnSpIDAndPsmIDNew("not-json")
+ .contains("Error while getting location data"));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/controller/login/IemrMmuLoginControllerTest.java b/src/test/java/com/iemr/tm/controller/login/IemrMmuLoginControllerTest.java
new file mode 100644
index 00000000..6d5e78de
--- /dev/null
+++ b/src/test/java/com/iemr/tm/controller/login/IemrMmuLoginControllerTest.java
@@ -0,0 +1,211 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.controller.login;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.security.core.Authentication;
+
+import com.iemr.tm.service.login.IemrMmuLoginServiceImpl;
+
+@ExtendWith(MockitoExtension.class)
+@DisplayName("IemrMmuLoginController Test Suite")
+class IemrMmuLoginControllerTest {
+
+ @Mock
+ private IemrMmuLoginServiceImpl iemrMmuLoginServiceImpl;
+
+ @Mock
+ private Authentication authentication;
+
+ private IemrMmuLoginController controller;
+
+ @BeforeEach
+ @DisplayName("Wire the controller with a mocked login service")
+ void setUp() {
+ controller = new IemrMmuLoginController();
+ controller.setIemrMmuLoginServiceImpl(iemrMmuLoginServiceImpl);
+ }
+
+ private void authenticateAs(String userId) {
+ when(authentication.isAuthenticated()).thenReturn(true);
+ when(authentication.getPrincipal()).thenReturn(userId);
+ }
+
+ @Nested
+ @DisplayName("getUserServicePointVanDetails")
+ class ServicePointVanDetailsTests {
+
+ @Test
+ @DisplayName("getUserServicePointVanDetails should return the van details for an authenticated user")
+ void getUserServicePointVanDetails_shouldReturnVanDetails() throws Exception {
+ authenticateAs("42");
+ when(iemrMmuLoginServiceImpl.getUserServicePointVanDetails(42)).thenReturn("{\"vanID\":7}");
+
+ String result = controller.getUserServicePointVanDetails("{}", authentication);
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("vanID"));
+ }
+
+ @Test
+ @DisplayName("getUserServicePointVanDetails should reject a missing authentication")
+ void getUserServicePointVanDetails_shouldRejectMissingAuthentication() throws Exception {
+ String result = controller.getUserServicePointVanDetails("{}", null);
+
+ assertTrue(result.contains("Unauthorized access"));
+ verify(iemrMmuLoginServiceImpl, never()).getUserServicePointVanDetails(anyInt());
+ }
+
+ @Test
+ @DisplayName("getUserServicePointVanDetails should reject an unauthenticated principal")
+ void getUserServicePointVanDetails_shouldRejectUnauthenticatedPrincipal() throws Exception {
+ when(authentication.isAuthenticated()).thenReturn(false);
+
+ assertTrue(controller.getUserServicePointVanDetails("{}", authentication).contains("Unauthorized access"));
+ }
+
+ @Test
+ @DisplayName("getUserServicePointVanDetails should surface a non-numeric principal as a failure")
+ void getUserServicePointVanDetails_shouldSurfaceNonNumericPrincipal() {
+ authenticateAs("not-a-number");
+
+ assertTrue(controller.getUserServicePointVanDetails("{}", authentication)
+ .contains("Error while getting service points and van data"));
+ }
+
+ @Test
+ @DisplayName("getUserServicePointVanDetails should surface a service failure")
+ void getUserServicePointVanDetails_shouldSurfaceServiceFailure() throws Exception {
+ authenticateAs("42");
+ when(iemrMmuLoginServiceImpl.getUserServicePointVanDetails(42))
+ .thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getUserServicePointVanDetails("{}", authentication)
+ .contains("Error while getting service points and van data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getServicepointVillages")
+ class ServicePointVillagesTests {
+
+ @Test
+ @DisplayName("getServicepointVillages should return the villages for the service point")
+ void getServicepointVillages_shouldReturnVillages() throws Exception {
+ when(iemrMmuLoginServiceImpl.getServicepointVillages(3)).thenReturn("[{\"villageID\":5}]");
+
+ assertTrue(controller.getServicepointVillages("{\"servicePointID\":3}").contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getServicepointVillages should surface a request without the service point id")
+ void getServicepointVillages_shouldSurfaceRequestWithoutServicePointId() {
+ assertTrue(controller.getServicepointVillages("{}")
+ .contains("Error while getting service points and villages"));
+ }
+
+ @Test
+ @DisplayName("getServicepointVillages should surface a service failure")
+ void getServicepointVillages_shouldSurfaceServiceFailure() throws Exception {
+ when(iemrMmuLoginServiceImpl.getServicepointVillages(3)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getServicepointVillages("{\"servicePointID\":3}")
+ .contains("Error while getting service points and villages"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getUserVanSpDetails")
+ class UserVanSpDetailsTests {
+
+ @Test
+ @DisplayName("getUserVanSpDetails should return the van and service point details")
+ void getUserVanSpDetails_shouldReturnVanAndServicePointDetails() throws Exception {
+ authenticateAs("42");
+ when(iemrMmuLoginServiceImpl.getUserVanSpDetails(42, 9)).thenReturn("{\"vanID\":7}");
+
+ assertTrue(controller.getUserVanSpDetails("{\"providerServiceMapID\":9}", authentication)
+ .contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getUserVanSpDetails should reject a missing authentication")
+ void getUserVanSpDetails_shouldRejectMissingAuthentication() {
+ assertTrue(controller.getUserVanSpDetails("{\"providerServiceMapID\":9}", null)
+ .contains("Unauthorized access"));
+ }
+
+ @Test
+ @DisplayName("getUserVanSpDetails should reject a request without providerServiceMapID")
+ void getUserVanSpDetails_shouldRejectRequestWithoutProviderServiceMapId() throws Exception {
+ authenticateAs("42");
+
+ String result = controller.getUserVanSpDetails("{}", authentication);
+
+ assertTrue(result.contains("Invalid request"));
+ verify(iemrMmuLoginServiceImpl, never()).getUserVanSpDetails(anyInt(), anyInt());
+ }
+
+ @Test
+ @DisplayName("getUserVanSpDetails should surface a service failure")
+ void getUserVanSpDetails_shouldSurfaceServiceFailure() throws Exception {
+ authenticateAs("42");
+ when(iemrMmuLoginServiceImpl.getUserVanSpDetails(42, 9)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getUserVanSpDetails("{\"providerServiceMapID\":9}", authentication)
+ .contains("Error while getting van and service points data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getUserSpokeDetails")
+ class UserSpokeDetailsTests {
+
+ @Test
+ @DisplayName("getUserSpokeDetails should return the spoke details for the provider service map")
+ void getUserSpokeDetails_shouldReturnSpokeDetails() throws Exception {
+ when(iemrMmuLoginServiceImpl.getUserSpokeDetails(9)).thenReturn("[{\"spokeID\":1}]");
+
+ assertTrue(controller.getUserSpokeDetails(9).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getUserSpokeDetails should surface a service failure")
+ void getUserSpokeDetails_shouldSurfaceServiceFailure() throws Exception {
+ when(iemrMmuLoginServiceImpl.getUserSpokeDetails(9)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getUserSpokeDetails(9).contains("Error occurred while fetching van master"));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/controller/ncdCare/NCDCareControllerTest.java b/src/test/java/com/iemr/tm/controller/ncdCare/NCDCareControllerTest.java
new file mode 100644
index 00000000..b35aa13d
--- /dev/null
+++ b/src/test/java/com/iemr/tm/controller/ncdCare/NCDCareControllerTest.java
@@ -0,0 +1,348 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.controller.ncdCare;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import com.google.gson.JsonObject;
+import com.iemr.tm.service.ncdCare.NCDCareServiceImpl;
+
+@ExtendWith(MockitoExtension.class)
+@DisplayName("NCDCareController Test Suite")
+class NCDCareControllerTest {
+
+ private static final String AUTHORIZATION = "Bearer session-token";
+ private static final String BEN_REQUEST = "{\"benRegID\":11,\"visitCode\":22}";
+
+ @Mock
+ private NCDCareServiceImpl ncdCareServiceImpl;
+
+ private NCDCareController controller;
+
+ @BeforeEach
+ @DisplayName("Wire the controller with a mocked NCD care service")
+ void setUp() {
+ controller = new NCDCareController();
+ controller.setNcdCareServiceImpl(ncdCareServiceImpl);
+ }
+
+ @Nested
+ @DisplayName("saveBenNCDCareNurseData")
+ class SaveNurseDataTests {
+
+ @Test
+ @DisplayName("saveBenNCDCareNurseData should return the payload produced by the service")
+ void saveBenNCDCareNurseData_shouldReturnServicePayload() throws Exception {
+ when(ncdCareServiceImpl.saveNCDCareNurseData(any(JsonObject.class), eq(AUTHORIZATION)))
+ .thenReturn("{\"benVisitID\":5}");
+
+ String result = controller.saveBenNCDCareNurseData("{\"benVisitID\":5}", AUTHORIZATION);
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("benVisitID"));
+ }
+
+ @Test
+ @DisplayName("saveBenNCDCareNurseData should roll back the visit details when the service fails")
+ void saveBenNCDCareNurseData_shouldRollBackVisitDetailsOnFailure() throws Exception {
+ when(ncdCareServiceImpl.saveNCDCareNurseData(any(JsonObject.class), eq(AUTHORIZATION)))
+ .thenThrow(new IllegalStateException("save failed"));
+
+ String result = controller.saveBenNCDCareNurseData("{\"benVisitID\":5}", AUTHORIZATION);
+
+ assertTrue(result.contains("save failed"));
+ verify(ncdCareServiceImpl).deleteVisitDetails(any(JsonObject.class));
+ }
+
+ @Test
+ @DisplayName("saveBenNCDCareNurseData should return the untouched failure response for a null request")
+ void saveBenNCDCareNurseData_shouldReturnGenericFailureForNullRequest() throws Exception {
+ String result = controller.saveBenNCDCareNurseData(null, AUTHORIZATION);
+
+ assertTrue(result.contains("Failed with generic error"));
+ verify(ncdCareServiceImpl, never()).saveNCDCareNurseData(any(JsonObject.class), anyString());
+ }
+ }
+
+ @Nested
+ @DisplayName("saveBenNCDCareDoctorData")
+ class SaveDoctorDataTests {
+
+ @Test
+ @DisplayName("saveBenNCDCareDoctorData should confirm the save when the service returns an id")
+ void saveBenNCDCareDoctorData_shouldConfirmSave() throws Exception {
+ when(ncdCareServiceImpl.saveDoctorData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn(7L);
+
+ String result = controller.saveBenNCDCareDoctorData("{\"benRegID\":11}", AUTHORIZATION);
+
+ assertTrue(result.contains("Data saved successfully"));
+ }
+
+ @Test
+ @DisplayName("saveBenNCDCareDoctorData should report an unsuccessful save")
+ void saveBenNCDCareDoctorData_shouldReportUnsuccessfulSave() throws Exception {
+ when(ncdCareServiceImpl.saveDoctorData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn(0L);
+
+ String result = controller.saveBenNCDCareDoctorData("{\"benRegID\":11}", AUTHORIZATION);
+
+ assertTrue(result.contains("Unable to save data"));
+ }
+
+ @Test
+ @DisplayName("saveBenNCDCareDoctorData should report an unsuccessful save when no id comes back")
+ void saveBenNCDCareDoctorData_shouldReportUnsuccessfulSaveForNullId() throws Exception {
+ when(ncdCareServiceImpl.saveDoctorData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn(null);
+
+ String result = controller.saveBenNCDCareDoctorData("{\"benRegID\":11}", AUTHORIZATION);
+
+ assertTrue(result.contains("Unable to save data"));
+ }
+
+ @Test
+ @DisplayName("saveBenNCDCareDoctorData should surface a service failure")
+ void saveBenNCDCareDoctorData_shouldSurfaceServiceFailure() throws Exception {
+ when(ncdCareServiceImpl.saveDoctorData(any(JsonObject.class), eq(AUTHORIZATION)))
+ .thenThrow(new IllegalStateException("doctor save failed"));
+
+ assertTrue(controller.saveBenNCDCareDoctorData("{\"benRegID\":11}", AUTHORIZATION)
+ .contains("doctor save failed"));
+ }
+
+ @Test
+ @DisplayName("saveBenNCDCareDoctorData should surface a malformed request")
+ void saveBenNCDCareDoctorData_shouldSurfaceMalformedRequest() {
+ assertTrue(controller.saveBenNCDCareDoctorData("not-json", AUTHORIZATION).contains("\"statusCode\":5000"));
+ }
+ }
+
+ @Nested
+ @DisplayName("read endpoints")
+ class ReadTests
+
+ {
+ @Test
+ @DisplayName("getBenVisitDetailsFrmNurseNCDCare should return the visit details for a complete request")
+ void getBenVisitDetailsFrmNurseNCDCare_shouldReturnVisitDetails() throws Exception {
+ when(ncdCareServiceImpl.getBenVisitDetailsFrmNurseNCDCare(11L, 22L)).thenReturn("{\"visitCode\":22}");
+
+ assertTrue(controller.getBenVisitDetailsFrmNurseNCDCare(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenVisitDetailsFrmNurseNCDCare should reject a request with a single field")
+ void getBenVisitDetailsFrmNurseNCDCare_shouldRejectSingleFieldRequest() throws Exception {
+ String result = controller.getBenVisitDetailsFrmNurseNCDCare("{\"benRegID\":11}");
+
+ assertTrue(result.contains("Invalid request"));
+ verify(ncdCareServiceImpl, never()).getBenVisitDetailsFrmNurseNCDCare(anyLong(), anyLong());
+ }
+
+ @Test
+ @DisplayName("getBenVisitDetailsFrmNurseNCDCare should surface a service failure")
+ void getBenVisitDetailsFrmNurseNCDCare_shouldSurfaceServiceFailure() throws Exception {
+ when(ncdCareServiceImpl.getBenVisitDetailsFrmNurseNCDCare(11L, 22L))
+ .thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenVisitDetailsFrmNurseNCDCare(BEN_REQUEST)
+ .contains("Error while getting beneficiary visit data"));
+ }
+
+ @Test
+ @DisplayName("getBenNCDCareHistoryDetails should return the history for a complete request")
+ void getBenNCDCareHistoryDetails_shouldReturnHistory() throws Exception {
+ when(ncdCareServiceImpl.getBenNCDCareHistoryDetails(11L, 22L)).thenReturn("{\"history\":[]}");
+
+ assertTrue(controller.getBenNCDCareHistoryDetails(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenNCDCareHistoryDetails should reject a request without the visit code")
+ void getBenNCDCareHistoryDetails_shouldRejectRequestWithoutVisitCode() {
+ assertTrue(controller.getBenNCDCareHistoryDetails("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenNCDCareHistoryDetails should surface a service failure")
+ void getBenNCDCareHistoryDetails_shouldSurfaceServiceFailure() throws Exception {
+ when(ncdCareServiceImpl.getBenNCDCareHistoryDetails(11L, 22L))
+ .thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenNCDCareHistoryDetails(BEN_REQUEST)
+ .contains("Error while getting beneficiary history data"));
+ }
+
+ @Test
+ @DisplayName("getBenVitalDetailsFrmNurseNCDCare should return the vitals for a complete request")
+ void getBenVitalDetailsFrmNurseNCDCare_shouldReturnVitals() throws Exception {
+ when(ncdCareServiceImpl.getBeneficiaryVitalDetails(11L, 22L)).thenReturn("{\"height\":170}");
+
+ assertTrue(controller.getBenVitalDetailsFrmNurseNCDCare(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenVitalDetailsFrmNurseNCDCare should reject a request without the visit code")
+ void getBenVitalDetailsFrmNurseNCDCare_shouldRejectRequestWithoutVisitCode() {
+ assertTrue(controller.getBenVitalDetailsFrmNurseNCDCare("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenVitalDetailsFrmNurseNCDCare should surface a service failure")
+ void getBenVitalDetailsFrmNurseNCDCare_shouldSurfaceServiceFailure() throws Exception {
+ when(ncdCareServiceImpl.getBeneficiaryVitalDetails(11L, 22L))
+ .thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenVitalDetailsFrmNurseNCDCare(BEN_REQUEST)
+ .contains("Error while getting beneficiary vital data"));
+ }
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorNCDCare should return the case record for a complete request")
+ void getBenCaseRecordFromDoctorNCDCare_shouldReturnCaseRecord() throws Exception {
+ when(ncdCareServiceImpl.getBenCaseRecordFromDoctorNCDCare(11L, 22L)).thenReturn("{\"diagnosis\":\"x\"}");
+
+ assertTrue(controller.getBenCaseRecordFromDoctorNCDCare(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorNCDCare should reject an incomplete request")
+ void getBenCaseRecordFromDoctorNCDCare_shouldRejectIncompleteRequest() {
+ assertTrue(controller.getBenCaseRecordFromDoctorNCDCare("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorNCDCare should surface a service failure")
+ void getBenCaseRecordFromDoctorNCDCare_shouldSurfaceServiceFailure() throws Exception {
+ when(ncdCareServiceImpl.getBenCaseRecordFromDoctorNCDCare(11L, 22L))
+ .thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenCaseRecordFromDoctorNCDCare(BEN_REQUEST)
+ .contains("Error while getting beneficiary doctor data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("update endpoints")
+ class UpdateTests {
+
+ @Test
+ @DisplayName("updateHistoryNurse should confirm the update when a row was changed")
+ void updateHistoryNurse_shouldConfirmUpdate() throws Exception {
+ when(ncdCareServiceImpl.updateBenHistoryDetails(any(JsonObject.class))).thenReturn(1);
+
+ assertTrue(controller.updateHistoryNurse("{\"benRegID\":11}").contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("updateHistoryNurse should report that nothing was modified")
+ void updateHistoryNurse_shouldReportNothingModified() throws Exception {
+ when(ncdCareServiceImpl.updateBenHistoryDetails(any(JsonObject.class))).thenReturn(0);
+
+ assertTrue(controller.updateHistoryNurse("{\"benRegID\":11}").contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updateHistoryNurse should surface a service failure")
+ void updateHistoryNurse_shouldSurfaceServiceFailure() throws Exception {
+ when(ncdCareServiceImpl.updateBenHistoryDetails(any(JsonObject.class)))
+ .thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.updateHistoryNurse("{\"benRegID\":11}").contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updateVitalNurse should confirm the update when a row was changed")
+ void updateVitalNurse_shouldConfirmUpdate() throws Exception {
+ when(ncdCareServiceImpl.updateBenVitalDetails(any(JsonObject.class))).thenReturn(1);
+
+ assertTrue(controller.updateVitalNurse("{\"benRegID\":11}").contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("updateVitalNurse should report that nothing was modified")
+ void updateVitalNurse_shouldReportNothingModified() throws Exception {
+ when(ncdCareServiceImpl.updateBenVitalDetails(any(JsonObject.class))).thenReturn(0);
+
+ assertTrue(controller.updateVitalNurse("{\"benRegID\":11}").contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updateVitalNurse should surface a service failure")
+ void updateVitalNurse_shouldSurfaceServiceFailure() throws Exception {
+ when(ncdCareServiceImpl.updateBenVitalDetails(any(JsonObject.class)))
+ .thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.updateVitalNurse("{\"benRegID\":11}").contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updateNCDCareDoctorData should confirm the update when a row was changed")
+ void updateNCDCareDoctorData_shouldConfirmUpdate() throws Exception {
+ when(ncdCareServiceImpl.updateNCDCareDoctorData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn(1L);
+
+ assertTrue(controller.updateNCDCareDoctorData("{\"benRegID\":11}", AUTHORIZATION)
+ .contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("updateNCDCareDoctorData should report that nothing was modified")
+ void updateNCDCareDoctorData_shouldReportNothingModified() throws Exception {
+ when(ncdCareServiceImpl.updateNCDCareDoctorData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn(0L);
+
+ assertTrue(controller.updateNCDCareDoctorData("{\"benRegID\":11}", AUTHORIZATION)
+ .contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updateNCDCareDoctorData should report that nothing was modified when no id comes back")
+ void updateNCDCareDoctorData_shouldReportNothingModifiedForNullId() throws Exception {
+ when(ncdCareServiceImpl.updateNCDCareDoctorData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn(null);
+
+ assertTrue(controller.updateNCDCareDoctorData("{\"benRegID\":11}", AUTHORIZATION)
+ .contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updateNCDCareDoctorData should surface a service failure")
+ void updateNCDCareDoctorData_shouldSurfaceServiceFailure() throws Exception {
+ when(ncdCareServiceImpl.updateNCDCareDoctorData(any(JsonObject.class), eq(AUTHORIZATION)))
+ .thenThrow(new IllegalStateException("doctor update failed"));
+
+ assertTrue(controller.updateNCDCareDoctorData("{\"benRegID\":11}", AUTHORIZATION)
+ .contains("doctor update failed"));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/controller/ncdscreening/NCDScreeningControllerTest.java b/src/test/java/com/iemr/tm/controller/ncdscreening/NCDScreeningControllerTest.java
new file mode 100644
index 00000000..a81d9518
--- /dev/null
+++ b/src/test/java/com/iemr/tm/controller/ncdscreening/NCDScreeningControllerTest.java
@@ -0,0 +1,371 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.controller.ncdscreening;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.google.gson.JsonObject;
+import com.iemr.tm.service.ncdscreening.NCDScreeningServiceImpl;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("NCDScreeningController Test Suite")
+class NCDScreeningControllerTest {
+
+ private static final String AUTHORIZATION = "Bearer session-token";
+ private static final Long BEN_REG_ID = 11L;
+ private static final Long VISIT_CODE = 22L;
+ private static final String REQUEST = "{\"beneficiaryRegID\":11,\"visitCode\":22}";
+ private static final String VISIT_REQUEST = "{\"benRegID\":11,\"visitCode\":22}";
+
+ @Mock
+ private NCDScreeningServiceImpl ncdScreeningServiceImpl;
+
+ private NCDScreeningController controller;
+
+ @BeforeEach
+ @DisplayName("Wire the controller with mocked services")
+ void setUp() {
+ controller = new NCDScreeningController();
+ controller.setNcdScreeningServiceImpl(ncdScreeningServiceImpl);
+ }
+
+ @Nested
+ @DisplayName("saveBeneficiaryNCDScreeningDetails")
+ class SaveNurseTests {
+
+ @Test
+ @DisplayName("saveBeneficiaryNCDScreeningDetails should return the payload produced by the service")
+ void saveBeneficiaryNCDScreeningDetails_shouldReturnServicePayload() throws Exception {
+ when(ncdScreeningServiceImpl.saveNCDScreeningNurseData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn("{\"visitCode\":\"22\"}");
+
+ String result = controller.saveBeneficiaryNCDScreeningDetails(REQUEST, AUTHORIZATION);
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("visitCode"));
+ }
+
+ @Test
+ @DisplayName("saveBeneficiaryNCDScreeningDetails should roll back the visit details when the service fails")
+ void saveBeneficiaryNCDScreeningDetails_shouldRollBackVisitDetailsOnFailure() throws Exception {
+ when(ncdScreeningServiceImpl.saveNCDScreeningNurseData(any(JsonObject.class), eq(AUTHORIZATION)))
+ .thenThrow(new IllegalStateException("save failed"));
+
+ assertTrue(controller.saveBeneficiaryNCDScreeningDetails(REQUEST, AUTHORIZATION).contains("save failed"));
+ verify(ncdScreeningServiceImpl).deleteVisitDetails(any(JsonObject.class));
+ }
+
+ @Test
+ @DisplayName("saveBeneficiaryNCDScreeningDetails should return the untouched failure response for a null request")
+ void saveBeneficiaryNCDScreeningDetails_shouldReturnGenericFailureForNullRequest() throws Exception {
+ assertTrue(controller.saveBeneficiaryNCDScreeningDetails(null, AUTHORIZATION).contains("Failed with generic error"));
+ verify(ncdScreeningServiceImpl, never()).saveNCDScreeningNurseData(any(JsonObject.class), anyString());
+ }
+ }
+
+ @Nested
+ @DisplayName("saveBenNCDScreeningDoctorData")
+ class SaveDoctorTests {
+
+ @Test
+ @DisplayName("saveBenNCDScreeningDoctorData should confirm the save when the service returns an id")
+ void saveBenNCDScreeningDoctorData_shouldConfirmSave() throws Exception {
+ when(ncdScreeningServiceImpl.saveDoctorData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn(7L);
+
+ assertTrue(controller.saveBenNCDScreeningDoctorData(REQUEST, AUTHORIZATION).contains("Data saved successfully"));
+ }
+
+ @Test
+ @DisplayName("saveBenNCDScreeningDoctorData should report an unsuccessful save")
+ void saveBenNCDScreeningDoctorData_shouldReportUnsuccessfulSave() throws Exception {
+ when(ncdScreeningServiceImpl.saveDoctorData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn(0L);
+
+ assertTrue(controller.saveBenNCDScreeningDoctorData(REQUEST, AUTHORIZATION).contains("Unable to save data"));
+ }
+
+ @Test
+ @DisplayName("saveBenNCDScreeningDoctorData should surface a service failure")
+ void saveBenNCDScreeningDoctorData_shouldSurfaceServiceFailure() throws Exception {
+ when(ncdScreeningServiceImpl.saveDoctorData(any(JsonObject.class), eq(AUTHORIZATION)))
+ .thenThrow(new IllegalStateException("doctor save failed"));
+
+ assertTrue(controller.saveBenNCDScreeningDoctorData(REQUEST, AUTHORIZATION).contains("doctor save failed"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getNCDScreenigDetails")
+ class ReadScreeningTests {
+
+ @Test
+ @DisplayName("getNCDScreenigDetails should return the details for a complete request")
+ void getNCDScreenigDetails_shouldReturnDetails() throws Exception {
+ when(ncdScreeningServiceImpl.getNCDScreeningDetails(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getNCDScreenigDetails(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getNCDScreenigDetails should reject an incomplete request")
+ void getNCDScreenigDetails_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getNCDScreenigDetails("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getNCDScreenigDetails should surface a service failure")
+ void getNCDScreenigDetails_shouldSurfaceServiceFailure() throws Exception {
+ when(ncdScreeningServiceImpl.getNCDScreeningDetails(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getNCDScreenigDetails(VISIT_REQUEST).contains("Error while getting NCD Screening data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getNcdScreeningVisitCount")
+ class ReadVisitCountTests {
+
+ @Test
+ @DisplayName("getNcdScreeningVisitCount should return the details for the beneficiary")
+ void getNcdScreeningVisitCount_shouldReturnDetails() throws Exception {
+ when(ncdScreeningServiceImpl.getNcdScreeningVisitCnt(BEN_REG_ID)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getNcdScreeningVisitCount(BEN_REG_ID).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getNcdScreeningVisitCount should surface a service failure")
+ void getNcdScreeningVisitCount_shouldSurfaceServiceFailure() throws Exception {
+ when(ncdScreeningServiceImpl.getNcdScreeningVisitCnt(BEN_REG_ID)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getNcdScreeningVisitCount(BEN_REG_ID).contains("Error while getting NCD screening Visit Count"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenCaseRecordFromDoctorNCDCare")
+ class ReadCaseRecordTests {
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorNCDCare should return the details for a complete request")
+ void getBenCaseRecordFromDoctorNCDCare_shouldReturnDetails() throws Exception {
+ when(ncdScreeningServiceImpl.getBenCaseRecordFromDoctorNCDScreening(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenCaseRecordFromDoctorNCDCare(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorNCDCare should reject an incomplete request")
+ void getBenCaseRecordFromDoctorNCDCare_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenCaseRecordFromDoctorNCDCare("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorNCDCare should surface a service failure")
+ void getBenCaseRecordFromDoctorNCDCare_shouldSurfaceServiceFailure() throws Exception {
+ when(ncdScreeningServiceImpl.getBenCaseRecordFromDoctorNCDScreening(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenCaseRecordFromDoctorNCDCare(VISIT_REQUEST).contains("Error while getting beneficiary doctor data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenVisitDetailsFrmNurseGOPD")
+ class ReadVisitTests {
+
+ @Test
+ @DisplayName("getBenVisitDetailsFrmNurseGOPD should return the details for a complete request")
+ void getBenVisitDetailsFrmNurseGOPD_shouldReturnDetails() throws Exception {
+ when(ncdScreeningServiceImpl.getBenVisitDetailsFrmNurseNCDScreening(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenVisitDetailsFrmNurseGOPD(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenVisitDetailsFrmNurseGOPD should reject an incomplete request")
+ void getBenVisitDetailsFrmNurseGOPD_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenVisitDetailsFrmNurseGOPD("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenVisitDetailsFrmNurseGOPD should surface a service failure")
+ void getBenVisitDetailsFrmNurseGOPD_shouldSurfaceServiceFailure() throws Exception {
+ when(ncdScreeningServiceImpl.getBenVisitDetailsFrmNurseNCDScreening(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenVisitDetailsFrmNurseGOPD(VISIT_REQUEST).contains("Error while getting beneficiary visit data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenHistoryDetails")
+ class ReadHistoryTests {
+
+ @Test
+ @DisplayName("getBenHistoryDetails should return the details for a complete request")
+ void getBenHistoryDetails_shouldReturnDetails() throws Exception {
+ when(ncdScreeningServiceImpl.getBenHistoryDetails(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenHistoryDetails(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenHistoryDetails should reject an incomplete request")
+ void getBenHistoryDetails_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenHistoryDetails("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenHistoryDetails should surface a service failure")
+ void getBenHistoryDetails_shouldSurfaceServiceFailure() throws Exception {
+ when(ncdScreeningServiceImpl.getBenHistoryDetails(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenHistoryDetails(VISIT_REQUEST).contains("Error while getting beneficiary history data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenVitalDetailsFrmNurse")
+ class ReadVitalsTests {
+
+ @Test
+ @DisplayName("getBenVitalDetailsFrmNurse should return the details for a complete request")
+ void getBenVitalDetailsFrmNurse_shouldReturnDetails() throws Exception {
+ when(ncdScreeningServiceImpl.getBeneficiaryVitalDetails(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenVitalDetailsFrmNurse(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenVitalDetailsFrmNurse should reject an incomplete request")
+ void getBenVitalDetailsFrmNurse_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenVitalDetailsFrmNurse("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenVitalDetailsFrmNurse should surface a service failure")
+ void getBenVitalDetailsFrmNurse_shouldSurfaceServiceFailure() throws Exception {
+ when(ncdScreeningServiceImpl.getBeneficiaryVitalDetails(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenVitalDetailsFrmNurse(VISIT_REQUEST).contains("Error while getting beneficiary vital data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenIdrsDetailsFrmNurse")
+ class ReadIdrsTests {
+
+ @Test
+ @DisplayName("getBenIdrsDetailsFrmNurse should return the details for a complete request")
+ void getBenIdrsDetailsFrmNurse_shouldReturnDetails() throws Exception {
+ when(ncdScreeningServiceImpl.getBenIdrsDetailsFrmNurse(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenIdrsDetailsFrmNurse(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenIdrsDetailsFrmNurse should reject an incomplete request")
+ void getBenIdrsDetailsFrmNurse_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenIdrsDetailsFrmNurse("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenIdrsDetailsFrmNurse should surface a service failure")
+ void getBenIdrsDetailsFrmNurse_shouldSurfaceServiceFailure() throws Exception {
+ when(ncdScreeningServiceImpl.getBenIdrsDetailsFrmNurse(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenIdrsDetailsFrmNurse(VISIT_REQUEST).contains("Error while getting beneficiary Idrs data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("updateBeneficiaryNCDScreeningDetails")
+ class UpdateScreeningTests {
+
+ @Test
+ @DisplayName("updateBeneficiaryNCDScreeningDetails should confirm the update when a row was changed")
+ void updateBeneficiaryNCDScreeningDetails_shouldConfirmUpdate() throws Exception {
+ when(ncdScreeningServiceImpl.updateNurseNCDScreeningDetails(any(JsonObject.class))).thenReturn(1);
+
+ assertTrue(controller.updateBeneficiaryNCDScreeningDetails(REQUEST).contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("updateBeneficiaryNCDScreeningDetails should report that nothing was modified")
+ void updateBeneficiaryNCDScreeningDetails_shouldReportNothingModified() throws Exception {
+ when(ncdScreeningServiceImpl.updateNurseNCDScreeningDetails(any(JsonObject.class))).thenReturn(0);
+
+ assertTrue(controller.updateBeneficiaryNCDScreeningDetails(REQUEST).contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updateBeneficiaryNCDScreeningDetails should surface a service failure")
+ void updateBeneficiaryNCDScreeningDetails_shouldSurfaceServiceFailure() throws Exception {
+ when(ncdScreeningServiceImpl.updateNurseNCDScreeningDetails(any(JsonObject.class))).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.updateBeneficiaryNCDScreeningDetails(REQUEST).contains("Unable to modify data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("updateVitalNurse")
+ class UpdateVitalsTests {
+
+ @Test
+ @DisplayName("updateVitalNurse should confirm the update when a row was changed")
+ void updateVitalNurse_shouldConfirmUpdate() throws Exception {
+ when(ncdScreeningServiceImpl.updateBenVitalDetails(any(JsonObject.class))).thenReturn(1);
+
+ assertTrue(controller.updateVitalNurse(REQUEST).contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("updateVitalNurse should report that nothing was modified")
+ void updateVitalNurse_shouldReportNothingModified() throws Exception {
+ when(ncdScreeningServiceImpl.updateBenVitalDetails(any(JsonObject.class))).thenReturn(0);
+
+ assertTrue(controller.updateVitalNurse(REQUEST).contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updateVitalNurse should surface a service failure")
+ void updateVitalNurse_shouldSurfaceServiceFailure() throws Exception {
+ when(ncdScreeningServiceImpl.updateBenVitalDetails(any(JsonObject.class))).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.updateVitalNurse(REQUEST).contains("Unable to modify data"));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/controller/nurse/vitals/AnthropometryVitalsControllerTest.java b/src/test/java/com/iemr/tm/controller/nurse/vitals/AnthropometryVitalsControllerTest.java
new file mode 100644
index 00000000..11f74289
--- /dev/null
+++ b/src/test/java/com/iemr/tm/controller/nurse/vitals/AnthropometryVitalsControllerTest.java
@@ -0,0 +1,84 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.controller.nurse.vitals;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import com.iemr.tm.service.nurse.vitals.AnthropometryVitalsService;
+
+@ExtendWith(MockitoExtension.class)
+@DisplayName("AnthropometryVitalsController Test Suite")
+class AnthropometryVitalsControllerTest {
+
+ @Mock
+ private AnthropometryVitalsService anthropometryVitalsService;
+
+ @InjectMocks
+ private AnthropometryVitalsController controller;
+
+ @Test
+ @DisplayName("getBenHeightDetailsFrmNurse should return the height details for a valid request")
+ void getBenHeightDetailsFrmNurse_shouldReturnHeightDetails() throws Exception {
+ when(anthropometryVitalsService.getBeneficiaryHeightDetails(11L)).thenReturn("{\"height\":170}");
+
+ String result = controller.getBenHeightDetailsFrmNurse("{\"benRegID\":11}");
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("height"));
+ }
+
+ @Test
+ @DisplayName("getBenHeightDetailsFrmNurse should reject a request without benRegID")
+ void getBenHeightDetailsFrmNurse_shouldRejectRequestWithoutBenRegId() throws Exception {
+ String result = controller.getBenHeightDetailsFrmNurse("{\"visitCode\":22}");
+
+ assertTrue(result.contains("Invalid request"));
+ verify(anthropometryVitalsService, never()).getBeneficiaryHeightDetails(anyLong());
+ }
+
+ @Test
+ @DisplayName("getBenHeightDetailsFrmNurse should surface a service failure")
+ void getBenHeightDetailsFrmNurse_shouldSurfaceServiceFailure() throws Exception {
+ when(anthropometryVitalsService.getBeneficiaryHeightDetails(11L)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenHeightDetailsFrmNurse("{\"benRegID\":11}")
+ .contains("Error while getting beneficiary height data"));
+ }
+
+ @Test
+ @DisplayName("getBenHeightDetailsFrmNurse should surface a malformed request")
+ void getBenHeightDetailsFrmNurse_shouldSurfaceMalformedRequest() {
+ assertTrue(controller.getBenHeightDetailsFrmNurse("not-json")
+ .contains("Error while getting beneficiary height data"));
+ }
+}
diff --git a/src/test/java/com/iemr/tm/controller/patientApp/master/PatientAppCommonMasterControllerTest.java b/src/test/java/com/iemr/tm/controller/patientApp/master/PatientAppCommonMasterControllerTest.java
new file mode 100644
index 00000000..b28a0a77
--- /dev/null
+++ b/src/test/java/com/iemr/tm/controller/patientApp/master/PatientAppCommonMasterControllerTest.java
@@ -0,0 +1,334 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.controller.patientApp.master;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.service.patientApp.master.CommonPatientAppMasterService;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("PatientAppCommonMasterController Test Suite")
+class PatientAppCommonMasterControllerTest {
+
+ private static final String AUTHORIZATION = "Bearer session-token";
+ private static final String REQUEST = "{\"beneficiaryRegID\":11,\"visitCode\":22}";
+
+ @Mock
+ private CommonPatientAppMasterService commonPatientAppMasterService;
+
+ private PatientAppCommonMasterController controller;
+
+ @BeforeEach
+ @DisplayName("Wire the controller with a mocked service")
+ void setUp() {
+ controller = new PatientAppCommonMasterController();
+ controller.setCommonPatientAppMasterService(commonPatientAppMasterService);
+ }
+
+ @Nested
+ @DisplayName("patientAppChiefComplaintsMasterData")
+ class PatientAppChiefComplaintsMasterDataTests {
+
+ @Test
+ @DisplayName("patientAppChiefComplaintsMasterData should return the master the service assembled")
+ void patientAppChiefComplaintsMasterData_shouldReturnServiceMaster() {
+ when(commonPatientAppMasterService.getChiefComplaintsMaster(1, 9, "Female")).thenReturn("{\"master\":[]}");
+
+ String result = controller.patientAppChiefComplaintsMasterData(1, 9, "Female");
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("master"));
+ }
+ }
+
+ @Nested
+ @DisplayName("patientAppCovidMasterData")
+ class PatientAppCovidMasterDataTests {
+
+ @Test
+ @DisplayName("patientAppCovidMasterData should return the master the service assembled")
+ void patientAppCovidMasterData_shouldReturnServiceMaster() {
+ when(commonPatientAppMasterService.getCovidMaster(1, 9, "Female")).thenReturn("{\"master\":[]}");
+
+ String result = controller.patientAppCovidMasterData(1, 9, "Female");
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("master"));
+ }
+ }
+
+ @Nested
+ @DisplayName("saveBenCovidDoctorDataPatientApp")
+ class SaveBenCovidDoctorDataPatientAppTests {
+
+ @Test
+ @DisplayName("saveBenCovidDoctorDataPatientApp should return the payload the service produced")
+ void saveBenCovidDoctorDataPatientApp_shouldReturnServicePayload() throws Exception {
+ when(commonPatientAppMasterService.saveCovidScreeningData(REQUEST)).thenReturn("saved");
+
+ String result = controller.saveBenCovidDoctorDataPatientApp(REQUEST, AUTHORIZATION);
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("saved"));
+ }
+
+ @Test
+ @DisplayName("saveBenCovidDoctorDataPatientApp should report a request the service could not act on")
+ void saveBenCovidDoctorDataPatientApp_shouldReportRequestItCannotActOn() throws Exception {
+ when(commonPatientAppMasterService.saveCovidScreeningData(REQUEST))
+ .thenThrow(new IllegalStateException("save failed"));
+
+ assertTrue(controller.saveBenCovidDoctorDataPatientApp(REQUEST, AUTHORIZATION).contains("Unable to save data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("saveBenChiefComplaintsDataPatientApp")
+ class SaveBenChiefComplaintsDataPatientAppTests {
+
+ @Test
+ @DisplayName("saveBenChiefComplaintsDataPatientApp should return the payload the service produced")
+ void saveBenChiefComplaintsDataPatientApp_shouldReturnServicePayload() throws Exception {
+ when(commonPatientAppMasterService.savechiefComplaintsData(REQUEST)).thenReturn("saved");
+
+ String result = controller.saveBenChiefComplaintsDataPatientApp(REQUEST, AUTHORIZATION);
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("saved"));
+ }
+
+ @Test
+ @DisplayName("saveBenChiefComplaintsDataPatientApp should report a request the service could not act on")
+ void saveBenChiefComplaintsDataPatientApp_shouldReportRequestItCannotActOn() throws Exception {
+ when(commonPatientAppMasterService.savechiefComplaintsData(REQUEST))
+ .thenThrow(new IllegalStateException("save failed"));
+
+ assertTrue(controller.saveBenChiefComplaintsDataPatientApp(REQUEST, AUTHORIZATION).contains("Unable to save data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("saveTCSlotDataPatientApp")
+ class SaveTCSlotDataPatientAppTests {
+
+ @Test
+ @DisplayName("saveTCSlotDataPatientApp should confirm the booked slot")
+ void saveTCSlotDataPatientApp_shouldConfirmBookedSlot() throws Exception {
+ when(commonPatientAppMasterService.bookTCSlotData(REQUEST, AUTHORIZATION)).thenReturn(1);
+
+ String result = controller.saveTCSlotDataPatientApp(REQUEST, AUTHORIZATION);
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("saveTCSlotDataPatientApp should report a slot the service could not book")
+ void saveTCSlotDataPatientApp_shouldReportUnbookedSlot() throws Exception {
+ when(commonPatientAppMasterService.bookTCSlotData(REQUEST, AUTHORIZATION)).thenReturn(null);
+
+ assertTrue(controller.saveTCSlotDataPatientApp(REQUEST, AUTHORIZATION).contains("error in slot booking"));
+ }
+
+ @Test
+ @DisplayName("saveTCSlotDataPatientApp should report a request the service could not act on")
+ void saveTCSlotDataPatientApp_shouldReportRequestItCannotActOn() throws Exception {
+ when(commonPatientAppMasterService.bookTCSlotData(REQUEST, AUTHORIZATION))
+ .thenThrow(new IllegalStateException("booking failed"));
+
+ assertTrue(controller.saveTCSlotDataPatientApp(REQUEST, AUTHORIZATION).contains("error in slot booking"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getPatientEpisodeDataMobileApp")
+ class GetPatientEpisodeDataMobileAppTests {
+
+ @Test
+ @DisplayName("getPatientEpisodeDataMobileApp should return the payload the service produced")
+ void getPatientEpisodeDataMobileApp_shouldReturnServicePayload() throws Exception {
+ when(commonPatientAppMasterService.getPatientEpisodeData(REQUEST)).thenReturn("{\"data\":[]}");
+
+ String result = controller.getPatientEpisodeDataMobileApp(REQUEST, AUTHORIZATION);
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getPatientEpisodeDataMobileApp should report an answer the service could not produce")
+ void getPatientEpisodeDataMobileApp_shouldReportMissingAnswer() throws Exception {
+ when(commonPatientAppMasterService.getPatientEpisodeData(REQUEST)).thenReturn(null);
+
+ assertTrue(controller.getPatientEpisodeDataMobileApp(REQUEST, AUTHORIZATION).contains("error in getting beneficiary episode data"));
+ }
+
+ @Test
+ @DisplayName("getPatientEpisodeDataMobileApp should report a request the service could not act on")
+ void getPatientEpisodeDataMobileApp_shouldReportRequestItCannotActOn() throws Exception {
+ when(commonPatientAppMasterService.getPatientEpisodeData(REQUEST))
+ .thenThrow(new IllegalStateException("lookup failed"));
+
+ assertTrue(controller.getPatientEpisodeDataMobileApp(REQUEST, AUTHORIZATION).contains("error in getting beneficiary episode data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getPatientBookedSlotDetails")
+ class GetPatientBookedSlotDetailsTests {
+
+ @Test
+ @DisplayName("getPatientBookedSlotDetails should return the payload the service produced")
+ void getPatientBookedSlotDetails_shouldReturnServicePayload() throws Exception {
+ when(commonPatientAppMasterService.getPatientBookedSlots(REQUEST)).thenReturn("{\"data\":[]}");
+
+ String result = controller.getPatientBookedSlotDetails(REQUEST, AUTHORIZATION);
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getPatientBookedSlotDetails should report an answer the service could not produce")
+ void getPatientBookedSlotDetails_shouldReportMissingAnswer() throws Exception {
+ when(commonPatientAppMasterService.getPatientBookedSlots(REQUEST)).thenReturn(null);
+
+ assertTrue(controller.getPatientBookedSlotDetails(REQUEST, AUTHORIZATION).contains("error in getting beneficiary booked slot data"));
+ }
+
+ @Test
+ @DisplayName("getPatientBookedSlotDetails should report a request the service could not act on")
+ void getPatientBookedSlotDetails_shouldReportRequestItCannotActOn() throws Exception {
+ when(commonPatientAppMasterService.getPatientBookedSlots(REQUEST))
+ .thenThrow(new IllegalStateException("lookup failed"));
+
+ assertTrue(controller.getPatientBookedSlotDetails(REQUEST, AUTHORIZATION).contains("error in getting beneficiary booked slot data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("saveSpecialistDiagnosisData")
+ class SaveSpecialistDiagnosisDataTests {
+
+ @Test
+ @DisplayName("saveSpecialistDiagnosisData should return the payload the service produced")
+ void saveSpecialistDiagnosisData_shouldReturnServicePayload() throws Exception {
+ when(commonPatientAppMasterService.saveSpecialistDiagnosisData(REQUEST)).thenReturn(4L);
+
+ String result = controller.saveSpecialistDiagnosisData(REQUEST, AUTHORIZATION);
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("saveSpecialistDiagnosisData should report an answer the service could not produce")
+ void saveSpecialistDiagnosisData_shouldReportMissingAnswer() throws Exception {
+ when(commonPatientAppMasterService.saveSpecialistDiagnosisData(REQUEST)).thenReturn(null);
+
+ assertTrue(controller.saveSpecialistDiagnosisData(REQUEST, AUTHORIZATION).contains("error in saving diagnosis data"));
+ }
+
+ @Test
+ @DisplayName("saveSpecialistDiagnosisData should report a request the service could not act on")
+ void saveSpecialistDiagnosisData_shouldReportRequestItCannotActOn() throws Exception {
+ when(commonPatientAppMasterService.saveSpecialistDiagnosisData(REQUEST))
+ .thenThrow(new IllegalStateException("lookup failed"));
+
+ assertTrue(controller.saveSpecialistDiagnosisData(REQUEST, AUTHORIZATION)
+ .contains("error in saving specialist diagnosis data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getSpecialistDiagnosisData")
+ class GetSpecialistDiagnosisDataTests {
+
+ @Test
+ @DisplayName("getSpecialistDiagnosisData should return the payload the service produced")
+ void getSpecialistDiagnosisData_shouldReturnServicePayload() throws Exception {
+ when(commonPatientAppMasterService.getSpecialistDiagnosisData(REQUEST)).thenReturn("{\"data\":[]}");
+
+ String result = controller.getSpecialistDiagnosisData(REQUEST, AUTHORIZATION);
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getSpecialistDiagnosisData should report an answer the service could not produce")
+ void getSpecialistDiagnosisData_shouldReportMissingAnswer() throws Exception {
+ when(commonPatientAppMasterService.getSpecialistDiagnosisData(REQUEST)).thenReturn(null);
+
+ assertTrue(controller.getSpecialistDiagnosisData(REQUEST, AUTHORIZATION).contains("error in getting diagnosis data"));
+ }
+
+ @Test
+ @DisplayName("getSpecialistDiagnosisData should report a request the service could not act on")
+ void getSpecialistDiagnosisData_shouldReportRequestItCannotActOn() throws Exception {
+ when(commonPatientAppMasterService.getSpecialistDiagnosisData(REQUEST))
+ .thenThrow(new IllegalStateException("lookup failed"));
+
+ assertTrue(controller.getSpecialistDiagnosisData(REQUEST, AUTHORIZATION)
+ .contains("error in getting specialist diagnosis data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getPatientsLast_3_Episode")
+ class GetPatientsLast_3_EpisodeTests {
+
+ @Test
+ @DisplayName("getPatientsLast_3_Episode should return the payload the service produced")
+ void getPatientsLast_3_Episode_shouldReturnServicePayload() throws Exception {
+ when(commonPatientAppMasterService.getPatientsLast_3_Episode(REQUEST)).thenReturn("{\"data\":[]}");
+
+ String result = controller.getPatientsLast_3_Episode(REQUEST, AUTHORIZATION);
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getPatientsLast_3_Episode should report an answer the service could not produce")
+ void getPatientsLast_3_Episode_shouldReportMissingAnswer() throws Exception {
+ when(commonPatientAppMasterService.getPatientsLast_3_Episode(REQUEST)).thenReturn(null);
+
+ assertTrue(controller.getPatientsLast_3_Episode(REQUEST, AUTHORIZATION).contains("error in getPatientsLast_3_Episode data"));
+ }
+
+ @Test
+ @DisplayName("getPatientsLast_3_Episode should report a request the service could not act on")
+ void getPatientsLast_3_Episode_shouldReportRequestItCannotActOn() throws Exception {
+ when(commonPatientAppMasterService.getPatientsLast_3_Episode(REQUEST))
+ .thenThrow(new IllegalStateException("lookup failed"));
+
+ assertTrue(controller.getPatientsLast_3_Episode(REQUEST, AUTHORIZATION).contains("error in getPatientsLast_3_Episode data"));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/controller/pnc/PostnatalCareControllerTest.java b/src/test/java/com/iemr/tm/controller/pnc/PostnatalCareControllerTest.java
new file mode 100644
index 00000000..5d73be70
--- /dev/null
+++ b/src/test/java/com/iemr/tm/controller/pnc/PostnatalCareControllerTest.java
@@ -0,0 +1,438 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.controller.pnc;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.google.gson.JsonObject;
+import com.iemr.tm.service.pnc.PNCServiceImpl;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("PostnatalCareController Test Suite")
+class PostnatalCareControllerTest {
+
+ private static final String AUTHORIZATION = "Bearer session-token";
+ private static final Long BEN_REG_ID = 11L;
+ private static final Long VISIT_CODE = 22L;
+ private static final String REQUEST = "{\"beneficiaryRegID\":11,\"visitCode\":22}";
+ private static final String VISIT_REQUEST = "{\"benRegID\":11,\"visitCode\":22}";
+
+ @Mock
+ private PNCServiceImpl pncServiceImpl;
+
+ private PostnatalCareController controller;
+
+ @BeforeEach
+ @DisplayName("Wire the controller with a mocked service")
+ void setUp() {
+ controller = new PostnatalCareController();
+ controller.setPncServiceImpl(pncServiceImpl);
+ }
+
+ @Nested
+ @DisplayName("saveBenPNCNurseData")
+ class SavenurseTests {
+
+ @Test
+ @DisplayName("saveBenPNCNurseData should return the payload produced by the service")
+ void saveBenPNCNurseData_shouldReturnServicePayload() throws Exception {
+ when(pncServiceImpl.savePNCNurseData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn("{\"visitCode\":\"22\"}");
+
+ String result = controller.saveBenPNCNurseData(REQUEST, AUTHORIZATION);
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("visitCode"));
+ }
+
+ @Test
+ @DisplayName("saveBenPNCNurseData should roll back the visit details when the service fails")
+ void saveBenPNCNurseData_shouldRollBackVisitDetailsOnFailure() throws Exception {
+ when(pncServiceImpl.savePNCNurseData(any(JsonObject.class), eq(AUTHORIZATION)))
+ .thenThrow(new IllegalStateException("save failed"));
+
+ assertTrue(controller.saveBenPNCNurseData(REQUEST, AUTHORIZATION).contains("save failed"));
+ verify(pncServiceImpl).deleteVisitDetails(any(JsonObject.class));
+ }
+
+ @Test
+ @DisplayName("saveBenPNCNurseData should return the untouched failure response for a null request")
+ void saveBenPNCNurseData_shouldReturnGenericFailureForNullRequest() throws Exception {
+ assertTrue(controller.saveBenPNCNurseData(null, AUTHORIZATION).contains("Failed with generic error"));
+ verify(pncServiceImpl, never()).savePNCNurseData(any(JsonObject.class), anyString());
+ }
+ }
+
+ @Nested
+ @DisplayName("saveBenPNCDoctorData")
+ class SavedoctorTests {
+
+ @Test
+ @DisplayName("saveBenPNCDoctorData should confirm the save when the service returns an id")
+ void saveBenPNCDoctorData_shouldConfirmSave() throws Exception {
+ when(pncServiceImpl.savePNCDoctorData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn(7L);
+
+ assertTrue(controller.saveBenPNCDoctorData(REQUEST, AUTHORIZATION).contains("Data saved successfully"));
+ }
+
+ @Test
+ @DisplayName("saveBenPNCDoctorData should report an unsuccessful save")
+ void saveBenPNCDoctorData_shouldReportUnsuccessfulSave() throws Exception {
+ when(pncServiceImpl.savePNCDoctorData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn(0L);
+
+ assertTrue(controller.saveBenPNCDoctorData(REQUEST, AUTHORIZATION).contains("Unable to save data"));
+ }
+
+ @Test
+ @DisplayName("saveBenPNCDoctorData should surface a service failure")
+ void saveBenPNCDoctorData_shouldSurfaceServiceFailure() throws Exception {
+ when(pncServiceImpl.savePNCDoctorData(any(JsonObject.class), eq(AUTHORIZATION)))
+ .thenThrow(new IllegalStateException("doctor save failed"));
+
+ assertTrue(controller.saveBenPNCDoctorData(REQUEST, AUTHORIZATION).contains("doctor save failed"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenVisitDetailsFrmNursePNC")
+ class ReadvisitTests {
+
+ @Test
+ @DisplayName("getBenVisitDetailsFrmNursePNC should return the details for a complete request")
+ void getBenVisitDetailsFrmNursePNC_shouldReturnDetails() throws Exception {
+ when(pncServiceImpl.getBenVisitDetailsFrmNursePNC(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenVisitDetailsFrmNursePNC(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenVisitDetailsFrmNursePNC should reject an incomplete request")
+ void getBenVisitDetailsFrmNursePNC_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenVisitDetailsFrmNursePNC("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenVisitDetailsFrmNursePNC should surface a service failure")
+ void getBenVisitDetailsFrmNursePNC_shouldSurfaceServiceFailure() throws Exception {
+ when(pncServiceImpl.getBenVisitDetailsFrmNursePNC(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenVisitDetailsFrmNursePNC(VISIT_REQUEST).contains("Error while getting beneficiary visit data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenPNCDetailsFrmNursePNC")
+ class ReadpncTests {
+
+ @Test
+ @DisplayName("getBenPNCDetailsFrmNursePNC should return the details for a complete request")
+ void getBenPNCDetailsFrmNursePNC_shouldReturnDetails() throws Exception {
+ when(pncServiceImpl.getBenPNCDetailsFrmNursePNC(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenPNCDetailsFrmNursePNC(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenPNCDetailsFrmNursePNC should reject an incomplete request")
+ void getBenPNCDetailsFrmNursePNC_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenPNCDetailsFrmNursePNC("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenPNCDetailsFrmNursePNC should surface a service failure")
+ void getBenPNCDetailsFrmNursePNC_shouldSurfaceServiceFailure() throws Exception {
+ when(pncServiceImpl.getBenPNCDetailsFrmNursePNC(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenPNCDetailsFrmNursePNC(VISIT_REQUEST).contains("Error while getting beneficiary PNC Care data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenHistoryDetails")
+ class ReadhistoryTests {
+
+ @Test
+ @DisplayName("getBenHistoryDetails should return the details for a complete request")
+ void getBenHistoryDetails_shouldReturnDetails() throws Exception {
+ when(pncServiceImpl.getBenHistoryDetails(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenHistoryDetails(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenHistoryDetails should reject an incomplete request")
+ void getBenHistoryDetails_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenHistoryDetails("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenHistoryDetails should surface a service failure")
+ void getBenHistoryDetails_shouldSurfaceServiceFailure() throws Exception {
+ when(pncServiceImpl.getBenHistoryDetails(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenHistoryDetails(VISIT_REQUEST).contains("Error while getting beneficiary history data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenVitalDetailsFrmNurse")
+ class ReadvitalsTests {
+
+ @Test
+ @DisplayName("getBenVitalDetailsFrmNurse should return the details for a complete request")
+ void getBenVitalDetailsFrmNurse_shouldReturnDetails() throws Exception {
+ when(pncServiceImpl.getBeneficiaryVitalDetails(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenVitalDetailsFrmNurse(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenVitalDetailsFrmNurse should reject an incomplete request")
+ void getBenVitalDetailsFrmNurse_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenVitalDetailsFrmNurse("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenVitalDetailsFrmNurse should surface a service failure")
+ void getBenVitalDetailsFrmNurse_shouldSurfaceServiceFailure() throws Exception {
+ when(pncServiceImpl.getBeneficiaryVitalDetails(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenVitalDetailsFrmNurse(VISIT_REQUEST).contains("Error while getting beneficiary vital data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenExaminationDetailsPNC")
+ class ReadexaminationTests {
+
+ @Test
+ @DisplayName("getBenExaminationDetailsPNC should return the details for a complete request")
+ void getBenExaminationDetailsPNC_shouldReturnDetails() throws Exception {
+ when(pncServiceImpl.getPNCExaminationDetailsData(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenExaminationDetailsPNC(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenExaminationDetailsPNC should reject an incomplete request")
+ void getBenExaminationDetailsPNC_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenExaminationDetailsPNC("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenExaminationDetailsPNC should surface a service failure")
+ void getBenExaminationDetailsPNC_shouldSurfaceServiceFailure() throws Exception {
+ when(pncServiceImpl.getPNCExaminationDetailsData(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenExaminationDetailsPNC(VISIT_REQUEST).contains("Error while getting beneficiary examination data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenCaseRecordFromDoctorPNC")
+ class ReadcaserecordTests {
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorPNC should return the details for a complete request")
+ void getBenCaseRecordFromDoctorPNC_shouldReturnDetails() throws Exception {
+ when(pncServiceImpl.getBenCaseRecordFromDoctorPNC(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenCaseRecordFromDoctorPNC(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorPNC should reject an incomplete request")
+ void getBenCaseRecordFromDoctorPNC_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenCaseRecordFromDoctorPNC("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorPNC should surface a service failure")
+ void getBenCaseRecordFromDoctorPNC_shouldSurfaceServiceFailure() throws Exception {
+ when(pncServiceImpl.getBenCaseRecordFromDoctorPNC(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenCaseRecordFromDoctorPNC(VISIT_REQUEST).contains("Error while getting beneficiary doctor data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("updatePNCCareNurse")
+ class UpdatepncTests {
+
+ @Test
+ @DisplayName("updatePNCCareNurse should confirm the update when a row was changed")
+ void updatePNCCareNurse_shouldConfirmUpdate() throws Exception {
+ when(pncServiceImpl.updateBenPNCDetails(any(JsonObject.class))).thenReturn(1);
+
+ assertTrue(controller.updatePNCCareNurse(REQUEST).contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("updatePNCCareNurse should report that nothing was modified")
+ void updatePNCCareNurse_shouldReportNothingModified() throws Exception {
+ when(pncServiceImpl.updateBenPNCDetails(any(JsonObject.class))).thenReturn(0);
+
+ assertTrue(controller.updatePNCCareNurse(REQUEST).contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updatePNCCareNurse should surface a service failure")
+ void updatePNCCareNurse_shouldSurfaceServiceFailure() throws Exception {
+ when(pncServiceImpl.updateBenPNCDetails(any(JsonObject.class))).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.updatePNCCareNurse(REQUEST).contains("Unable to modify data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("updateHistoryNurse")
+ class UpdatehistoryTests {
+
+ @Test
+ @DisplayName("updateHistoryNurse should confirm the update when a row was changed")
+ void updateHistoryNurse_shouldConfirmUpdate() throws Exception {
+ when(pncServiceImpl.updateBenHistoryDetails(any(JsonObject.class))).thenReturn(1);
+
+ assertTrue(controller.updateHistoryNurse(REQUEST).contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("updateHistoryNurse should report that nothing was modified")
+ void updateHistoryNurse_shouldReportNothingModified() throws Exception {
+ when(pncServiceImpl.updateBenHistoryDetails(any(JsonObject.class))).thenReturn(0);
+
+ assertTrue(controller.updateHistoryNurse(REQUEST).contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updateHistoryNurse should surface a service failure")
+ void updateHistoryNurse_shouldSurfaceServiceFailure() throws Exception {
+ when(pncServiceImpl.updateBenHistoryDetails(any(JsonObject.class))).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.updateHistoryNurse(REQUEST).contains("Unable to modify data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("updateVitalNurse")
+ class UpdatevitalsTests {
+
+ @Test
+ @DisplayName("updateVitalNurse should confirm the update when a row was changed")
+ void updateVitalNurse_shouldConfirmUpdate() throws Exception {
+ when(pncServiceImpl.updateBenVitalDetails(any(JsonObject.class))).thenReturn(1);
+
+ assertTrue(controller.updateVitalNurse(REQUEST).contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("updateVitalNurse should report that nothing was modified")
+ void updateVitalNurse_shouldReportNothingModified() throws Exception {
+ when(pncServiceImpl.updateBenVitalDetails(any(JsonObject.class))).thenReturn(0);
+
+ assertTrue(controller.updateVitalNurse(REQUEST).contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updateVitalNurse should surface a service failure")
+ void updateVitalNurse_shouldSurfaceServiceFailure() throws Exception {
+ when(pncServiceImpl.updateBenVitalDetails(any(JsonObject.class))).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.updateVitalNurse(REQUEST).contains("Unable to modify data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("updateGeneralOPDExaminationNurse")
+ class UpdateexaminationTests {
+
+ @Test
+ @DisplayName("updateGeneralOPDExaminationNurse should confirm the update when a row was changed")
+ void updateGeneralOPDExaminationNurse_shouldConfirmUpdate() throws Exception {
+ when(pncServiceImpl.updateBenExaminationDetails(any(JsonObject.class))).thenReturn(1);
+
+ assertTrue(controller.updateGeneralOPDExaminationNurse(REQUEST).contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("updateGeneralOPDExaminationNurse should report that nothing was modified")
+ void updateGeneralOPDExaminationNurse_shouldReportNothingModified() throws Exception {
+ when(pncServiceImpl.updateBenExaminationDetails(any(JsonObject.class))).thenReturn(0);
+
+ assertTrue(controller.updateGeneralOPDExaminationNurse(REQUEST).contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updateGeneralOPDExaminationNurse should surface a service failure")
+ void updateGeneralOPDExaminationNurse_shouldSurfaceServiceFailure() throws Exception {
+ when(pncServiceImpl.updateBenExaminationDetails(any(JsonObject.class))).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.updateGeneralOPDExaminationNurse(REQUEST).contains("Unable to modify data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("updatePNCDoctorData")
+ class UpdatedoctorTests {
+
+ @Test
+ @DisplayName("updatePNCDoctorData should confirm the update when a row was changed")
+ void updatePNCDoctorData_shouldConfirmUpdate() throws Exception {
+ when(pncServiceImpl.updatePNCDoctorData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn(1L);
+
+ assertTrue(controller.updatePNCDoctorData(REQUEST, AUTHORIZATION).contains("Data updated successfully"));
+ }
+
+ @Test
+ @DisplayName("updatePNCDoctorData should report that nothing was modified")
+ void updatePNCDoctorData_shouldReportNothingModified() throws Exception {
+ when(pncServiceImpl.updatePNCDoctorData(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn(0L);
+
+ assertTrue(controller.updatePNCDoctorData(REQUEST, AUTHORIZATION).contains("Unable to modify data"));
+ }
+
+ @Test
+ @DisplayName("updatePNCDoctorData should surface a service failure")
+ void updatePNCDoctorData_shouldSurfaceServiceFailure() throws Exception {
+ when(pncServiceImpl.updatePNCDoctorData(any(JsonObject.class), eq(AUTHORIZATION)))
+ .thenThrow(new IllegalStateException("update failed"));
+
+ assertTrue(controller.updatePNCDoctorData(REQUEST, AUTHORIZATION).contains("update failed"));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/controller/quickBlox/QuickbloxControllerTest.java b/src/test/java/com/iemr/tm/controller/quickBlox/QuickbloxControllerTest.java
new file mode 100644
index 00000000..3e1a9a1d
--- /dev/null
+++ b/src/test/java/com/iemr/tm/controller/quickBlox/QuickbloxControllerTest.java
@@ -0,0 +1,67 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.controller.quickBlox;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import com.iemr.tm.service.quickBlox.QuickbloxService;
+
+@ExtendWith(MockitoExtension.class)
+@DisplayName("QuickbloxController Test Suite")
+class QuickbloxControllerTest {
+
+ private static final String AUTHORIZATION = "Bearer session-token";
+ private static final String REQUEST = "{\"userName\":\"nurse\"}";
+
+ @Mock
+ private QuickbloxService quickbloxService;
+
+ @InjectMocks
+ private QuickbloxController controller;
+
+ @Test
+ @DisplayName("getquickbloxIds should return the ids produced by the service")
+ void getquickbloxIds_shouldReturnServiceIds() throws Exception {
+ when(quickbloxService.getQuickbloxIds(REQUEST)).thenReturn("{\"quickbloxId\":\"99\"}");
+
+ String result = controller.getquickbloxIds(REQUEST, AUTHORIZATION);
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("quickbloxId"));
+ }
+
+ @Test
+ @DisplayName("getquickbloxIds should surface a service failure")
+ void getquickbloxIds_shouldSurfaceServiceFailure() throws Exception {
+ when(quickbloxService.getQuickbloxIds(REQUEST)).thenThrow(new IllegalStateException("quickblox down"));
+
+ assertTrue(controller.getquickbloxIds(REQUEST, AUTHORIZATION).contains("Error while getting quickblox Ids"));
+ }
+}
diff --git a/src/test/java/com/iemr/tm/controller/quickconsult/QuickConsultControllerTest.java b/src/test/java/com/iemr/tm/controller/quickconsult/QuickConsultControllerTest.java
new file mode 100644
index 00000000..8cf9bdc0
--- /dev/null
+++ b/src/test/java/com/iemr/tm/controller/quickconsult/QuickConsultControllerTest.java
@@ -0,0 +1,181 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.controller.quickconsult;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.google.gson.JsonObject;
+import com.iemr.tm.service.quickConsultation.QuickConsultationServiceImpl;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("QuickConsultController Test Suite")
+class QuickConsultControllerTest {
+
+ private static final String AUTHORIZATION = "Bearer session-token";
+ private static final Long BEN_REG_ID = 11L;
+ private static final Long VISIT_CODE = 22L;
+ private static final String REQUEST = "{\"beneficiaryRegID\":11,\"visitCode\":22}";
+ private static final String VISIT_REQUEST = "{\"benRegID\":11,\"visitCode\":22}";
+
+ @Mock
+ private QuickConsultationServiceImpl quickConsultationServiceImpl;
+
+ private QuickConsultController controller;
+
+ @BeforeEach
+ @DisplayName("Wire the controller with mocked services")
+ void setUp() {
+ controller = new QuickConsultController();
+ controller.setQuickConsultationServiceImpl(quickConsultationServiceImpl);
+ }
+
+ @Nested
+ @DisplayName("saveBenQuickConsultDataNurse")
+ class SaveNurseTests {
+
+ @Test
+ @DisplayName("saveBenQuickConsultDataNurse should return the payload produced by the service")
+ void saveBenQuickConsultDataNurse_shouldReturnServicePayload() throws Exception {
+ when(quickConsultationServiceImpl.quickConsultNurseDataInsert(any(JsonObject.class), eq(AUTHORIZATION))).thenReturn("{\"visitCode\":\"22\"}");
+
+ String result = controller.saveBenQuickConsultDataNurse(REQUEST, AUTHORIZATION);
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("visitCode"));
+ }
+
+ @Test
+ @DisplayName("saveBenQuickConsultDataNurse should roll back the visit details when the service fails")
+ void saveBenQuickConsultDataNurse_shouldRollBackVisitDetailsOnFailure() throws Exception {
+ when(quickConsultationServiceImpl.quickConsultNurseDataInsert(any(JsonObject.class), eq(AUTHORIZATION)))
+ .thenThrow(new IllegalStateException("save failed"));
+
+ assertTrue(controller.saveBenQuickConsultDataNurse(REQUEST, AUTHORIZATION).contains("save failed"));
+ verify(quickConsultationServiceImpl).deleteVisitDetails(any(JsonObject.class));
+ }
+
+ @Test
+ @DisplayName("saveBenQuickConsultDataNurse should return the untouched failure response for a null request")
+ void saveBenQuickConsultDataNurse_shouldReturnGenericFailureForNullRequest() throws Exception {
+ assertTrue(controller.saveBenQuickConsultDataNurse(null, AUTHORIZATION).contains("Failed with generic error"));
+ verify(quickConsultationServiceImpl, never()).quickConsultNurseDataInsert(any(JsonObject.class), anyString());
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenDataFrmNurseScrnToDocScrnVisitDetails")
+ class ReadVisitTests {
+
+ @Test
+ @DisplayName("getBenDataFrmNurseScrnToDocScrnVisitDetails should return the details for a complete request")
+ void getBenDataFrmNurseScrnToDocScrnVisitDetails_shouldReturnDetails() throws Exception {
+ when(quickConsultationServiceImpl.getBenDataFrmNurseToDocVisitDetailsScreen(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenDataFrmNurseScrnToDocScrnVisitDetails(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenDataFrmNurseScrnToDocScrnVisitDetails should reject an incomplete request")
+ void getBenDataFrmNurseScrnToDocScrnVisitDetails_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenDataFrmNurseScrnToDocScrnVisitDetails("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenDataFrmNurseScrnToDocScrnVisitDetails should surface a service failure")
+ void getBenDataFrmNurseScrnToDocScrnVisitDetails_shouldSurfaceServiceFailure() throws Exception {
+ when(quickConsultationServiceImpl.getBenDataFrmNurseToDocVisitDetailsScreen(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenDataFrmNurseScrnToDocScrnVisitDetails(VISIT_REQUEST).contains("Error while getting visit data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenVitalDetailsFrmNurse")
+ class ReadVitalsTests {
+
+ @Test
+ @DisplayName("getBenVitalDetailsFrmNurse should return the details for a complete request")
+ void getBenVitalDetailsFrmNurse_shouldReturnDetails() throws Exception {
+ when(quickConsultationServiceImpl.getBeneficiaryVitalDetails(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenVitalDetailsFrmNurse(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenVitalDetailsFrmNurse should reject an incomplete request")
+ void getBenVitalDetailsFrmNurse_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenVitalDetailsFrmNurse("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenVitalDetailsFrmNurse should surface a service failure")
+ void getBenVitalDetailsFrmNurse_shouldSurfaceServiceFailure() throws Exception {
+ when(quickConsultationServiceImpl.getBeneficiaryVitalDetails(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenVitalDetailsFrmNurse(VISIT_REQUEST).contains("Error while getting vital data"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getBenCaseRecordFromDoctorQuickConsult")
+ class ReadCaseRecordTests {
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorQuickConsult should return the details for a complete request")
+ void getBenCaseRecordFromDoctorQuickConsult_shouldReturnDetails() throws Exception {
+ when(quickConsultationServiceImpl.getBenCaseRecordFromDoctorQuickConsult(BEN_REG_ID, VISIT_CODE)).thenReturn("{\"result\":1}");
+
+ assertTrue(controller.getBenCaseRecordFromDoctorQuickConsult(VISIT_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorQuickConsult should reject an incomplete request")
+ void getBenCaseRecordFromDoctorQuickConsult_shouldRejectIncompleteRequest() throws Exception {
+ assertTrue(controller.getBenCaseRecordFromDoctorQuickConsult("{\"benRegID\":11}").contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorQuickConsult should surface a service failure")
+ void getBenCaseRecordFromDoctorQuickConsult_shouldSurfaceServiceFailure() throws Exception {
+ when(quickConsultationServiceImpl.getBenCaseRecordFromDoctorQuickConsult(BEN_REG_ID, VISIT_CODE)).thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getBenCaseRecordFromDoctorQuickConsult(VISIT_REQUEST).contains("Error while getting doctor data"));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/controller/registrar/main/RegistrarControllerTest.java b/src/test/java/com/iemr/tm/controller/registrar/main/RegistrarControllerTest.java
new file mode 100644
index 00000000..97e1f0c4
--- /dev/null
+++ b/src/test/java/com/iemr/tm/controller/registrar/main/RegistrarControllerTest.java
@@ -0,0 +1,399 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.controller.registrar.main;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.data.registrar.BeneficiaryData;
+import com.iemr.tm.service.common.master.RegistrarServiceMasterDataImpl;
+import com.iemr.tm.service.common.transaction.CommonNurseServiceImpl;
+import com.iemr.tm.service.nurse.NurseServiceImpl;
+import com.iemr.tm.service.registrar.RegistrarServiceImpl;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("RegistrarController Test Suite")
+class RegistrarControllerTest {
+
+ private static final String AUTHORIZATION = "Bearer session-token";
+ private static final Long BEN_REG_ID = 11L;
+ private static final String BEN_REQUEST = "{\"beneficiaryRegID\":11}";
+
+ @Mock
+ private RegistrarServiceImpl registrarServiceImpl;
+ @Mock
+ private RegistrarServiceMasterDataImpl registrarServiceMasterDataImpl;
+ @Mock
+ private NurseServiceImpl nurseServiceImpl;
+ @Mock
+ private CommonNurseServiceImpl commonNurseServiceImpl;
+
+ private RegistrarController controller;
+
+ @BeforeEach
+ @DisplayName("Wire the controller with mocked registrar services")
+ void setUp() {
+ controller = new RegistrarController();
+ controller.setRegistrarServiceImpl(registrarServiceImpl);
+ controller.setRegistrarServiceMasterDataImpl(registrarServiceMasterDataImpl);
+ controller.setNurseServiceImpl(nurseServiceImpl);
+ org.springframework.test.util.ReflectionTestUtils.setField(controller, "commonNurseServiceImpl",
+ commonNurseServiceImpl);
+ }
+
+ @Nested
+ @DisplayName("search endpoints")
+ class SearchTests {
+
+ @Test
+ @DisplayName("getRegistrarWorkList should return the worklist for the service point")
+ void getRegistrarWorkList_shouldReturnWorklist() throws Exception {
+ when(registrarServiceImpl.getRegWorkList(9)).thenReturn("[]");
+
+ assertTrue(controller.getRegistrarWorkList("{\"spID\":9}").contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getRegistrarWorkList should surface a malformed request")
+ void getRegistrarWorkList_shouldSurfaceMalformedRequest() throws Exception {
+ assertTrue(controller.getRegistrarWorkList("{}").contains("\"statusCode\""));
+ }
+
+ @Test
+ @DisplayName("quickSearchBeneficiary should return the matched beneficiaries")
+ void quickSearchBeneficiary_shouldReturnMatches() throws Exception {
+ when(registrarServiceImpl.getQuickSearchBenData("BEN1")).thenReturn("[]");
+
+ assertTrue(controller.quickSearchBeneficiary("{\"benID\":\"BEN1\"}").contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("advanceSearch should return the matched beneficiaries")
+ void advanceSearch_shouldReturnMatches() throws Exception {
+ when(registrarServiceImpl.getAdvanceSearchBenData(any())).thenReturn("[]");
+
+ assertTrue(controller.advanceSearch("{\"firstName\":\"Asha\"}").contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("quickSearchNew should return the matched beneficiaries")
+ void quickSearchNew_shouldReturnMatches() throws Exception {
+ when(registrarServiceImpl.beneficiaryQuickSearch(BEN_REQUEST, AUTHORIZATION)).thenReturn("[{\"id\":1}]");
+
+ assertEquals("[{\"id\":1}]", controller.quickSearchNew(BEN_REQUEST, AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("quickSearchNew should reject a null request")
+ void quickSearchNew_shouldRejectNullRequest() throws Exception {
+ assertTrue(controller.quickSearchNew(null, AUTHORIZATION).contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("quickSearchNew should surface a service failure")
+ void quickSearchNew_shouldSurfaceServiceFailure() throws Exception {
+ when(registrarServiceImpl.beneficiaryQuickSearch(BEN_REQUEST, AUTHORIZATION))
+ .thenThrow(new IllegalStateException("identity down"));
+
+ assertTrue(controller.quickSearchNew(BEN_REQUEST, AUTHORIZATION)
+ .contains("Error while searching beneficiary"));
+ }
+
+ @Test
+ @DisplayName("advanceSearchNew should return the matched beneficiaries")
+ void advanceSearchNew_shouldReturnMatches() throws Exception {
+ when(registrarServiceImpl.beneficiaryAdvanceSearch(BEN_REQUEST, AUTHORIZATION)).thenReturn("[{\"id\":1}]");
+
+ assertEquals("[{\"id\":1}]", controller.advanceSearchNew(BEN_REQUEST, AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("advanceSearchNew should reject a null request")
+ void advanceSearchNew_shouldRejectNullRequest() throws Exception {
+ assertTrue(controller.advanceSearchNew(null, AUTHORIZATION).contains("Invalid request"));
+ }
+ }
+
+ @Nested
+ @DisplayName("beneficiary detail reads")
+ class DetailReadTests {
+
+ @Test
+ @DisplayName("getBenDetailsByRegID should return the stored beneficiary")
+ void getBenDetailsByRegID_shouldReturnBeneficiary() throws Exception {
+ when(registrarServiceMasterDataImpl.getBenDetailsByRegID(BEN_REG_ID)).thenReturn("{}");
+
+ assertTrue(controller.getBenDetailsByRegID(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenDetailsByRegID should reject a non positive registration id")
+ void getBenDetailsByRegID_shouldRejectNonPositiveId() throws Exception {
+ assertTrue(controller.getBenDetailsByRegID("{\"beneficiaryRegID\":0}")
+ .contains("Please pass beneficiaryRegID"));
+ }
+
+ @Test
+ @DisplayName("getBenDetailsByRegID should reject a request without the registration id")
+ void getBenDetailsByRegID_shouldRejectRequestWithoutId() throws Exception {
+ assertTrue(controller.getBenDetailsByRegID("{}").contains("Bad Request"));
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryDetails should return the stored beneficiary")
+ void getBeneficiaryDetails_shouldReturnBeneficiary() throws Exception {
+ when(registrarServiceImpl.getBeneficiaryDetails(BEN_REG_ID)).thenReturn("{}");
+
+ assertTrue(controller.getBeneficiaryDetails(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryDetails should report no data when the beneficiary is unknown")
+ void getBeneficiaryDetails_shouldReportNoDataForUnknownBeneficiary() throws Exception {
+ when(registrarServiceImpl.getBeneficiaryDetails(BEN_REG_ID)).thenReturn(null);
+
+ assertTrue(controller.getBeneficiaryDetails(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryDetails should reject a request without the registration id")
+ void getBeneficiaryDetails_shouldRejectRequestWithoutId() throws Exception {
+ assertTrue(controller.getBeneficiaryDetails("{}").contains("\"statusCode\""));
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryImage should return the stored image")
+ void getBeneficiaryImage_shouldReturnImage() throws Exception {
+ when(registrarServiceImpl.getBenImage(BEN_REG_ID)).thenReturn("base64-image");
+
+ assertTrue(controller.getBeneficiaryImage(BEN_REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryImage should reject a request without the registration id")
+ void getBeneficiaryImage_shouldRejectRequestWithoutId() throws Exception {
+ assertTrue(controller.getBeneficiaryImage("{}").contains("Bad Request"));
+ }
+
+ @Test
+ @DisplayName("getBenDetailsForLeftSidePanelByRegID should return the panel details")
+ void getLeftSidePanelDetails_shouldReturnPanelDetails() throws Exception {
+ String request = "{\"beneficiaryRegID\":11,\"benFlowID\":5}";
+ when(registrarServiceMasterDataImpl.getBenDetailsForLeftSideByRegIDNew(BEN_REG_ID, 5L, AUTHORIZATION,
+ request)).thenReturn("{}");
+
+ assertTrue(controller.getBenDetailsForLeftSidePanelByRegID(request, AUTHORIZATION)
+ .contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getBenDetailsForLeftSidePanelByRegID should reject a request without the registration id")
+ void getLeftSidePanelDetails_shouldRejectRequestWithoutId() throws Exception {
+ assertTrue(controller.getBenDetailsForLeftSidePanelByRegID("{}", AUTHORIZATION)
+ .contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("getBenImage should return the identity image")
+ void getBenImage_shouldReturnIdentityImage() throws Exception {
+ when(registrarServiceMasterDataImpl.getBenImageFromIdentityAPI(AUTHORIZATION, BEN_REQUEST))
+ .thenReturn("base64-image");
+
+ assertEquals("base64-image", controller.getBenImage(BEN_REQUEST, AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("getBenImage should surface a service failure")
+ void getBenImage_shouldSurfaceServiceFailure() throws Exception {
+ when(registrarServiceMasterDataImpl.getBenImageFromIdentityAPI(AUTHORIZATION, BEN_REQUEST))
+ .thenThrow(new IllegalStateException("identity down"));
+
+ assertTrue(controller.getBenImage(BEN_REQUEST, AUTHORIZATION)
+ .contains("Error while getting beneficiary image"));
+ }
+
+ @Test
+ @DisplayName("masterDataForRegistration should return the registration master data")
+ void masterDataForRegistration_shouldReturnMasterData() throws Exception {
+ when(registrarServiceMasterDataImpl.getRegMasterData()).thenReturn("{}");
+
+ assertTrue(controller.masterDataForRegistration("{\"spID\":9}").contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("masterDataForRegistration should reject an invalid service point")
+ void masterDataForRegistration_shouldRejectInvalidServicePoint() throws Exception {
+ assertTrue(controller.masterDataForRegistration("{\"spID\":0}").contains("Invalid service point"));
+ }
+
+ @Test
+ @DisplayName("masterDataForRegistration should reject a request without the service point")
+ void masterDataForRegistration_shouldRejectRequestWithoutServicePoint() throws Exception {
+ assertTrue(controller.masterDataForRegistration("{}").contains("Invalid request"));
+ }
+ }
+
+ @Nested
+ @DisplayName("registration and update")
+ class RegistrationTests {
+
+ private static final String BEN_PAYLOAD = "{\"benD\":{\"firstName\":\"Asha\",\"beneficiaryRegID\":11,"
+ + "\"createdBy\":\"registrar1\"}}";
+
+ @Test
+ @DisplayName("createBeneficiary should register the beneficiary and submit them to the nurse worklist")
+ void createBeneficiary_shouldRegisterAndSubmitToNurse() throws Exception {
+ BeneficiaryData created = new BeneficiaryData();
+ created.setBeneficiaryRegID(BEN_REG_ID);
+ created.setBeneficiaryID("BEN1");
+ when(registrarServiceImpl.createBeneficiary(any())).thenReturn(created);
+ when(registrarServiceImpl.createBeneficiaryDemographic(any(), eq(BEN_REG_ID))).thenReturn(1L);
+ when(registrarServiceImpl.createBeneficiaryPhoneMapping(any(), eq(BEN_REG_ID))).thenReturn(1L);
+ when(registrarServiceImpl.createBenGovIdMapping(any(), eq(BEN_REG_ID))).thenReturn(1);
+ when(registrarServiceImpl.createBeneficiaryDemographicAdditional(any(), eq(BEN_REG_ID))).thenReturn(1L);
+ when(registrarServiceImpl.createBeneficiaryImage(any(), eq(BEN_REG_ID))).thenReturn(1L);
+ when(commonNurseServiceImpl.updateBeneficiaryStatus('R', BEN_REG_ID)).thenReturn(1);
+
+ assertTrue(controller.createBeneficiary(BEN_PAYLOAD, AUTHORIZATION).contains("BEN1"));
+ }
+
+ @Test
+ @DisplayName("createBeneficiary should report a failure when the registration did not complete")
+ void createBeneficiary_shouldReportFailureWhenRegistrationIncomplete() throws Exception {
+ BeneficiaryData created = new BeneficiaryData();
+ created.setBeneficiaryRegID(BEN_REG_ID);
+ when(registrarServiceImpl.createBeneficiary(any())).thenReturn(created);
+
+ assertTrue(controller.createBeneficiary(BEN_PAYLOAD, AUTHORIZATION).contains("Something Went-Wrong"));
+ }
+
+ @Test
+ @DisplayName("createBeneficiary should reject a payload without beneficiary details")
+ void createBeneficiary_shouldRejectPayloadWithoutDetails() throws Exception {
+ assertTrue(controller.createBeneficiary("{}", AUTHORIZATION).contains("\"statusCode\""));
+ }
+
+ @Test
+ @DisplayName("registrarBeneficaryRegistrationNew should return the registration payload")
+ void registerBeneficiaryNew_shouldReturnRegistrationPayload() throws Exception {
+ when(registrarServiceImpl.registerBeneficiary(BEN_REQUEST, AUTHORIZATION)).thenReturn("{\"benID\":1}");
+
+ assertEquals("{\"benID\":1}", controller.registrarBeneficaryRegistrationNew(BEN_REQUEST, AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("registrarBeneficaryRegistrationNew should surface a registration failure")
+ void registerBeneficiaryNew_shouldSurfaceRegistrationFailure() throws Exception {
+ when(registrarServiceImpl.registerBeneficiary(BEN_REQUEST, AUTHORIZATION))
+ .thenThrow(new IllegalStateException("identity down"));
+
+ assertTrue(controller.registrarBeneficaryRegistrationNew(BEN_REQUEST, AUTHORIZATION)
+ .contains("Error in registration"));
+ }
+
+ @Test
+ @DisplayName("updateBeneficiary should update every beneficiary section")
+ void updateBeneficiary_shouldUpdateEverySection() throws Exception {
+ when(registrarServiceImpl.updateBeneficiary(any())).thenReturn(1);
+ when(registrarServiceImpl.updateBeneficiaryDemographic(any(), eq(BEN_REG_ID))).thenReturn(1);
+ when(registrarServiceImpl.updateBeneficiaryPhoneMapping(any(), eq(BEN_REG_ID))).thenReturn(1);
+ when(registrarServiceImpl.updateBenGovIdMapping(any(), eq(BEN_REG_ID))).thenReturn(1);
+ when(registrarServiceImpl.updateBeneficiaryDemographicAdditional(any(), eq(BEN_REG_ID))).thenReturn(1);
+ when(registrarServiceImpl.updateBeneficiaryImage(any(), eq(BEN_REG_ID))).thenReturn(1);
+ when(commonNurseServiceImpl.updateBeneficiaryStatus('R', BEN_REG_ID)).thenReturn(1);
+
+ assertTrue(controller.updateBeneficiary(BEN_PAYLOAD).contains("Beneficiary Details updated successfully"));
+ }
+
+ @Test
+ @DisplayName("updateBeneficiary should report a failure when a section did not change")
+ void updateBeneficiary_shouldReportFailureWhenSectionUnchanged() throws Exception {
+ when(registrarServiceImpl.updateBeneficiary(any())).thenReturn(0);
+
+ assertTrue(controller.updateBeneficiary(BEN_PAYLOAD).contains("Something Went-Wrong"));
+ }
+
+ @Test
+ @DisplayName("beneficiaryUpdate should confirm the update")
+ void beneficiaryUpdate_shouldConfirmUpdate() throws Exception {
+ when(registrarServiceImpl.updateBeneficiary(BEN_REQUEST, AUTHORIZATION)).thenReturn(1);
+
+ assertTrue(controller.beneficiaryUpdate(BEN_REQUEST, AUTHORIZATION)
+ .contains("Beneficiary details updated successfully"));
+ }
+
+ @Test
+ @DisplayName("createReVisitForBenToNurse should move the beneficiary to the nurse worklist")
+ void createReVisit_shouldMoveBeneficiaryToNurseWorklist() throws Exception {
+ when(registrarServiceImpl.searchAndSubmitBeneficiaryToNurse(BEN_REQUEST)).thenReturn(1);
+
+ assertTrue(controller.createReVisitForBenToNurse(BEN_REQUEST)
+ .contains("Beneficiary moved to nurse worklist"));
+ }
+
+ @Test
+ @DisplayName("createReVisitForBenToNurse should report a beneficiary already on the worklist")
+ void createReVisit_shouldReportBeneficiaryAlreadyOnWorklist() throws Exception {
+ when(registrarServiceImpl.searchAndSubmitBeneficiaryToNurse(BEN_REQUEST)).thenReturn(2);
+
+ assertTrue(controller.createReVisitForBenToNurse(BEN_REQUEST)
+ .contains("Beneficiary already present in nurse worklist"));
+ }
+
+ @Test
+ @DisplayName("createReVisitForBenToNurse should report a failed move")
+ void createReVisit_shouldReportFailedMove() throws Exception {
+ when(registrarServiceImpl.searchAndSubmitBeneficiaryToNurse(BEN_REQUEST)).thenReturn(0);
+
+ assertTrue(controller.createReVisitForBenToNurse(BEN_REQUEST)
+ .contains("Error while moving beneficiary to nurse worklist"));
+ }
+
+ @Test
+ @DisplayName("createReVisitForBenToNurse should surface a service failure")
+ void createReVisit_shouldSurfaceServiceFailure() throws Exception {
+ when(registrarServiceImpl.searchAndSubmitBeneficiaryToNurse(BEN_REQUEST))
+ .thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.createReVisitForBenToNurse(BEN_REQUEST)
+ .contains("Error while moving beneficiary to nurse worklist"));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/controller/report/CRMReportControllerTest.java b/src/test/java/com/iemr/tm/controller/report/CRMReportControllerTest.java
new file mode 100644
index 00000000..d21a3700
--- /dev/null
+++ b/src/test/java/com/iemr/tm/controller/report/CRMReportControllerTest.java
@@ -0,0 +1,144 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.controller.report;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import com.iemr.tm.data.report.ConsultationReport;
+import com.iemr.tm.data.report.ReportInput;
+import com.iemr.tm.data.report.SpokeReport;
+import com.iemr.tm.data.report.TMDailyReport;
+import com.iemr.tm.service.report.CRMReportService;
+
+@ExtendWith(MockitoExtension.class)
+@DisplayName("CRMReportController Test Suite")
+class CRMReportControllerTest {
+
+ @Mock
+ private CRMReportService cRMReportService;
+
+ @InjectMocks
+ private CRMReportController controller;
+
+ private final ReportInput input = new ReportInput();
+
+ @Test
+ @DisplayName("chiefcomplaintreport should return the chief complaint report")
+ void chiefcomplaintreport_shouldReturnReport() throws Exception {
+ Set report = Collections.singleton(new SpokeReport());
+ when(cRMReportService.getChiefcomplaintreport(any(ReportInput.class))).thenReturn(report);
+
+ assertTrue(controller.chiefcomplaintreport(input).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("chiefcomplaintreport should surface a service failure")
+ void chiefcomplaintreport_shouldSurfaceServiceFailure() throws Exception {
+ when(cRMReportService.getChiefcomplaintreport(any(ReportInput.class)))
+ .thenThrow(new IllegalStateException("report failed"));
+
+ assertTrue(controller.chiefcomplaintreport(input).contains("report failed"));
+ }
+
+ @Test
+ @DisplayName("getConsultationReport should return the consultation report with nulls serialised")
+ void getConsultationReport_shouldReturnReport() throws Exception {
+ List report = Collections.singletonList(new ConsultationReport());
+ when(cRMReportService.getConsultationReport(any(ReportInput.class))).thenReturn(report);
+
+ assertTrue(controller.getConsultationReport(input).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getConsultationReport should surface a service failure")
+ void getConsultationReport_shouldSurfaceServiceFailure() throws Exception {
+ when(cRMReportService.getConsultationReport(any(ReportInput.class)))
+ .thenThrow(new IllegalStateException("report failed"));
+
+ assertTrue(controller.getConsultationReport(input).contains("report failed"));
+ }
+
+ @Test
+ @DisplayName("getTotalConsultationReport should return the total consultation report")
+ void getTotalConsultationReport_shouldReturnReport() throws Exception {
+ when(cRMReportService.getTotalConsultationReport(any(ReportInput.class))).thenReturn("{\"total\":9}");
+
+ assertTrue(controller.getTotalConsultationReport(input).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getTotalConsultationReport should surface a service failure")
+ void getTotalConsultationReport_shouldSurfaceServiceFailure() throws Exception {
+ when(cRMReportService.getTotalConsultationReport(any(ReportInput.class)))
+ .thenThrow(new IllegalStateException("report failed"));
+
+ assertTrue(controller.getTotalConsultationReport(input).contains("report failed"));
+ }
+
+ @Test
+ @DisplayName("getMonthlyReport should return the monthly report")
+ void getMonthlyReport_shouldReturnReport() throws Exception {
+ when(cRMReportService.getMonthlyReport(any(ReportInput.class))).thenReturn("{\"month\":\"Jan\"}");
+
+ assertTrue(controller.getMonthlyReport(input).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getMonthlyReport should surface a service failure")
+ void getMonthlyReport_shouldSurfaceServiceFailure() throws Exception {
+ when(cRMReportService.getMonthlyReport(any(ReportInput.class)))
+ .thenThrow(new IllegalStateException("report failed"));
+
+ assertTrue(controller.getMonthlyReport(input).contains("report failed"));
+ }
+
+ @Test
+ @DisplayName("getDailyReport should return the daily report with nulls serialised")
+ void getDailyReport_shouldReturnReport() throws Exception {
+ List report = Collections.singletonList(new TMDailyReport());
+ when(cRMReportService.getDailyReport(any(ReportInput.class))).thenReturn(report);
+
+ assertTrue(controller.getDailyReport(input).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getDailyReport should surface a service failure")
+ void getDailyReport_shouldSurfaceServiceFailure() throws Exception {
+ when(cRMReportService.getDailyReport(any(ReportInput.class)))
+ .thenThrow(new IllegalStateException("report failed"));
+
+ assertTrue(controller.getDailyReport(input).contains("report failed"));
+ }
+}
diff --git a/src/test/java/com/iemr/tm/controller/snomedct/SnomedControllerTest.java b/src/test/java/com/iemr/tm/controller/snomedct/SnomedControllerTest.java
new file mode 100644
index 00000000..e93a888b
--- /dev/null
+++ b/src/test/java/com/iemr/tm/controller/snomedct/SnomedControllerTest.java
@@ -0,0 +1,149 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.controller.snomedct;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import com.iemr.tm.data.snomedct.SCTDescription;
+import com.iemr.tm.service.snomedct.SnomedService;
+
+@ExtendWith(MockitoExtension.class)
+@DisplayName("SnomedController Test Suite")
+class SnomedControllerTest {
+
+ private static final String TERM_REQUEST = "{\"term\":\"fever\"}";
+
+ @Mock
+ private SnomedService snomedService;
+
+ private SnomedController controller;
+
+ @BeforeEach
+ @DisplayName("Wire the controller with a mocked SNOMED service")
+ void setUp() {
+ controller = new SnomedController();
+ controller.setSnomedService(snomedService);
+ }
+
+ private SCTDescription record(String conceptId, String term) {
+ SCTDescription description = new SCTDescription();
+ description.setConceptID(conceptId);
+ description.setTerm(term);
+ return description;
+ }
+
+ @Nested
+ @DisplayName("getSnomedCTRecord")
+ class GetSnomedCtRecordTests {
+
+ @Test
+ @DisplayName("getSnomedCTRecord should return the matched clinical term")
+ void getSnomedCTRecord_shouldReturnMatchedTerm() {
+ when(snomedService.findSnomedCTRecordFromTerm("fever")).thenReturn(record("386661006", "Fever"));
+
+ String result = controller.getSnomedCTRecord(TERM_REQUEST);
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("386661006"));
+ }
+
+ @Test
+ @DisplayName("getSnomedCTRecord should report no records when the service finds nothing")
+ void getSnomedCTRecord_shouldReportNoRecordsWhenNothingFound() {
+ when(snomedService.findSnomedCTRecordFromTerm("fever")).thenReturn(null);
+
+ assertTrue(controller.getSnomedCTRecord(TERM_REQUEST).contains("No Records Found"));
+ }
+
+ @Test
+ @DisplayName("getSnomedCTRecord should report no records when the match carries no concept id")
+ void getSnomedCTRecord_shouldReportNoRecordsWithoutConceptId() {
+ when(snomedService.findSnomedCTRecordFromTerm("fever")).thenReturn(record(null, "Fever"));
+
+ assertTrue(controller.getSnomedCTRecord(TERM_REQUEST).contains("No Records Found"));
+ }
+
+ @Test
+ @DisplayName("getSnomedCTRecord should surface a service failure")
+ void getSnomedCTRecord_shouldSurfaceServiceFailure() {
+ when(snomedService.findSnomedCTRecordFromTerm("fever")).thenThrow(new IllegalStateException("snomed down"));
+
+ assertTrue(controller.getSnomedCTRecord(TERM_REQUEST).contains("snomed down"));
+ }
+
+ @Test
+ @DisplayName("getSnomedCTRecord should surface a malformed request")
+ void getSnomedCTRecord_shouldSurfaceMalformedRequest() {
+ assertTrue(controller.getSnomedCTRecord("not-json").contains("\"statusCode\""));
+ }
+ }
+
+ @Nested
+ @DisplayName("getSnomedCTRecordList")
+ class GetSnomedCtRecordListTests {
+
+ @Test
+ @DisplayName("getSnomedCTRecordList should return the matched clinical term list")
+ void getSnomedCTRecordList_shouldReturnMatchedList() throws Exception {
+ when(snomedService.findSnomedCTRecordList(any(SCTDescription.class)))
+ .thenReturn("[{\"conceptID\":\"386661006\"}]");
+
+ String result = controller.getSnomedCTRecordList(TERM_REQUEST);
+
+ assertTrue(result.contains("\"statusCode\":200"));
+ assertTrue(result.contains("386661006"));
+ }
+
+ @Test
+ @DisplayName("getSnomedCTRecordList should report no records when the service returns nothing")
+ void getSnomedCTRecordList_shouldReportNoRecords() throws Exception {
+ when(snomedService.findSnomedCTRecordList(any(SCTDescription.class))).thenReturn(null);
+
+ assertTrue(controller.getSnomedCTRecordList(TERM_REQUEST).contains("No Records Found"));
+ }
+
+ @Test
+ @DisplayName("getSnomedCTRecordList should surface a service failure")
+ void getSnomedCTRecordList_shouldSurfaceServiceFailure() throws Exception {
+ when(snomedService.findSnomedCTRecordList(any(SCTDescription.class)))
+ .thenThrow(new IllegalStateException("snomed down"));
+
+ assertTrue(controller.getSnomedCTRecordList(TERM_REQUEST).contains("snomed down"));
+ }
+
+ @Test
+ @DisplayName("getSnomedCTRecordList should surface a malformed request")
+ void getSnomedCTRecordList_shouldSurfaceMalformedRequest() {
+ assertTrue(controller.getSnomedCTRecordList("not-json").contains("\"statusCode\""));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/controller/teleconsultation/TeleConsultationControllerTest.java b/src/test/java/com/iemr/tm/controller/teleconsultation/TeleConsultationControllerTest.java
new file mode 100644
index 00000000..1724d56d
--- /dev/null
+++ b/src/test/java/com/iemr/tm/controller/teleconsultation/TeleConsultationControllerTest.java
@@ -0,0 +1,321 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.controller.teleconsultation;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.security.core.Authentication;
+
+import com.google.gson.JsonObject;
+import com.iemr.tm.service.tele_consultation.TeleConsultationServiceImpl;
+
+@ExtendWith(MockitoExtension.class)
+@DisplayName("TeleConsultationController Test Suite")
+class TeleConsultationControllerTest {
+
+ private static final String AUTHORIZATION = "Bearer session-token";
+ private static final String REQUEST = "{\"benRegID\":11,\"visitCode\":22}";
+
+ @Mock
+ private TeleConsultationServiceImpl teleConsultationServiceImpl;
+
+ @Mock
+ private Authentication authentication;
+
+ @InjectMocks
+ private TeleConsultationController controller;
+
+ @Nested
+ @DisplayName("benArrivalStatusUpdater")
+ class ArrivalStatusTests {
+
+ @Test
+ @DisplayName("benArrivalStatusUpdater should confirm the update when a row was changed")
+ void benArrivalStatusUpdater_shouldConfirmUpdate() throws Exception {
+ when(teleConsultationServiceImpl.updateBeneficiaryArrivalStatus(REQUEST)).thenReturn(1);
+
+ assertTrue(controller.benArrivalStatusUpdater(REQUEST)
+ .contains("Beneficiary arrival status updated successfully."));
+ }
+
+ @Test
+ @DisplayName("benArrivalStatusUpdater should report a failure when no row was changed")
+ void benArrivalStatusUpdater_shouldReportFailureWhenNothingChanged() throws Exception {
+ when(teleConsultationServiceImpl.updateBeneficiaryArrivalStatus(REQUEST)).thenReturn(0);
+
+ assertTrue(controller.benArrivalStatusUpdater(REQUEST)
+ .contains("Error in updating beneficiary arrival status."));
+ }
+
+ @Test
+ @DisplayName("benArrivalStatusUpdater should reject a null request")
+ void benArrivalStatusUpdater_shouldRejectNullRequest() throws Exception {
+ String result = controller.benArrivalStatusUpdater(null);
+
+ assertTrue(result.contains("Invalid request"));
+ verify(teleConsultationServiceImpl, never()).updateBeneficiaryArrivalStatus(anyString());
+ }
+
+ @Test
+ @DisplayName("benArrivalStatusUpdater should surface a service failure")
+ void benArrivalStatusUpdater_shouldSurfaceServiceFailure() throws Exception {
+ when(teleConsultationServiceImpl.updateBeneficiaryArrivalStatus(REQUEST))
+ .thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.benArrivalStatusUpdater(REQUEST)
+ .contains("Error while updating beneficiary arrival status."));
+ }
+ }
+
+ @Nested
+ @DisplayName("updateBeneficiaryStatusToCancelTCRequest")
+ class CancelRequestTests {
+
+ @Test
+ @DisplayName("updateBeneficiaryStatusToCancelTCRequest should confirm the cancellation")
+ void cancelTCRequest_shouldConfirmCancellation() throws Exception {
+ when(teleConsultationServiceImpl.updateBeneficiaryStatusToCancelTCRequest(REQUEST, AUTHORIZATION))
+ .thenReturn(1);
+
+ assertTrue(controller.updateBeneficiaryStatusToCancelTCRequest(REQUEST, AUTHORIZATION)
+ .contains("Beneficiary TC request cancelled successfully."));
+ }
+
+ @Test
+ @DisplayName("updateBeneficiaryStatusToCancelTCRequest should report a failed cancellation")
+ void cancelTCRequest_shouldReportFailedCancellation() throws Exception {
+ when(teleConsultationServiceImpl.updateBeneficiaryStatusToCancelTCRequest(REQUEST, AUTHORIZATION))
+ .thenReturn(0);
+
+ assertTrue(controller.updateBeneficiaryStatusToCancelTCRequest(REQUEST, AUTHORIZATION)
+ .contains("Teleconsultation cancel request failed."));
+ }
+
+ @Test
+ @DisplayName("updateBeneficiaryStatusToCancelTCRequest should reject a null request")
+ void cancelTCRequest_shouldRejectNullRequest() {
+ assertTrue(controller.updateBeneficiaryStatusToCancelTCRequest(null, AUTHORIZATION)
+ .contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("updateBeneficiaryStatusToCancelTCRequest should surface a service failure")
+ void cancelTCRequest_shouldSurfaceServiceFailure() throws Exception {
+ when(teleConsultationServiceImpl.updateBeneficiaryStatusToCancelTCRequest(REQUEST, AUTHORIZATION))
+ .thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.updateBeneficiaryStatusToCancelTCRequest(REQUEST, AUTHORIZATION)
+ .contains("Error while updating beneficiary status"));
+ }
+ }
+
+ @Nested
+ @DisplayName("checkBeneficiaryStatusToProceedWithSpecialist")
+ class CheckStatusTests {
+
+ @Test
+ @DisplayName("checkBeneficiaryStatusToProceedWithSpecialist should allow the specialist to proceed")
+ void checkStatus_shouldAllowSpecialistToProceed() throws Exception {
+ when(teleConsultationServiceImpl.checkBeneficiaryStatusForSpecialistTransaction(REQUEST)).thenReturn(1);
+
+ assertTrue(controller.checkBeneficiaryStatusToProceedWithSpecialist(REQUEST)
+ .contains("Specialist can proceed with beneficiary TM session."));
+ }
+
+ @Test
+ @DisplayName("checkBeneficiaryStatusToProceedWithSpecialist should report a lookup failure")
+ void checkStatus_shouldReportLookupFailure() throws Exception {
+ when(teleConsultationServiceImpl.checkBeneficiaryStatusForSpecialistTransaction(REQUEST)).thenReturn(0);
+
+ assertTrue(controller.checkBeneficiaryStatusToProceedWithSpecialist(REQUEST)
+ .contains("Issue while fetching beneficiary status."));
+ }
+
+ @Test
+ @DisplayName("checkBeneficiaryStatusToProceedWithSpecialist should reject a null request")
+ void checkStatus_shouldRejectNullRequest() {
+ assertTrue(controller.checkBeneficiaryStatusToProceedWithSpecialist(null).contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("checkBeneficiaryStatusToProceedWithSpecialist should surface a service failure")
+ void checkStatus_shouldSurfaceServiceFailure() throws Exception {
+ when(teleConsultationServiceImpl.checkBeneficiaryStatusForSpecialistTransaction(REQUEST))
+ .thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.checkBeneficiaryStatusToProceedWithSpecialist(REQUEST)
+ .contains("Issue while fetching beneficiary status"));
+ }
+ }
+
+ @Nested
+ @DisplayName("createTCRequestForBeneficiary")
+ class CreateRequestTests {
+
+ @Test
+ @DisplayName("createTCRequestForBeneficiary should confirm the created request")
+ void createTCRequest_shouldConfirmCreatedRequest() throws Exception {
+ when(teleConsultationServiceImpl.createTCRequestFromWorkList(any(JsonObject.class), eq(AUTHORIZATION)))
+ .thenReturn(1);
+
+ assertTrue(controller.createTCRequestForBeneficiary(REQUEST, AUTHORIZATION)
+ .contains("Teleconsultation request created successfully."));
+ }
+
+ @Test
+ @DisplayName("createTCRequestForBeneficiary should report a failed creation")
+ void createTCRequest_shouldReportFailedCreation() throws Exception {
+ when(teleConsultationServiceImpl.createTCRequestFromWorkList(any(JsonObject.class), eq(AUTHORIZATION)))
+ .thenReturn(0);
+
+ assertTrue(controller.createTCRequestForBeneficiary(REQUEST, AUTHORIZATION)
+ .contains("Issue while creating Teleconsultation request."));
+ }
+
+ @Test
+ @DisplayName("createTCRequestForBeneficiary should reject a null request")
+ void createTCRequest_shouldRejectNullRequest() {
+ assertTrue(controller.createTCRequestForBeneficiary(null, AUTHORIZATION).contains("Invalid request"));
+ }
+
+ @Test
+ @DisplayName("createTCRequestForBeneficiary should surface a service failure")
+ void createTCRequest_shouldSurfaceServiceFailure() throws Exception {
+ when(teleConsultationServiceImpl.createTCRequestFromWorkList(any(JsonObject.class), eq(AUTHORIZATION)))
+ .thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.createTCRequestForBeneficiary(REQUEST, AUTHORIZATION)
+ .contains("Issue while creating Teleconsultation request"));
+ }
+ }
+
+ @Nested
+ @DisplayName("getTCSpecialistWorkListNew")
+ class WorkListTests {
+
+ private static final String LIST_REQUEST = "{\"psmID\":9,\"date\":\"2024-01-15\"}";
+
+ @Test
+ @DisplayName("getTCSpecialistWorkListNew should return the request list for the specialist")
+ void getTCSpecialistWorkListNew_shouldReturnRequestList() throws Exception {
+ when(authentication.isAuthenticated()).thenReturn(true);
+ when(authentication.getPrincipal()).thenReturn("42");
+ when(teleConsultationServiceImpl.getTCRequestListBySpecialistIdAndDate(9, 42, "2024-01-15"))
+ .thenReturn("[{\"benRegID\":11}]");
+
+ assertTrue(controller.getTCSpecialistWorkListNew(LIST_REQUEST, authentication)
+ .contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("getTCSpecialistWorkListNew should reject a missing authentication")
+ void getTCSpecialistWorkListNew_shouldRejectMissingAuthentication() throws Exception {
+ String result = controller.getTCSpecialistWorkListNew(LIST_REQUEST, null);
+
+ assertTrue(result.contains("Unauthorized access"));
+ verify(teleConsultationServiceImpl, never()).getTCRequestListBySpecialistIdAndDate(anyInt(), anyInt(),
+ anyString());
+ }
+
+ @Test
+ @DisplayName("getTCSpecialistWorkListNew should reject an unauthenticated principal")
+ void getTCSpecialistWorkListNew_shouldRejectUnauthenticatedPrincipal() {
+ when(authentication.isAuthenticated()).thenReturn(false);
+
+ assertTrue(controller.getTCSpecialistWorkListNew(LIST_REQUEST, authentication)
+ .contains("Unauthorized access"));
+ }
+
+ @Test
+ @DisplayName("getTCSpecialistWorkListNew should reject a null request body")
+ void getTCSpecialistWorkListNew_shouldRejectNullRequestBody() {
+ when(authentication.isAuthenticated()).thenReturn(true);
+ when(authentication.getPrincipal()).thenReturn("42");
+
+ assertTrue(controller.getTCSpecialistWorkListNew(null, authentication)
+ .contains("Invalid request, either ProviderServiceMapID or RequestDate is invalid"));
+ }
+
+ @Test
+ @DisplayName("getTCSpecialistWorkListNew should surface a service failure")
+ void getTCSpecialistWorkListNew_shouldSurfaceServiceFailure() throws Exception {
+ when(authentication.isAuthenticated()).thenReturn(true);
+ when(authentication.getPrincipal()).thenReturn("42");
+ when(teleConsultationServiceImpl.getTCRequestListBySpecialistIdAndDate(9, 42, "2024-01-15"))
+ .thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.getTCSpecialistWorkListNew(LIST_REQUEST, authentication)
+ .contains("Error while getting TC requestList"));
+ }
+ }
+
+ @Nested
+ @DisplayName("startconsultation")
+ class StartConsultationTests {
+
+ @Test
+ @DisplayName("startconsultation should return the number of updated rows")
+ void startconsultation_shouldReturnUpdatedRowCount() {
+ when(teleConsultationServiceImpl.startconsultation(11L, 22L)).thenReturn(1);
+
+ assertTrue(controller.startconsultation(REQUEST).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("startconsultation should leave the generic failure when nothing comes back")
+ void startconsultation_shouldLeaveGenericFailureWhenNothingReturned() {
+ when(teleConsultationServiceImpl.startconsultation(11L, 22L)).thenReturn(null);
+
+ assertTrue(controller.startconsultation(REQUEST).contains("Failed with generic error"));
+ }
+
+ @Test
+ @DisplayName("startconsultation should reject a null request")
+ void startconsultation_shouldRejectNullRequest() {
+ assertTrue(controller.startconsultation(null)
+ .contains("Invalid request, either ProviderServiceMapID or UserID or RequestDate is invalid"));
+ }
+
+ @Test
+ @DisplayName("startconsultation should surface a service failure")
+ void startconsultation_shouldSurfaceServiceFailure() {
+ when(teleConsultationServiceImpl.startconsultation(11L, 22L))
+ .thenThrow(new IllegalStateException("db down"));
+
+ assertTrue(controller.startconsultation(REQUEST).contains("Error while getting TC requestList"));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/controller/version/VersionControllerTest.java b/src/test/java/com/iemr/tm/controller/version/VersionControllerTest.java
new file mode 100644
index 00000000..96c15db2
--- /dev/null
+++ b/src/test/java/com/iemr/tm/controller/version/VersionControllerTest.java
@@ -0,0 +1,78 @@
+/*
+* AMRIT - Accessible Medical Records via Integrated Technologies
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.controller.version;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@ExtendWith(MockitoExtension.class)
+@DisplayName("VersionController Test Suite")
+class VersionControllerTest {
+
+ private MockMvc mockMvc;
+ private ObjectMapper objectMapper;
+
+ @BeforeEach
+ void setUp() {
+ VersionController versionController = new VersionController();
+
+ mockMvc = MockMvcBuilders.standaloneSetup(versionController).build();
+
+ objectMapper = new ObjectMapper();
+ }
+
+ @Test
+ @DisplayName("Should return version details sourced from git.properties on the classpath")
+ void versionInformation_shouldReturnGitPropertiesContent() throws Exception {
+ Properties gitProperties = new Properties();
+ try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream("git.properties")) {
+ if (inputStream == null) {
+ throw new IOException("git.properties file not found in test resources.");
+ }
+ gitProperties.load(inputStream);
+ }
+
+ mockMvc.perform(get("/version"))
+ .andDo(MockMvcResultHandlers.print())
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$.buildTimestamp").value(gitProperties.getProperty("git.build.time", "unknown")))
+ .andExpect(jsonPath("$.version").value(gitProperties.getProperty("git.build.version", "unknown")))
+ .andExpect(jsonPath("$.branch").value(gitProperties.getProperty("git.branch", "unknown")))
+ .andExpect(jsonPath("$.commitHash").value(gitProperties.getProperty("git.commit.id.abbrev", "unknown")));
+ }
+}
diff --git a/src/test/java/com/iemr/tm/controller/videoconsultationcontroller/VideoConsultationControllerTest.java b/src/test/java/com/iemr/tm/controller/videoconsultationcontroller/VideoConsultationControllerTest.java
new file mode 100644
index 00000000..b50c93fd
--- /dev/null
+++ b/src/test/java/com/iemr/tm/controller/videoconsultationcontroller/VideoConsultationControllerTest.java
@@ -0,0 +1,218 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.controller.videoconsultationcontroller;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.security.core.Authentication;
+
+import com.iemr.tm.service.videoconsultation.VideoConsultationService;
+
+@ExtendWith(MockitoExtension.class)
+@DisplayName("VideoConsultationController Test Suite")
+class VideoConsultationControllerTest {
+
+ @Mock
+ private VideoConsultationService videoConsultationService;
+
+ @Mock
+ private Authentication authentication;
+
+ @InjectMocks
+ private VideoConsultationController controller;
+
+ @Nested
+ @DisplayName("login")
+ class LoginTests {
+
+ @Test
+ @DisplayName("login should return the session data when the principal matches the requested user")
+ void login_shouldReturnSessionDataForMatchingPrincipal() throws Exception {
+ when(authentication.isAuthenticated()).thenReturn(true);
+ when(authentication.getPrincipal()).thenReturn("42");
+ when(videoConsultationService.login(42L)).thenReturn("{\"sessionId\":\"abc\"}");
+
+ assertTrue(controller.login(42L, authentication).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("login should reject a missing authentication")
+ void login_shouldRejectMissingAuthentication() throws Exception {
+ String result = controller.login(42L, null);
+
+ assertTrue(result.contains("Unauthorized access"));
+ verify(videoConsultationService, never()).login(anyLong());
+ }
+
+ @Test
+ @DisplayName("login should reject an unauthenticated principal")
+ void login_shouldRejectUnauthenticatedPrincipal() {
+ when(authentication.isAuthenticated()).thenReturn(false);
+
+ assertTrue(controller.login(42L, authentication).contains("Unauthorized access"));
+ }
+
+ @Test
+ @DisplayName("login should reject a principal that does not match the requested user")
+ void login_shouldRejectMismatchedPrincipal() throws Exception {
+ when(authentication.isAuthenticated()).thenReturn(true);
+ when(authentication.getPrincipal()).thenReturn("99");
+
+ String result = controller.login(42L, authentication);
+
+ assertTrue(result.contains("Unauthorized access!"));
+ verify(videoConsultationService, never()).login(anyLong());
+ }
+
+ @Test
+ @DisplayName("login should surface a service failure")
+ void login_shouldSurfaceServiceFailure() throws Exception {
+ when(authentication.isAuthenticated()).thenReturn(true);
+ when(authentication.getPrincipal()).thenReturn("42");
+ when(videoConsultationService.login(42L)).thenThrow(new IllegalStateException("swymed down"));
+
+ assertTrue(controller.login(42L, authentication).contains("swymed down"));
+ }
+ }
+
+ @Nested
+ @DisplayName("call")
+ class CallTests {
+
+ @Test
+ @DisplayName("call should return the call details produced by the service")
+ void call_shouldReturnCallDetails() throws Exception {
+ when(videoConsultationService.callUser(42L, 43L)).thenReturn("{\"callId\":\"c1\"}");
+
+ assertTrue(controller.call(42L, 43L).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("call should surface a service failure")
+ void call_shouldSurfaceServiceFailure() throws Exception {
+ when(videoConsultationService.callUser(42L, 43L)).thenThrow(new IllegalStateException("swymed down"));
+
+ assertTrue(controller.call(42L, 43L).contains("swymed down"));
+ }
+
+ @Test
+ @DisplayName("callSwymedAndJitsi should place a video consultation call for the VideoConsultation type")
+ void callSwymedAndJitsi_shouldPlaceVideoConsultationCall() throws Exception {
+ when(videoConsultationService.callUser(42L, 43L)).thenReturn("{\"callId\":\"c1\"}");
+
+ assertTrue(controller.callSwymedAndJitsi(42L, 43L, "VideoConsultation").contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("callSwymedAndJitsi should fall back to a Jitsi call for any other type")
+ void callSwymedAndJitsi_shouldFallBackToJitsi() throws Exception {
+ when(videoConsultationService.callUserjitsi(42L, 43L)).thenReturn("{\"callId\":\"j1\"}");
+
+ assertTrue(controller.callSwymedAndJitsi(42L, 43L, "Jitsi").contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("callSwymedAndJitsi should surface a service failure")
+ void callSwymedAndJitsi_shouldSurfaceServiceFailure() throws Exception {
+ when(videoConsultationService.callUserjitsi(42L, 43L)).thenThrow(new IllegalStateException("jitsi down"));
+
+ assertTrue(controller.callSwymedAndJitsi(42L, 43L, "Jitsi").contains("jitsi down"));
+ }
+ }
+
+ @Nested
+ @DisplayName("callvan")
+ class CallVanTests {
+
+ @Test
+ @DisplayName("callvan should return the van call details")
+ void callvan_shouldReturnVanCallDetails() throws Exception {
+ when(videoConsultationService.callVan(42L, 7)).thenReturn("{\"callId\":\"v1\"}");
+
+ assertTrue(controller.callvan(42L, 7).contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("callvan should surface a service failure")
+ void callvan_shouldSurfaceServiceFailure() throws Exception {
+ when(videoConsultationService.callVan(42L, 7)).thenThrow(new IllegalStateException("swymed down"));
+
+ assertTrue(controller.callvan(42L, 7).contains("swymed down"));
+ }
+
+ @Test
+ @DisplayName("callVanSwymedAndJitsi should place a Swymed van call for the Swymed type")
+ void callVanSwymedAndJitsi_shouldPlaceSwymedVanCall() throws Exception {
+ when(videoConsultationService.callVan(42L, 7)).thenReturn("{\"callId\":\"v1\"}");
+
+ assertTrue(controller.callVanSwymedAndJitsi(42L, 7, "Swymed").contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("callVanSwymedAndJitsi should fall back to a Jitsi van call for any other type")
+ void callVanSwymedAndJitsi_shouldFallBackToJitsi() throws Exception {
+ when(videoConsultationService.callVanJitsi(42L, 7)).thenReturn("{\"callId\":\"j1\"}");
+
+ assertTrue(controller.callVanSwymedAndJitsi(42L, 7, "Jitsi").contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("callVanSwymedAndJitsi should surface a service failure")
+ void callVanSwymedAndJitsi_shouldSurfaceServiceFailure() throws Exception {
+ when(videoConsultationService.callVanJitsi(42L, 7)).thenThrow(new IllegalStateException("jitsi down"));
+
+ assertTrue(controller.callVanSwymedAndJitsi(42L, 7, "Jitsi").contains("jitsi down"));
+ }
+ }
+
+ @Nested
+ @DisplayName("logout")
+ class LogoutTests {
+
+ @Test
+ @DisplayName("logout should return the logout confirmation from the service")
+ void logout_shouldReturnLogoutConfirmation() throws Exception {
+ when(videoConsultationService.logout()).thenReturn("logged out");
+
+ assertTrue(controller.logout().contains("\"statusCode\":200"));
+ }
+
+ @Test
+ @DisplayName("logout should surface a service failure")
+ void logout_shouldSurfaceServiceFailure() throws Exception {
+ when(videoConsultationService.logout()).thenThrow(new IllegalStateException("swymed down"));
+
+ assertTrue(controller.logout().contains("swymed down"));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/anc/DataAncDataTest.java b/src/test/java/com/iemr/tm/data/anc/DataAncDataTest.java
new file mode 100644
index 00000000..f2b11810
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/anc/DataAncDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.anc;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.anc}.
+ */
+@DisplayName("com.iemr.tm.data.anc data classes")
+class DataAncDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.anc");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/benFlowStatus/DataBenFlowStatusDataTest.java b/src/test/java/com/iemr/tm/data/benFlowStatus/DataBenFlowStatusDataTest.java
new file mode 100644
index 00000000..6afe355a
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/benFlowStatus/DataBenFlowStatusDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.benFlowStatus;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.benFlowStatus}.
+ */
+@DisplayName("com.iemr.tm.data.benFlowStatus data classes")
+class DataBenFlowStatusDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.benFlowStatus");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/bmi/DataBmiDataTest.java b/src/test/java/com/iemr/tm/data/bmi/DataBmiDataTest.java
new file mode 100644
index 00000000..0678af86
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/bmi/DataBmiDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.bmi;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.bmi}.
+ */
+@DisplayName("com.iemr.tm.data.bmi data classes")
+class DataBmiDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.bmi");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/covid19/DataCovid19DataTest.java b/src/test/java/com/iemr/tm/data/covid19/DataCovid19DataTest.java
new file mode 100644
index 00000000..1be56758
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/covid19/DataCovid19DataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.covid19;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.covid19}.
+ */
+@DisplayName("com.iemr.tm.data.covid19 data classes")
+class DataCovid19DataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.covid19");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/doctor/DataDoctorDataTest.java b/src/test/java/com/iemr/tm/data/doctor/DataDoctorDataTest.java
new file mode 100644
index 00000000..cbd22198
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/doctor/DataDoctorDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.doctor;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.doctor}.
+ */
+@DisplayName("com.iemr.tm.data.doctor data classes")
+class DataDoctorDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.doctor");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/factory/RowFactoryTest.java b/src/test/java/com/iemr/tm/data/factory/RowFactoryTest.java
new file mode 100644
index 00000000..d9b74d01
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/factory/RowFactoryTest.java
@@ -0,0 +1,721 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.factory;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+
+/**
+ * The data classes expose static factories that turn a native query's
+ * {@code Object[]} rows into the payloads the API answers with. These tests
+ * feed them rows shaped the way the queries return them.
+ */
+@DisplayName("Row factory Test Suite")
+class RowFactoryTest {
+
+ /**
+ * Builds one query row from a compact type spec: {@code L} long, {@code I}
+ * integer, {@code S} short, {@code T} comma separated text, {@code D}
+ * timestamp, {@code B} boolean, {@code C} character, {@code A} sql date and
+ * {@code _} null.
+ */
+ private static Object[] row(String spec) {
+ Object[] values = new Object[spec.length()];
+ for (int i = 0; i < spec.length(); i++) {
+ switch (spec.charAt(i)) {
+ case 'L':
+ values[i] = Long.valueOf(i + 1);
+ break;
+ case 'I':
+ values[i] = Integer.valueOf(i + 1);
+ break;
+ case 'S':
+ values[i] = Short.valueOf((short) (i + 1));
+ break;
+ case 'T':
+ values[i] = "1,2";
+ break;
+ case 'D':
+ values[i] = new Timestamp(System.currentTimeMillis());
+ break;
+ case 'B':
+ values[i] = Boolean.TRUE;
+ break;
+ case 'C':
+ values[i] = Character.valueOf('Y');
+ break;
+ case 'A':
+ values[i] = java.sql.Date.valueOf(java.time.LocalDate.now().minusYears(31));
+ break;
+ default:
+ values[i] = null;
+ }
+ }
+ return values;
+ }
+
+ private static ArrayList rows(Object[]... values) {
+ return new ArrayList<>(Arrays.asList(values));
+ }
+
+ @Nested
+ @DisplayName("registrar worklist rows")
+ class RegistrarWorklistTests {
+
+ /** benRegID, benID, name, dob, genderID, gender, visitID, visitNo, flag, category, … */
+ private Object[] worklistRow(String flowStatus, java.sql.Date dob) {
+ Object[] values = row("LTTASTLSTTTTTTT");
+ values[3] = dob;
+ values[8] = flowStatus;
+ return values;
+ }
+
+ @Test
+ @DisplayName("getDocWorkListData should read a beneficiary pending consultation")
+ void docWorkList_shouldReadPendingBeneficiary() {
+ String result = com.iemr.tm.data.registrar.WrapperRegWorklist.getDocWorkListData(
+ Collections.singletonList(worklistRow("N",
+ java.sql.Date.valueOf(java.time.LocalDate.now().minusYears(31)))));
+
+ assertTrue(result.contains("Pending For Consultation"));
+ assertTrue(result.contains("years"));
+ }
+
+ @Test
+ @DisplayName("getDocWorkListData should read a beneficiary whose consultation is done")
+ void docWorkList_shouldReadConsultationDone() {
+ assertTrue(com.iemr.tm.data.registrar.WrapperRegWorklist.getDocWorkListData(
+ Collections.singletonList(worklistRow("D",
+ java.sql.Date.valueOf(java.time.LocalDate.now().minusMonths(5)))))
+ .contains("Consultation Done"));
+ }
+
+ @Test
+ @DisplayName("getDocWorkListData should read a visit the nurse closed")
+ void docWorkList_shouldReadVisitClosedByNurse() {
+ assertTrue(com.iemr.tm.data.registrar.WrapperRegWorklist.getDocWorkListData(
+ Collections.singletonList(worklistRow("C",
+ java.sql.Date.valueOf(java.time.LocalDate.now().minusDays(11)))))
+ .contains("Visit closed by Nurse"));
+ }
+
+ @Test
+ @DisplayName("getDocWorkListData should read a beneficiary with no date of birth")
+ void docWorkList_shouldReadBeneficiaryWithoutDob() {
+ assertNotNull(com.iemr.tm.data.registrar.WrapperRegWorklist
+ .getDocWorkListData(Collections.singletonList(worklistRow("N", null))));
+ }
+
+ @Test
+ @DisplayName("getDocWorkListData should render an empty list for no rows")
+ void docWorkList_shouldRenderEmptyListForNoRows() {
+ assertEquals("[]", com.iemr.tm.data.registrar.WrapperRegWorklist
+ .getDocWorkListData(new ArrayList()));
+ }
+
+ @Test
+ @DisplayName("getRegistrarWorkList should read the registered beneficiary")
+ void registrarWorkList_shouldReadRegisteredBeneficiary() {
+ String result = com.iemr.tm.data.registrar.WrapperRegWorklist
+ .getRegistrarWorkList(Collections.singletonList(row("LTTASTTTTTTT")));
+
+ assertTrue(result.contains("years"));
+ assertTrue(result.contains("genderName"));
+ }
+
+ @Test
+ @DisplayName("getRegistrarWorkList should read a beneficiary aged in months")
+ void registrarWorkList_shouldReadBeneficiaryAgedInMonths() {
+ Object[] values = row("LTTASTTTTTTT");
+ values[3] = java.sql.Date.valueOf(java.time.LocalDate.now().minusMonths(5));
+
+ assertTrue(com.iemr.tm.data.registrar.WrapperRegWorklist
+ .getRegistrarWorkList(Collections.singletonList(values)).contains("months"));
+ }
+
+ @Test
+ @DisplayName("getRegistrarWorkList should read a beneficiary aged in days")
+ void registrarWorkList_shouldReadBeneficiaryAgedInDays() {
+ Object[] values = row("LTTASTTTTTTT");
+ values[3] = java.sql.Date.valueOf(java.time.LocalDate.now().minusDays(11));
+
+ assertTrue(com.iemr.tm.data.registrar.WrapperRegWorklist
+ .getRegistrarWorkList(Collections.singletonList(values)).contains("days"));
+ }
+
+ @Test
+ @DisplayName("getRegistrarWorkList should render an empty list for no rows")
+ void registrarWorkList_shouldRenderEmptyListForNoRows() {
+ assertEquals("[]", com.iemr.tm.data.registrar.WrapperRegWorklist
+ .getRegistrarWorkList(new ArrayList()));
+ }
+ }
+
+ @Nested
+ @DisplayName("prescription and investigation rows")
+ class PrescriptionRowTests {
+
+ @Test
+ @DisplayName("getprescribedDrugs should read the prescribed drug rows")
+ void getPrescribedDrugs_shouldReadRows() {
+ ArrayList drugs =
+ com.iemr.tm.data.quickConsultation.PrescribedDrugDetail
+ .getprescribedDrugs(rows(row("LLTTITTTTTTTTTIBTTD")));
+
+ assertEquals(1, drugs.size());
+ assertNotNull(drugs.get(0));
+ }
+
+ @Test
+ @DisplayName("getprescribedDrugs should read an empty result set")
+ void getPrescribedDrugs_shouldReadEmptyResultSet() {
+ assertTrue(com.iemr.tm.data.quickConsultation.PrescribedDrugDetail
+ .getprescribedDrugs(new ArrayList()).isEmpty());
+ }
+
+ @Test
+ @DisplayName("getBenChiefComplaints should read the recorded complaint rows")
+ void getChiefComplaints_shouldReadRows() {
+ ArrayList complaints =
+ com.iemr.tm.data.quickConsultation.BenChiefComplaint
+ .getBenChiefComplaints(rows(row("LLLIITITTLT")));
+
+ assertEquals(1, complaints.size());
+ assertNotNull(complaints.get(0).getChiefComplaint());
+ }
+
+ @Test
+ @DisplayName("getBenChiefComplaintList should read the complaints out of a case sheet")
+ void getChiefComplaintList_shouldReadFromCaseSheet() {
+ com.google.gson.JsonObject caseSheet = com.google.gson.JsonParser.parseString(
+ "{\"beneficiaryRegID\":11,\"benVisitID\":3,\"visitCode\":22,\"providerServiceMapID\":9,"
+ + "\"vanID\":7,\"parkingPlaceID\":2,\"createdBy\":\"doctor1\","
+ + "\"chiefComplaintList\":[{\"chiefComplaintID\":4,\"chiefComplaint\":\"fever\","
+ + "\"duration\":2,\"unitOfDuration\":\"days\",\"description\":\"since monday\"},"
+ + "{\"chiefComplaint\":\"cough\"}]}").getAsJsonObject();
+
+ ArrayList complaints =
+ com.iemr.tm.data.quickConsultation.BenChiefComplaint.getBenChiefComplaintList(caseSheet);
+
+ assertEquals(2, complaints.size());
+ assertEquals("fever", complaints.get(0).getChiefComplaint());
+ assertEquals(22L, complaints.get(0).getVisitCode());
+ }
+
+ @Test
+ @DisplayName("getBenChiefComplaintList should read a case sheet with no complaint")
+ void getChiefComplaintList_shouldReadCaseSheetWithoutComplaint() {
+ assertTrue(com.iemr.tm.data.quickConsultation.BenChiefComplaint.getBenChiefComplaintList(
+ com.google.gson.JsonParser.parseString("{\"beneficiaryRegID\":11}").getAsJsonObject())
+ .isEmpty());
+ }
+
+ @Test
+ @DisplayName("getLabTestOrderDetails should group the ordered laboratory tests")
+ void getLabTestOrderDetails_shouldGroupOrderedTests() {
+ com.iemr.tm.data.anc.WrapperBenInvestigationANC orders =
+ com.iemr.tm.data.quickConsultation.LabTestOrderDetail
+ .getLabTestOrderDetails(rows(row("LLIIT_L"), row("LLIIT_L")));
+
+ assertEquals(2, orders.getLaboratoryList().size());
+ assertNotNull(orders.getBeneficiaryRegID());
+ }
+
+ @Test
+ @DisplayName("getLabTestOrderDetails should read an empty result set")
+ void getLabTestOrderDetails_shouldReadEmptyResultSet() {
+ assertNotNull(com.iemr.tm.data.quickConsultation.LabTestOrderDetail
+ .getLabTestOrderDetails(new ArrayList()));
+ }
+
+ @Test
+ @DisplayName("getRBSTestOrderDetailsFromVitals should add the RBS test taken with the vitals")
+ void getRbsTestOrderFromVitals_shouldAddRbsTest() {
+ com.iemr.tm.data.nurse.BenPhysicalVitalDetail vitals =
+ new com.iemr.tm.data.nurse.BenPhysicalVitalDetail();
+ vitals.setBeneficiaryRegID(11L);
+ vitals.setVisitCode(22L);
+ vitals.setRbsTestResult("110");
+
+ com.iemr.tm.data.anc.WrapperBenInvestigationANC orders =
+ com.iemr.tm.data.quickConsultation.LabTestOrderDetail
+ .getRBSTestOrderDetailsFromVitals(vitals);
+
+ assertEquals(1, orders.getLaboratoryList().size());
+ assertEquals("RBS Test", orders.getLaboratoryList().get(0).getProcedureName());
+ }
+
+ @Test
+ @DisplayName("getRBSTestOrderDetailsFromVitals should skip the RBS test when it was not taken")
+ void getRbsTestOrderFromVitals_shouldSkipUntakenRbsTest() {
+ assertTrue(com.iemr.tm.data.quickConsultation.LabTestOrderDetail
+ .getRBSTestOrderDetailsFromVitals(new com.iemr.tm.data.nurse.BenPhysicalVitalDetail())
+ .getLaboratoryList().isEmpty());
+ }
+
+ @Test
+ @DisplayName("getLabTestOrderDetailList should read the ordered tests out of a case sheet")
+ void getLabTestOrderDetailList_shouldReadFromCaseSheet() {
+ com.google.gson.JsonObject caseSheet = com.google.gson.JsonParser.parseString(
+ "{\"beneficiaryRegID\":11,\"benVisitID\":3,\"visitCode\":22,\"providerServiceMapID\":9,"
+ + "\"vanID\":7,\"parkingPlaceID\":2,\"createdBy\":\"doctor1\","
+ + "\"labTestOrders\":[{\"procedureID\":4,\"procedureName\":\"CBC\","
+ + "\"testingRequirements\":\"fasting\"},{\"procedureName\":\"ECG\"}]}")
+ .getAsJsonObject();
+
+ ArrayList orders =
+ com.iemr.tm.data.quickConsultation.LabTestOrderDetail
+ .getLabTestOrderDetailList(caseSheet, 31L);
+
+ assertEquals(2, orders.size());
+ assertEquals("CBC", orders.get(0).getProcedureName());
+ assertEquals(31L, orders.get(0).getPrescriptionID());
+ }
+
+ @Test
+ @DisplayName("getLabTestOrderDetailList should read a case sheet with no ordered test")
+ void getLabTestOrderDetailList_shouldReadCaseSheetWithoutOrder() {
+ assertTrue(com.iemr.tm.data.quickConsultation.LabTestOrderDetail.getLabTestOrderDetailList(
+ com.google.gson.JsonParser.parseString("{\"beneficiaryRegID\":11}").getAsJsonObject(), 31L)
+ .isEmpty());
+ }
+ }
+
+ @Nested
+ @DisplayName("lab result rows")
+ class LabResultRowTests {
+
+ @Test
+ @DisplayName("getVisitCodeAndDate should read the tested visits")
+ void getVisitCodeAndDate_shouldReadTestedVisits() {
+ ArrayList resultSet = rows(new Object[] { 22L, "2026-08-26" });
+
+ ArrayList visits =
+ com.iemr.tm.data.labModule.LabResultEntry.getVisitCodeAndDate(resultSet);
+
+ assertEquals(1, visits.size());
+ assertEquals(22L, visits.get(0).getVisitCode());
+ }
+
+ @Test
+ @DisplayName("getVisitCodeAndDate should read an empty result set")
+ void getVisitCodeAndDate_shouldReadEmptyResultSet() {
+ assertTrue(com.iemr.tm.data.labModule.LabResultEntry
+ .getVisitCodeAndDate(new ArrayList()).isEmpty());
+ }
+
+ private com.iemr.tm.data.labModule.LabResultEntry stored(Integer procedureID, String reportPath) {
+ com.iemr.tm.data.labModule.LabResultEntry entry = new com.iemr.tm.data.labModule.LabResultEntry();
+ entry.setPrescriptionID(31L);
+ entry.setProcedureID(procedureID);
+ entry.setTestComponentID(2);
+ entry.setTestResultValue("12");
+ entry.setTestResultUnit("g/dL");
+ entry.setTestReportFilePath(reportPath);
+ entry.setCreatedDate(new Timestamp(System.currentTimeMillis()));
+ com.iemr.tm.data.labModule.ProcedureData procedure = new com.iemr.tm.data.labModule.ProcedureData();
+ procedure.setProcedureName("CBC");
+ procedure.setProcedureType("Laboratory");
+ entry.setProcedureData(procedure);
+ com.iemr.tm.data.labModule.TestComponentMaster component =
+ new com.iemr.tm.data.labModule.TestComponentMaster();
+ component.setTestComponentName("Haemoglobin");
+ entry.setTestComponentMaster(component);
+ return entry;
+ }
+
+ @Test
+ @DisplayName("getLabResultEntry should group the components of one procedure and read its report files")
+ void getLabResultEntry_shouldGroupComponentsAndReadReportFiles() {
+ ArrayList comingList = new ArrayList<>();
+ comingList.add(stored(1, "81,82,"));
+ comingList.add(stored(1, null));
+ comingList.add(stored(5, ""));
+
+ ArrayList grouped =
+ com.iemr.tm.data.labModule.LabResultEntry.getLabResultEntry(comingList);
+
+ assertEquals(2, grouped.size());
+ assertEquals(2, grouped.get(0).getComponentList().size());
+ assertEquals("CBC", grouped.get(0).getProcedureName());
+ }
+
+ @Test
+ @DisplayName("getLabResultEntry should read an empty result list")
+ void getLabResultEntry_shouldReadEmptyList() {
+ assertTrue(com.iemr.tm.data.labModule.LabResultEntry
+ .getLabResultEntry(new ArrayList<>()).isEmpty());
+ }
+ }
+
+ @Nested
+ @DisplayName("obstetric and personal history rows")
+ class HistoryRowTests {
+
+ @Test
+ @DisplayName("getFemaleObstetricHistory should read every recorded pregnancy")
+ void getFemaleObstetricHistory_shouldReadRecordedPregnancies() {
+ com.iemr.tm.data.anc.WrapperFemaleObstetricHistory history =
+ com.iemr.tm.data.anc.WrapperFemaleObstetricHistory.getFemaleObstetricHistory(
+ rows(row("LLISSTTTSTSTSTTTTTSTTTTSTTTSTTLITIITTT")));
+
+ assertEquals(1, history.getFemaleObstetricHistoryList().size());
+ assertNotNull(history.getBeneficiaryRegID());
+ }
+
+ @Test
+ @DisplayName("getFemaleObstetricHistory should read a beneficiary with no recorded pregnancy")
+ void getFemaleObstetricHistory_shouldReadNoRecordedPregnancy() {
+ Object[] values = row("LLISSTTTSTSTSTTTTTSTTTTSTTTSTTLITIITTT");
+ values[4] = Short.valueOf((short) 0);
+
+ assertTrue(com.iemr.tm.data.anc.WrapperFemaleObstetricHistory
+ .getFemaleObstetricHistory(rows(values)).getFemaleObstetricHistoryList().isEmpty());
+ }
+
+ @Test
+ @DisplayName("getFemaleObstetricHistory should read an empty result set")
+ void getFemaleObstetricHistory_shouldReadEmptyResultSet() {
+ assertNotNull(com.iemr.tm.data.anc.WrapperFemaleObstetricHistory
+ .getFemaleObstetricHistory(new ArrayList()));
+ }
+
+ @Test
+ @DisplayName("getPersonalDetails should read the recorded tobacco and alcohol habits")
+ void getPersonalDetails_shouldReadTobaccoAndAlcoholHabits() {
+ com.iemr.tm.data.anc.BenPersonalHabit habits = com.iemr.tm.data.anc.BenPersonalHabit
+ .getPersonalDetails(rows(row("LLITTTTTTSD_TTTTTDCDL"), row("LLITTTTTTSD_TTTTTDCDL")));
+
+ assertNotNull(habits);
+ assertFalse(habits.getTobaccoList().isEmpty());
+ assertFalse(habits.getAlcoholList().isEmpty());
+ }
+
+ @Test
+ @DisplayName("getPersonalDetails should read a beneficiary with no recorded habit")
+ void getPersonalDetails_shouldReadNoRecordedHabit() {
+ org.junit.jupiter.api.Assertions.assertNull(
+ com.iemr.tm.data.anc.BenPersonalHabit.getPersonalDetails(new ArrayList()));
+ }
+ }
+
+ @Nested
+ @DisplayName("row builder")
+ class RowBuilderTests {
+
+ @Test
+ @DisplayName("row should build one value of each supported column type")
+ void row_shouldBuildOneValueOfEachType() {
+ Object[] values = row("LISTDBA_");
+
+ assertEquals(Long.valueOf(1L), values[0]);
+ assertEquals(Integer.valueOf(2), values[1]);
+ assertEquals(Short.valueOf((short) 3), values[2]);
+ assertEquals("1,2", values[3]);
+ assertNotNull(values[4]);
+ assertEquals(Boolean.TRUE, values[5]);
+ assertNotNull(values[6]);
+ org.junit.jupiter.api.Assertions.assertNull(values[7]);
+ }
+
+ @Test
+ @DisplayName("rows should collect the built rows in order")
+ void rows_shouldCollectRowsInOrder() {
+ List collected = rows(row("L"), row("I"));
+
+ assertEquals(2, collected.size());
+ assertEquals(Long.valueOf(1L), collected.get(0)[0]);
+ }
+ }
+
+ @Nested
+ @DisplayName("beneficiary search and detail rows")
+ class BeneficiarySearchRowTests {
+
+ @Test
+ @DisplayName("getSearchData should read the matched beneficiaries with their age")
+ void getSearchData_shouldReadMatchedBeneficiaries() {
+ String result = com.iemr.tm.data.registrar.V_BenAdvanceSearch
+ .getSearchData(Collections.singletonList(row("LTTSTATTITITTT")));
+
+ assertTrue(result.contains("years"));
+ assertTrue(result.contains("villageName"));
+ }
+
+ @Test
+ @DisplayName("getSearchData should read a beneficiary aged in months")
+ void getSearchData_shouldReadBeneficiaryAgedInMonths() {
+ Object[] values = row("LTTSTATTITITTT");
+ values[5] = java.sql.Date.valueOf(java.time.LocalDate.now().minusMonths(5));
+
+ assertTrue(com.iemr.tm.data.registrar.V_BenAdvanceSearch
+ .getSearchData(Collections.singletonList(values)).contains("months"));
+ }
+
+ @Test
+ @DisplayName("getSearchData should read a beneficiary aged in days")
+ void getSearchData_shouldReadBeneficiaryAgedInDays() {
+ Object[] values = row("LTTSTATTITITTT");
+ values[5] = java.sql.Date.valueOf(java.time.LocalDate.now().minusDays(11));
+
+ assertTrue(com.iemr.tm.data.registrar.V_BenAdvanceSearch
+ .getSearchData(Collections.singletonList(values)).contains("days"));
+ }
+
+ @Test
+ @DisplayName("getSearchData should read a beneficiary with no date of birth")
+ void getSearchData_shouldReadBeneficiaryWithoutDob() {
+ Object[] values = row("LTTSTATTITITTT");
+ values[5] = null;
+
+ assertNotNull(com.iemr.tm.data.registrar.V_BenAdvanceSearch
+ .getSearchData(Collections.singletonList(values)));
+ }
+
+ @Test
+ @DisplayName("getSearchData should render an empty list for no match")
+ void getSearchData_shouldRenderEmptyListForNoMatch() {
+ assertEquals("[]", com.iemr.tm.data.registrar.V_BenAdvanceSearch
+ .getSearchData(new ArrayList()));
+ }
+
+ /** The registration row the beneficiary details screen is built from. */
+ private Object[] detailRow() {
+ Object[] values = row("LTTTSASTSSSITITISTTITITTSTBATTTTTTT");
+ values[5] = java.sql.Date.valueOf(java.time.LocalDate.now().minusYears(31));
+ values[27] = java.sql.Date.valueOf(java.time.LocalDate.now().minusYears(9));
+ return values;
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryDetails should read the registration row and work out the age at marriage")
+ void getBeneficiaryDetails_shouldReadRowAndAgeAtMarriage() {
+ com.iemr.tm.data.registrar.FetchBeneficiaryDetails details =
+ com.iemr.tm.data.registrar.FetchBeneficiaryDetails.getBeneficiaryDetails(detailRow(),
+ new ArrayList<>(), "Yes", new ArrayList<>());
+
+ assertNotNull(details);
+ assertNotNull(details.getBeneficiaryRegID());
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryDetails should leave the age at marriage out when no marriage date is stored")
+ void getBeneficiaryDetails_shouldLeaveAgeAtMarriageOut() {
+ Object[] values = detailRow();
+ values[27] = null;
+
+ assertNotNull(com.iemr.tm.data.registrar.FetchBeneficiaryDetails.getBeneficiaryDetails(values,
+ new ArrayList<>(), "No", new ArrayList<>()));
+ }
+
+ @Test
+ @DisplayName("getFetchBeneficiaryDetailsObj should answer with nothing")
+ void getFetchBeneficiaryDetailsObj_shouldAnswerWithNothing() {
+ org.junit.jupiter.api.Assertions.assertNull(com.iemr.tm.data.registrar.FetchBeneficiaryDetails
+ .getFetchBeneficiaryDetailsObj(row("L"), new ArrayList<>()));
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryData should read the beneficiary rows")
+ void getBeneficiaryData_shouldReadRows() {
+ ArrayList beneficiaries =
+ com.iemr.tm.data.registrar.BeneficiaryData
+ .getBeneficiaryData(Collections.singletonList(row("LTTASDTT")));
+
+ assertEquals(1, beneficiaries.size());
+ assertNotNull(beneficiaries.get(0));
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryPersonalData should read the beneficiary rows without the extra columns")
+ void getBeneficiaryPersonalData_shouldReadRows() {
+ assertEquals(1, com.iemr.tm.data.registrar.BeneficiaryData
+ .getBeneficiaryPersonalData(Collections.singletonList(row("LTTASD"))).size());
+ }
+ }
+
+ @Nested
+ @DisplayName("history and master rows")
+ class HistoryAndMasterRowTests {
+
+ @Test
+ @DisplayName("getBenFamilyHistory should group the recorded family diseases")
+ void getBenFamilyHistory_shouldGroupRecordedDiseases() {
+ com.iemr.tm.data.anc.BenFamilyHistory history = com.iemr.tm.data.anc.BenFamilyHistory
+ .getBenFamilyHistory(rows(row("LLITSTTBTBLTT"), row("LLITSTTBTBLTT")));
+
+ assertNotNull(history);
+ assertEquals(2, history.getFamilyDiseaseList().size());
+ assertTrue(history.getFamilyDiseaseList().get(0).containsKey("familyMembers"));
+ }
+
+ @Test
+ @DisplayName("getBenFamilyHistory should read no recorded family disease")
+ void getBenFamilyHistory_shouldReadNoRecordedDisease() {
+ org.junit.jupiter.api.Assertions.assertNull(com.iemr.tm.data.anc.BenFamilyHistory
+ .getBenFamilyHistory(new ArrayList()));
+ }
+
+ @Test
+ @DisplayName("getBenFamilyHist should group the recorded family diseases with their row ids")
+ void getBenFamilyHist_shouldGroupRecordedDiseasesWithIds() {
+ com.iemr.tm.data.anc.BenFamilyHistory history = com.iemr.tm.data.anc.BenFamilyHistory
+ .getBenFamilyHist(rows(row("LLLITSTTBTBLTT"), row("LLLITSTTBTBLTT")));
+
+ assertNotNull(history);
+ assertEquals(2, history.getFamilyDiseaseList().size());
+ assertEquals(Boolean.FALSE, history.getFamilyDiseaseList().get(0).get("deleted"));
+ }
+
+ @Test
+ @DisplayName("getBenFamilyHist should read no recorded family disease")
+ void getBenFamilyHist_shouldReadNoRecordedDisease() {
+ org.junit.jupiter.api.Assertions.assertNull(com.iemr.tm.data.anc.BenFamilyHistory
+ .getBenFamilyHist(new ArrayList()));
+ }
+
+ @Test
+ @DisplayName("getBenAllergicHistory should expand the recorded reaction types")
+ void getBenAllergicHistory_shouldExpandReactionTypes() {
+ ArrayList allergies =
+ com.iemr.tm.data.anc.BenAllergyHistory
+ .getBenAllergicHistory(rows(row("LLITTTTTTTLTT")));
+
+ assertEquals(1, allergies.size());
+ assertFalse(allergies.get(0).getTypeOfAllergicReactions().isEmpty());
+ }
+
+ @Test
+ @DisplayName("getBenAllergicHistory should read no recorded allergy")
+ void getBenAllergicHistory_shouldReadNoRecordedAllergy() {
+ assertTrue(com.iemr.tm.data.anc.BenAllergyHistory
+ .getBenAllergicHistory(new ArrayList()).isEmpty());
+ }
+
+ @Test
+ @DisplayName("getBenChildDevelopmentDetails should split the recorded milestones")
+ void getChildDevelopmentDetails_shouldSplitRecordedMilestones() {
+ com.iemr.tm.data.anc.BenChildDevelopmentHistory history =
+ com.iemr.tm.data.anc.BenChildDevelopmentHistory
+ .getBenChildDevelopmentDetails(rows(row("LLITBTBTBTBTL")));
+
+ assertNotNull(history);
+ assertEquals(2, history.getGrossMotorMilestones().size());
+ assertEquals(2, history.getFineMotorMilestones().size());
+ assertEquals(2, history.getSocialMilestones().size());
+ assertEquals(2, history.getLanguageMilestones().size());
+ assertEquals(2, history.getDevelopmentProblems().size());
+ }
+
+ @Test
+ @DisplayName("getBenChildDevelopmentDetails should read no recorded development history")
+ void getChildDevelopmentDetails_shouldReadNoRecordedHistory() {
+ org.junit.jupiter.api.Assertions.assertNull(com.iemr.tm.data.anc.BenChildDevelopmentHistory
+ .getBenChildDevelopmentDetails(new ArrayList()));
+ }
+
+ @Test
+ @DisplayName("getDevelopmentHistory should flatten the picked milestones for storage")
+ void getDevelopmentHistory_shouldFlattenPickedMilestones() {
+ com.iemr.tm.data.anc.BenChildDevelopmentHistory history =
+ new com.iemr.tm.data.anc.BenChildDevelopmentHistory();
+ history.setGrossMotorMilestones(Arrays.asList("Sits", "Stands"));
+ history.setFineMotorMilestones(Arrays.asList("Grasps"));
+ history.setSocialMilestones(Arrays.asList("Smiles"));
+ history.setLanguageMilestones(Arrays.asList("Babbles"));
+ history.setDevelopmentProblems(Arrays.asList("None"));
+
+ com.iemr.tm.data.anc.BenChildDevelopmentHistory flattened =
+ com.iemr.tm.data.anc.BenChildDevelopmentHistory.getDevelopmentHistory(history);
+
+ assertEquals("Sits,Stands,", flattened.getGrossMotorMilestone());
+ assertEquals("Grasps,", flattened.getFineMotorMilestone());
+ assertEquals("Smiles,", flattened.getSocialMilestone());
+ assertEquals("Babbles,", flattened.getLanguageMilestone());
+ }
+
+ @Test
+ @DisplayName("getDevelopmentHistory should flatten an empty pick into empty text")
+ void getDevelopmentHistory_shouldFlattenEmptyPick() {
+ assertEquals("", com.iemr.tm.data.anc.BenChildDevelopmentHistory
+ .getDevelopmentHistory(new com.iemr.tm.data.anc.BenChildDevelopmentHistory())
+ .getGrossMotorMilestone());
+ }
+
+ @org.junit.jupiter.params.ParameterizedTest
+ @org.junit.jupiter.params.provider.CsvSource({ "1", "2", "3", "4" })
+ @DisplayName("getComplicationTypes should read the master rows for each complication master")
+ void getComplicationTypes_shouldReadEachMaster(int masterType) {
+ assertEquals(1, com.iemr.tm.data.masterdata.anc.ComplicationTypes
+ .getComplicationTypes(rows(row("ST")), masterType).size());
+ }
+
+ @Test
+ @DisplayName("getANCWomenVaccineDetails should read all three tetanus doses")
+ void getAncWomenVaccineDetails_shouldReadAllThreeDoses() {
+ com.iemr.tm.data.anc.WrapperAncImmunization immunization =
+ com.iemr.tm.data.anc.ANCWomenVaccineDetail.getANCWomenVaccineDetails(
+ rows(vaccineRow(1L), vaccineRow(2L), vaccineRow(3L)));
+
+ assertNotNull(immunization.getDateReceivedForTT_1());
+ assertNotNull(immunization.getDateReceivedForTT_2());
+ assertNotNull(immunization.getDateReceivedForTT_3());
+ assertNotNull(immunization.getFacilityNameOfTT_1());
+ }
+
+ private Object[] vaccineRow(Long id) {
+ Object[] values = row("LLLI_TATL");
+ values[0] = id;
+ values[6] = java.sql.Date.valueOf(java.time.LocalDate.now());
+ return values;
+ }
+
+ @Test
+ @DisplayName("getANCWomenVaccineDetails should read a dose with no received date")
+ void getAncWomenVaccineDetails_shouldReadDoseWithoutDate() {
+ Object[] values = vaccineRow(1L);
+ values[6] = null;
+
+ assertNotNull(com.iemr.tm.data.anc.ANCWomenVaccineDetail
+ .getANCWomenVaccineDetails(rows(values)));
+ }
+
+ @Test
+ @DisplayName("getANCWomenVaccineDetails should read no recorded dose")
+ void getAncWomenVaccineDetails_shouldReadNoRecordedDose() {
+ assertNotNull(com.iemr.tm.data.anc.ANCWomenVaccineDetail
+ .getANCWomenVaccineDetails(new ArrayList()));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/foetalmonitor/DataFoetalmonitorDataTest.java b/src/test/java/com/iemr/tm/data/foetalmonitor/DataFoetalmonitorDataTest.java
new file mode 100644
index 00000000..922b867b
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/foetalmonitor/DataFoetalmonitorDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.foetalmonitor;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.foetalmonitor}.
+ */
+@DisplayName("com.iemr.tm.data.foetalmonitor data classes")
+class DataFoetalmonitorDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.foetalmonitor");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/institution/DataInstitutionDataTest.java b/src/test/java/com/iemr/tm/data/institution/DataInstitutionDataTest.java
new file mode 100644
index 00000000..edd8c7a9
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/institution/DataInstitutionDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.institution;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.institution}.
+ */
+@DisplayName("com.iemr.tm.data.institution data classes")
+class DataInstitutionDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.institution");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/labModule/DataLabModuleDataTest.java b/src/test/java/com/iemr/tm/data/labModule/DataLabModuleDataTest.java
new file mode 100644
index 00000000..66550e02
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/labModule/DataLabModuleDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.labModule;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.labModule}.
+ */
+@DisplayName("com.iemr.tm.data.labModule data classes")
+class DataLabModuleDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.labModule");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/labtechnician/DataLabtechnicianDataTest.java b/src/test/java/com/iemr/tm/data/labtechnician/DataLabtechnicianDataTest.java
new file mode 100644
index 00000000..bbe87814
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/labtechnician/DataLabtechnicianDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.labtechnician;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.labtechnician}.
+ */
+@DisplayName("com.iemr.tm.data.labtechnician data classes")
+class DataLabtechnicianDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.labtechnician");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/location/DataLocationDataTest.java b/src/test/java/com/iemr/tm/data/location/DataLocationDataTest.java
new file mode 100644
index 00000000..c9d6464f
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/location/DataLocationDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.location;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.location}.
+ */
+@DisplayName("com.iemr.tm.data.location data classes")
+class DataLocationDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.location");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/login/DataLoginDataTest.java b/src/test/java/com/iemr/tm/data/login/DataLoginDataTest.java
new file mode 100644
index 00000000..96d6974c
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/login/DataLoginDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.login;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.login}.
+ */
+@DisplayName("com.iemr.tm.data.login data classes")
+class DataLoginDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.login");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/masterdata/anc/DataMasterdataAncDataTest.java b/src/test/java/com/iemr/tm/data/masterdata/anc/DataMasterdataAncDataTest.java
new file mode 100644
index 00000000..fe7447d6
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/masterdata/anc/DataMasterdataAncDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.masterdata.anc;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.masterdata.anc}.
+ */
+@DisplayName("com.iemr.tm.data.masterdata.anc data classes")
+class DataMasterdataAncDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.masterdata.anc");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/masterdata/doctor/DataMasterdataDoctorDataTest.java b/src/test/java/com/iemr/tm/data/masterdata/doctor/DataMasterdataDoctorDataTest.java
new file mode 100644
index 00000000..09a62c50
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/masterdata/doctor/DataMasterdataDoctorDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.masterdata.doctor;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.masterdata.doctor}.
+ */
+@DisplayName("com.iemr.tm.data.masterdata.doctor data classes")
+class DataMasterdataDoctorDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.masterdata.doctor");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/masterdata/ncdcare/DataMasterdataNcdcareDataTest.java b/src/test/java/com/iemr/tm/data/masterdata/ncdcare/DataMasterdataNcdcareDataTest.java
new file mode 100644
index 00000000..bdaad864
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/masterdata/ncdcare/DataMasterdataNcdcareDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.masterdata.ncdcare;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.masterdata.ncdcare}.
+ */
+@DisplayName("com.iemr.tm.data.masterdata.ncdcare data classes")
+class DataMasterdataNcdcareDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.masterdata.ncdcare");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/masterdata/ncdscreening/DataMasterdataNcdscreeningDataTest.java b/src/test/java/com/iemr/tm/data/masterdata/ncdscreening/DataMasterdataNcdscreeningDataTest.java
new file mode 100644
index 00000000..49c478c1
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/masterdata/ncdscreening/DataMasterdataNcdscreeningDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.masterdata.ncdscreening;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.masterdata.ncdscreening}.
+ */
+@DisplayName("com.iemr.tm.data.masterdata.ncdscreening data classes")
+class DataMasterdataNcdscreeningDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.masterdata.ncdscreening");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/masterdata/nurse/DataMasterdataNurseDataTest.java b/src/test/java/com/iemr/tm/data/masterdata/nurse/DataMasterdataNurseDataTest.java
new file mode 100644
index 00000000..78d713e7
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/masterdata/nurse/DataMasterdataNurseDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.masterdata.nurse;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.masterdata.nurse}.
+ */
+@DisplayName("com.iemr.tm.data.masterdata.nurse data classes")
+class DataMasterdataNurseDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.masterdata.nurse");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/masterdata/pnc/DataMasterdataPncDataTest.java b/src/test/java/com/iemr/tm/data/masterdata/pnc/DataMasterdataPncDataTest.java
new file mode 100644
index 00000000..10c30f17
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/masterdata/pnc/DataMasterdataPncDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.masterdata.pnc;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.masterdata.pnc}.
+ */
+@DisplayName("com.iemr.tm.data.masterdata.pnc data classes")
+class DataMasterdataPncDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.masterdata.pnc");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/masterdata/registrar/DataMasterdataRegistrarDataTest.java b/src/test/java/com/iemr/tm/data/masterdata/registrar/DataMasterdataRegistrarDataTest.java
new file mode 100644
index 00000000..fd5a2177
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/masterdata/registrar/DataMasterdataRegistrarDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.masterdata.registrar;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.masterdata.registrar}.
+ */
+@DisplayName("com.iemr.tm.data.masterdata.registrar data classes")
+class DataMasterdataRegistrarDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.masterdata.registrar");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/ncdScreening/DataNcdScreeningDataTest.java b/src/test/java/com/iemr/tm/data/ncdScreening/DataNcdScreeningDataTest.java
new file mode 100644
index 00000000..2a238bbc
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/ncdScreening/DataNcdScreeningDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.ncdScreening;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.ncdScreening}.
+ */
+@DisplayName("com.iemr.tm.data.ncdScreening data classes")
+class DataNcdScreeningDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.ncdScreening");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/ncdcare/DataNcdcareDataTest.java b/src/test/java/com/iemr/tm/data/ncdcare/DataNcdcareDataTest.java
new file mode 100644
index 00000000..209c8783
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/ncdcare/DataNcdcareDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.ncdcare;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.ncdcare}.
+ */
+@DisplayName("com.iemr.tm.data.ncdcare data classes")
+class DataNcdcareDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.ncdcare");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/nurse/DataNurseDataTest.java b/src/test/java/com/iemr/tm/data/nurse/DataNurseDataTest.java
new file mode 100644
index 00000000..420d8cbf
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/nurse/DataNurseDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.nurse;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.nurse}.
+ */
+@DisplayName("com.iemr.tm.data.nurse data classes")
+class DataNurseDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.nurse");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/patientApp/DataPatientAppDataTest.java b/src/test/java/com/iemr/tm/data/patientApp/DataPatientAppDataTest.java
new file mode 100644
index 00000000..3eeb16c0
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/patientApp/DataPatientAppDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.patientApp;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.patientApp}.
+ */
+@DisplayName("com.iemr.tm.data.patientApp data classes")
+class DataPatientAppDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.patientApp");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/pnc/DataPncDataTest.java b/src/test/java/com/iemr/tm/data/pnc/DataPncDataTest.java
new file mode 100644
index 00000000..777f1625
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/pnc/DataPncDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.pnc;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.pnc}.
+ */
+@DisplayName("com.iemr.tm.data.pnc data classes")
+class DataPncDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.pnc");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/provider/DataProviderDataTest.java b/src/test/java/com/iemr/tm/data/provider/DataProviderDataTest.java
new file mode 100644
index 00000000..71c7ed85
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/provider/DataProviderDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.provider;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.provider}.
+ */
+@DisplayName("com.iemr.tm.data.provider data classes")
+class DataProviderDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.provider");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/quickBlox/DataQuickBloxDataTest.java b/src/test/java/com/iemr/tm/data/quickBlox/DataQuickBloxDataTest.java
new file mode 100644
index 00000000..8e6c6871
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/quickBlox/DataQuickBloxDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.quickBlox;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.quickBlox}.
+ */
+@DisplayName("com.iemr.tm.data.quickBlox data classes")
+class DataQuickBloxDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.quickBlox");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/quickConsultation/DataQuickConsultationDataTest.java b/src/test/java/com/iemr/tm/data/quickConsultation/DataQuickConsultationDataTest.java
new file mode 100644
index 00000000..cfad778e
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/quickConsultation/DataQuickConsultationDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.quickConsultation;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.quickConsultation}.
+ */
+@DisplayName("com.iemr.tm.data.quickConsultation data classes")
+class DataQuickConsultationDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.quickConsultation");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/registrar/DataRegistrarDataTest.java b/src/test/java/com/iemr/tm/data/registrar/DataRegistrarDataTest.java
new file mode 100644
index 00000000..b6318858
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/registrar/DataRegistrarDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.registrar;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.registrar}.
+ */
+@DisplayName("com.iemr.tm.data.registrar data classes")
+class DataRegistrarDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.registrar");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/report/DataReportDataTest.java b/src/test/java/com/iemr/tm/data/report/DataReportDataTest.java
new file mode 100644
index 00000000..7535aaf2
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/report/DataReportDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.report;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.report}.
+ */
+@DisplayName("com.iemr.tm.data.report data classes")
+class DataReportDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.report");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/snomedct/DataSnomedctDataTest.java b/src/test/java/com/iemr/tm/data/snomedct/DataSnomedctDataTest.java
new file mode 100644
index 00000000..c610c2f5
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/snomedct/DataSnomedctDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.snomedct;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.snomedct}.
+ */
+@DisplayName("com.iemr.tm.data.snomedct data classes")
+class DataSnomedctDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.snomedct");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/syncActivity_syncLayer/DataSyncActivitySyncLayerDataTest.java b/src/test/java/com/iemr/tm/data/syncActivity_syncLayer/DataSyncActivitySyncLayerDataTest.java
new file mode 100644
index 00000000..1f874daa
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/syncActivity_syncLayer/DataSyncActivitySyncLayerDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.syncActivity_syncLayer;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.syncActivity_syncLayer}.
+ */
+@DisplayName("com.iemr.tm.data.syncActivity_syncLayer data classes")
+class DataSyncActivitySyncLayerDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.syncActivity_syncLayer");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/tele_consultation/DataTeleConsultationDataTest.java b/src/test/java/com/iemr/tm/data/tele_consultation/DataTeleConsultationDataTest.java
new file mode 100644
index 00000000..451199ed
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/tele_consultation/DataTeleConsultationDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.tele_consultation;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.tele_consultation}.
+ */
+@DisplayName("com.iemr.tm.data.tele_consultation data classes")
+class DataTeleConsultationDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.tele_consultation");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/data/videoconsultation/DataVideoconsultationDataTest.java b/src/test/java/com/iemr/tm/data/videoconsultation/DataVideoconsultationDataTest.java
new file mode 100644
index 00000000..86f988c2
--- /dev/null
+++ b/src/test/java/com/iemr/tm/data/videoconsultation/DataVideoconsultationDataTest.java
@@ -0,0 +1,44 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.data.videoconsultation;
+
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+/**
+ * Accessor, constructor and row-mapper coverage for every data class in
+ * {@code com.iemr.tm.data.videoconsultation}.
+ */
+@DisplayName("com.iemr.tm.data.videoconsultation data classes")
+class DataVideoconsultationDataTest {
+
+ @TestFactory
+ @DisplayName("every data class should round-trip its properties and map query rows")
+ List dataClassesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.data.videoconsultation");
+ }
+}
diff --git a/src/test/java/com/iemr/tm/repo/location/ZoneDistrictMappingTest.java b/src/test/java/com/iemr/tm/repo/location/ZoneDistrictMappingTest.java
new file mode 100644
index 00000000..ec4fe046
--- /dev/null
+++ b/src/test/java/com/iemr/tm/repo/location/ZoneDistrictMappingTest.java
@@ -0,0 +1,98 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/package com.iemr.tm.repo.location;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.sql.Timestamp;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestFactory;
+
+import com.iemr.tm.common.PojoTestSupport;
+
+@DisplayName("Location repository entity Test Suite")
+class ZoneDistrictMappingTest {
+
+ @TestFactory
+ @DisplayName("The location entities should round trip every mapped property")
+ List locationEntitiesShouldRoundTripProperties() {
+ return PojoTestSupport.accessorTestsFor("com.iemr.tm.repo.location");
+ }
+
+ @Test
+ @DisplayName("The mapping should hold the zone to district link it was built with")
+ void mapping_shouldHoldZoneToDistrictLink() {
+ Timestamp createdDate = new Timestamp(System.currentTimeMillis());
+
+ ZoneDistrictMapping mapping = new ZoneDistrictMapping(1, 2, 3, 9, false, "N", "admin", createdDate,
+ "admin", createdDate);
+
+ assertEquals(1, mapping.getZoneDistrictMapID());
+ assertEquals(2, mapping.getZoneID());
+ assertEquals(3, mapping.getDistrictID());
+ assertEquals(9, mapping.getProviderServiceMapID());
+ assertEquals(Boolean.FALSE, mapping.getDeleted());
+ assertEquals("N", mapping.getProcessed());
+ assertEquals("admin", mapping.getCreatedBy());
+ assertEquals(createdDate, mapping.getCreatedDate());
+ assertEquals("admin", mapping.getModifiedBy());
+ assertEquals(createdDate, mapping.getLastModDate());
+ }
+
+ @Test
+ @DisplayName("The mapping should hold the districts it was built with")
+ void mapping_shouldHoldDistricts() {
+ Timestamp createdDate = new Timestamp(System.currentTimeMillis());
+ com.iemr.tm.data.location.Districts district = new com.iemr.tm.data.location.Districts();
+
+ ZoneDistrictMapping mapping = new ZoneDistrictMapping(1, 2, 3, 9, false, "N", "admin", createdDate,
+ "admin", createdDate, Collections.singleton(district));
+
+ assertEquals(1, mapping.getDistrictsSet().size());
+ assertTrue(mapping.getDistrictsSet().contains(district));
+ }
+
+ @Test
+ @DisplayName("An empty mapping should accept every mapped property")
+ void emptyMapping_shouldAcceptEveryProperty() {
+ ZoneDistrictMapping mapping = new ZoneDistrictMapping();
+ mapping.setZoneDistrictMapID(1);
+ mapping.setZoneID(2);
+ mapping.setDistrictID(3);
+ mapping.setProviderServiceMapID(9);
+ mapping.setDeleted(true);
+ mapping.setProcessed("U");
+ mapping.setCreatedBy("admin");
+ mapping.setModifiedBy("admin");
+ mapping.setDistrictsSet(Collections.emptySet());
+
+ assertEquals(1, mapping.getZoneDistrictMapID());
+ assertEquals(Boolean.TRUE, mapping.getDeleted());
+ assertEquals("U", mapping.getProcessed());
+ assertTrue(mapping.getDistrictsSet().isEmpty());
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/anc/ANCDoctorServiceImplTest.java b/src/test/java/com/iemr/tm/service/anc/ANCDoctorServiceImplTest.java
new file mode 100644
index 00000000..83030221
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/anc/ANCDoctorServiceImplTest.java
@@ -0,0 +1,68 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.anc;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.nurse.anc.ANCDiagnosisRepo;
+import com.iemr.tm.repo.quickConsultation.PrescriptionDetailRepo;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("ANCDoctorServiceImpl Test Suite")
+class ANCDoctorServiceImplTest {
+
+ @Mock
+ private ANCDiagnosisRepo ancDiagnosisRepo;
+ @Mock
+ private PrescriptionDetailRepo prescriptionDetailRepo;
+
+ @InjectMocks
+ private ANCDoctorServiceImpl service;
+
+ @Test
+ @DisplayName("saveBenANCDiagnosis should answer for a well formed request")
+ void saveBenANCDiagnosis_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.saveBenANCDiagnosis(new com.google.gson.JsonObject(), 11L));
+ }
+
+ @Test
+ @DisplayName("getANCDiagnosisDetails should answer for a well formed request")
+ void getANCDiagnosisDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getANCDiagnosisDetails(11L, 11L));
+ }
+
+ @Test
+ @DisplayName("updateBenANCDiagnosis should answer for a well formed request")
+ void updateBenANCDiagnosis_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateBenANCDiagnosis(new com.iemr.tm.data.anc.ANCDiagnosis()));
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/anc/ANCNurseServiceImplTest.java b/src/test/java/com/iemr/tm/service/anc/ANCNurseServiceImplTest.java
new file mode 100644
index 00000000..dd5c640a
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/anc/ANCNurseServiceImplTest.java
@@ -0,0 +1,249 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.anc;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.nurse.anc.ANCCareRepo;
+import com.iemr.tm.repo.nurse.anc.ANCWomenVaccineRepo;
+import com.iemr.tm.repo.nurse.anc.BenAdherenceRepo;
+import com.iemr.tm.repo.nurse.anc.SysObstetricExaminationRepo;
+import com.iemr.tm.repo.quickConsultation.LabTestOrderDetailRepo;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("ANCNurseServiceImpl Test Suite")
+class ANCNurseServiceImplTest {
+
+ @Mock
+ private ANCCareRepo ancCareRepo;
+ @Mock
+ private ANCWomenVaccineRepo ancWomenVaccineRepo;
+ @Mock
+ private BenAdherenceRepo benAdherenceRepo;
+ @Mock
+ private SysObstetricExaminationRepo sysObstetricExaminationRepo;
+ @Mock
+ private LabTestOrderDetailRepo labTestOrderDetailRepo;
+
+ @InjectMocks
+ private ANCNurseServiceImpl service;
+
+ @Test
+ @DisplayName("saveBeneficiaryANCDetails should answer for a well formed request")
+ void saveBeneficiaryANCDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.saveBeneficiaryANCDetails(new com.iemr.tm.data.anc.ANCCareDetails()));
+ }
+
+ @Test
+ @DisplayName("saveANCWomenVaccineDetails should answer for a well formed request")
+ void saveANCWomenVaccineDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.saveANCWomenVaccineDetails(new java.util.ArrayList<>()));
+ }
+
+ @Test
+ @DisplayName("saveBenInvestigationFromDoc should answer for a well formed request")
+ void saveBenInvestigationFromDoc_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.saveBenInvestigationFromDoc(new com.iemr.tm.data.anc.WrapperBenInvestigationANC()));
+ }
+
+ @Test
+ @DisplayName("saveBenAncCareDetails should answer for a well formed request")
+ void saveBenAncCareDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.saveBenAncCareDetails(new com.iemr.tm.data.anc.ANCCareDetails()));
+ }
+
+ @Test
+ @DisplayName("saveAncImmunizationDetails should answer for a well formed request")
+ void saveAncImmunizationDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.saveAncImmunizationDetails(new com.iemr.tm.data.anc.WrapperAncImmunization()));
+ }
+
+ @Test
+ @DisplayName("saveSysObstetricExamination should answer for a well formed request")
+ void saveSysObstetricExamination_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.saveSysObstetricExamination(org.mockito.Mockito.mock(com.iemr.tm.data.anc.SysObstetricExamination.class)));
+ }
+
+ @Test
+ @DisplayName("getSysObstetricExamination should answer for a well formed request")
+ void getSysObstetricExamination_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getSysObstetricExamination(11L, 11L));
+ }
+
+ @Test
+ @DisplayName("getANCCareDetails should answer for a well formed request")
+ void getANCCareDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getANCCareDetails(11L, 11L));
+ }
+
+ @Test
+ @DisplayName("getANCWomenVaccineDetails should answer for a well formed request")
+ void getANCWomenVaccineDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getANCWomenVaccineDetails(11L, 11L));
+ }
+
+ @Test
+ @DisplayName("updateBenAdherenceDetails should answer for a well formed request")
+ void updateBenAdherenceDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateBenAdherenceDetails(new com.iemr.tm.data.anc.BenAdherence()));
+ }
+
+ @Test
+ @DisplayName("updateBenAncCareDetails should answer for a well formed request")
+ void updateBenAncCareDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateBenAncCareDetails(new com.iemr.tm.data.anc.ANCCareDetails()));
+ }
+
+ @Test
+ @DisplayName("updateBenAncImmunizationDetails should answer for a well formed request")
+ void updateBenAncImmunizationDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateBenAncImmunizationDetails(new com.iemr.tm.data.anc.WrapperAncImmunization()));
+ }
+
+ @Test
+ @DisplayName("updateSysObstetricExamination should answer for a well formed request")
+ void updateSysObstetricExamination_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateSysObstetricExamination(org.mockito.Mockito.mock(com.iemr.tm.data.anc.SysObstetricExamination.class)));
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("ANC care capture")
+ class AncCareTests {
+
+ private com.iemr.tm.data.anc.ANCCareDetails careDetails() {
+ com.iemr.tm.data.anc.ANCCareDetails details = new com.iemr.tm.data.anc.ANCCareDetails();
+ details.setBeneficiaryRegID(11L);
+ details.setVisitCode(22L);
+ return details;
+ }
+
+ @Test
+ @DisplayName("saveBeneficiaryANCDetails should return the stored row id")
+ void saveAncDetails_shouldReturnStoredId() {
+ com.iemr.tm.data.anc.ANCCareDetails stored = careDetails();
+ stored.setID(4L);
+ org.mockito.Mockito.when(ancCareRepo.save(org.mockito.ArgumentMatchers.any())).thenReturn(stored);
+
+ org.junit.jupiter.api.Assertions.assertEquals(4L, service.saveBeneficiaryANCDetails(careDetails()));
+ }
+
+ @Test
+ @DisplayName("saveBeneficiaryANCDetails should return null when nothing was stored")
+ void saveAncDetails_shouldReturnNullWhenNothingStored() {
+ org.mockito.Mockito.when(ancCareRepo.save(org.mockito.ArgumentMatchers.any())).thenReturn(null);
+
+ org.junit.jupiter.api.Assertions.assertNull(service.saveBeneficiaryANCDetails(careDetails()));
+ }
+
+ @Test
+ @DisplayName("saveBenAncCareDetails should store the ANC care details for the visit")
+ void saveAncCareDetails_shouldStoreCareDetails() throws Exception {
+ com.iemr.tm.data.anc.ANCCareDetails stored = careDetails();
+ stored.setID(4L);
+ org.mockito.Mockito.when(ancCareRepo.save(org.mockito.ArgumentMatchers.any())).thenReturn(stored);
+
+ org.junit.jupiter.api.Assertions.assertEquals(4L, service.saveBenAncCareDetails(careDetails()));
+ }
+
+ @Test
+ @DisplayName("getANCCareDetails should render the stored ANC care for the visit")
+ void getAncCareDetails_shouldRenderStoredCare() {
+ org.mockito.Mockito.when(ancCareRepo.getANCCareDetails(11L, 22L)).thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getANCCareDetails(11L, 22L));
+ }
+
+ @Test
+ @DisplayName("getANCWomenVaccineDetails should render the stored vaccine details for the visit")
+ void getWomenVaccineDetails_shouldRenderStoredVaccines() {
+ org.mockito.Mockito.when(ancWomenVaccineRepo.getANCWomenVaccineDetails(11L, 22L))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getANCWomenVaccineDetails(11L, 22L));
+ }
+
+ @Test
+ @DisplayName("getSysObstetricExamination should delegate to the obstetric examination repository")
+ void getObstetricExamination_shouldDelegateToRepo() {
+ com.iemr.tm.data.anc.SysObstetricExamination stored = new com.iemr.tm.data.anc.SysObstetricExamination();
+ org.mockito.Mockito.when(sysObstetricExaminationRepo.getSysObstetricExaminationData(11L, 22L))
+ .thenReturn(stored);
+
+ org.junit.jupiter.api.Assertions.assertEquals(stored, service.getSysObstetricExamination(11L, 22L));
+ }
+
+ @Test
+ @DisplayName("saveSysObstetricExamination should return the stored row id")
+ void saveObstetricExamination_shouldReturnStoredId() {
+ com.iemr.tm.data.anc.SysObstetricExamination stored = new com.iemr.tm.data.anc.SysObstetricExamination();
+ stored.setID(4L);
+ org.mockito.Mockito.when(sysObstetricExaminationRepo.save(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(stored);
+
+ org.junit.jupiter.api.Assertions.assertEquals(4L, service.saveSysObstetricExamination(
+ new com.iemr.tm.data.anc.SysObstetricExamination()));
+ }
+
+ @Test
+ @DisplayName("updateBenAncCareDetails should mark an already processed row as updated")
+ void updateAncCareDetails_shouldMarkProcessedAsUpdated() throws Exception {
+ org.mockito.Mockito.when(ancCareRepo.getBenANCCareDetailsStatus(11L, 22L)).thenReturn("P");
+
+ org.junit.jupiter.api.Assertions.assertEquals(0, service.updateBenAncCareDetails(careDetails()));
+ }
+
+ @Test
+ @DisplayName("updateSysObstetricExamination should mark an already processed row as updated")
+ void updateObstetricExamination_shouldMarkProcessedAsUpdated() {
+ com.iemr.tm.data.anc.SysObstetricExamination examination =
+ new com.iemr.tm.data.anc.SysObstetricExamination();
+ examination.setBeneficiaryRegID(11L);
+ examination.setVisitCode(22L);
+ org.mockito.Mockito.when(sysObstetricExaminationRepo.getBenObstetricExaminationStatus(11L, 22L))
+ .thenReturn("P");
+
+ org.junit.jupiter.api.Assertions.assertEquals(0, service.updateSysObstetricExamination(examination));
+ }
+
+ @Test
+ @DisplayName("updateBenAdherenceDetails should mark an already processed row as updated")
+ void updateAdherenceDetails_shouldMarkProcessedAsUpdated() {
+ com.iemr.tm.data.anc.BenAdherence adherence = new com.iemr.tm.data.anc.BenAdherence();
+ adherence.setBeneficiaryRegID(11L);
+ adherence.setVisitCode(22L);
+ org.mockito.Mockito.when(benAdherenceRepo.getBenAdherenceDetailsStatus(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.any())).thenReturn("P");
+
+ org.junit.jupiter.api.Assertions.assertEquals(0, service.updateBenAdherenceDetails(adherence));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/anc/ANCServiceImplTest.java b/src/test/java/com/iemr/tm/service/anc/ANCServiceImplTest.java
new file mode 100644
index 00000000..af39f95f
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/anc/ANCServiceImplTest.java
@@ -0,0 +1,722 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.anc;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyShort;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.iemr.tm.data.anc.ANCCareDetails;
+import com.iemr.tm.data.anc.FemaleObstetricHistory;
+import com.iemr.tm.data.nurse.CommonUtilityClass;
+import com.iemr.tm.data.tele_consultation.TeleconsultationRequestOBJ;
+import com.iemr.tm.repo.benFlowStatus.BeneficiaryFlowStatusRepo;
+import com.iemr.tm.repo.nurse.anc.ANCCareRepo;
+import com.iemr.tm.repo.nurse.BenAnthropometryRepo;
+import com.iemr.tm.repo.nurse.BenVisitDetailRepo;
+import com.iemr.tm.repo.nurse.anc.BenAdherenceRepo;
+import com.iemr.tm.repo.nurse.anc.BenMedHistoryRepo;
+import com.iemr.tm.repo.nurse.anc.BenMenstrualDetailsRepo;
+import com.iemr.tm.repo.nurse.anc.BencomrbidityCondRepo;
+import com.iemr.tm.repo.nurse.anc.FemaleObstetricHistoryRepo;
+import com.iemr.tm.repo.quickConsultation.BenChiefComplaintRepo;
+import com.iemr.tm.service.benFlowStatus.CommonBenStatusFlowServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonDoctorServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonNurseServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonServiceImpl;
+import com.iemr.tm.service.labtechnician.LabTechnicianServiceImpl;
+import com.iemr.tm.service.tele_consultation.SMSGatewayServiceImpl;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("ANCServiceImpl Test Suite")
+class ANCServiceImplTest {
+
+ private static final String AUTHORIZATION = "Bearer session-token";
+ private static final Long BEN_REG_ID = 11L;
+ private static final Long VISIT_ID = 3L;
+ private static final Long VISIT_CODE = 22L;
+
+ @Mock
+ private ANCNurseServiceImpl ancNurseServiceImpl;
+ @Mock
+ private ANCDoctorServiceImpl ancDoctorServiceImpl;
+ @Mock
+ private CommonNurseServiceImpl commonNurseServiceImpl;
+ @Mock
+ private CommonDoctorServiceImpl commonDoctorServiceImpl;
+ @Mock
+ private CommonBenStatusFlowServiceImpl commonBenStatusFlowServiceImpl;
+ @Mock
+ private LabTechnicianServiceImpl labTechnicianServiceImpl;
+ @Mock
+ private CommonServiceImpl commonServiceImpl;
+ @Mock
+ private BeneficiaryFlowStatusRepo beneficiaryFlowStatusRepo;
+ @Mock
+ private BenAnthropometryRepo benAnthropometryRepo;
+ @Mock
+ private BenMedHistoryRepo benMedHistoryRepo;
+ @Mock
+ private BencomrbidityCondRepo bencomrbidityCondRepo;
+ @Mock
+ private ANCCareRepo ancCareRepo;
+ @Mock
+ private FemaleObstetricHistoryRepo femaleObstetricHistoryRepo;
+ @Mock
+ private com.iemr.tm.repo.nurse.anc.ANCDiagnosisRepo aNCDiagnosisRepo;
+ @Mock
+ private com.iemr.tm.repo.foetalmonitor.FoetalMonitorRepo foetalMonitorRepo;
+ @Mock
+ private BenVisitDetailRepo benVisitDetailRepo;
+ @Mock
+ private BenChiefComplaintRepo benChiefComplaintRepo;
+ @Mock
+ private BenAdherenceRepo benAdherenceRepo;
+ @Mock
+ private BenMenstrualDetailsRepo benMenstrualDetailsRepo;
+ @Mock
+ private SMSGatewayServiceImpl sMSGatewayServiceImpl;
+
+ @InjectMocks
+ private ANCServiceImpl service;
+
+ private static final String FULL_HISTORY = "{\"pastHistory\":{},\"comorbidConditions\":{},"
+ + "\"medicationHistory\":{\"medicationHistoryList\":[{\"currentMedication\":\"Iron\"}]},"
+ + "\"personalHistory\":{},\"familyHistory\":{},\"menstrualHistory\":{},"
+ + "\"femaleObstetricHistory\":{},\"immunizationHistory\":{},\"childVaccineDetails\":{}}";
+
+ private static final String FULL_EXAMINATION = "{\"generalExamination\":{},\"headToToeExamination\":{},"
+ + "\"cardioVascularExamination\":{},\"respiratorySystemExamination\":{},"
+ + "\"centralNervousSystemExamination\":{},\"musculoskeletalSystemExamination\":{},"
+ + "\"genitoUrinarySystemExamination\":{},\"obstetricExamination\":{}}";
+
+ private JsonObject json(String raw) {
+ return JsonParser.parseString(raw).getAsJsonObject();
+ }
+
+ private JsonObject nurseRequest() {
+ return json("{" + "\"beneficiaryRegID\":11,\"providerServiceMapID\":9,\"vanID\":7,\"sessionID\":1,"
+ + "\"benFlowID\":5,\"createdBy\":\"nurse1\","
+ + "\"visitDetails\":{"
+ + " \"visitDetails\":{\"beneficiaryRegID\":11,\"visitReason\":\"New Chief Complaint\","
+ + " \"visitCategory\":\"ANC\"},"
+ + " \"chiefComplaints\":[{\"chiefComplaintID\":3}],\"adherence\":{\"toDrugs\":true},"
+ + " \"investigation\":{\"laboratoryList\":[{\"testID\":1}]}"
+ + "},"
+ + "\"ancDetails\":{\"ancObstetricDetails\":{},\"ancImmunization\":{}},"
+ + "\"historyDetails\":" + FULL_HISTORY + ",\"vitalDetails\":{\"height_cm\":170},"
+ + "\"examinationDetails\":" + FULL_EXAMINATION + "}");
+ }
+
+ private CommonUtilityClass utility() {
+ CommonUtilityClass utility = new CommonUtilityClass();
+ utility.setBeneficiaryRegID(BEN_REG_ID);
+ utility.setVanID(7);
+ utility.setSessionID(1);
+ utility.setProviderServiceMapID(9);
+ utility.setCreatedBy("nurse1");
+ return utility;
+ }
+
+ private TeleconsultationRequestOBJ teleconsultationRequest(boolean walkIn) {
+ TeleconsultationRequestOBJ request = new TeleconsultationRequestOBJ();
+ request.setWalkIn(walkIn);
+ request.setUserID(42);
+ request.setSpecializationID(2);
+ request.setTmRequestID(8L);
+ request.setAllocationDate(new Timestamp(1_700_000_000_000L));
+ return request;
+ }
+
+ @BeforeEach
+ @DisplayName("Wire the collaborators that every save path needs")
+ void setUp() throws Exception {
+ when(commonNurseServiceImpl.getMaxCurrentdate(anyLong(), anyString(), anyString())).thenReturn(0);
+ when(commonNurseServiceImpl.saveBeneficiaryVisitDetails(any())).thenReturn(VISIT_ID);
+ when(commonNurseServiceImpl.generateVisitCode(anyLong(), any(), any())).thenReturn(VISIT_CODE);
+ when(commonNurseServiceImpl.saveBenChiefComplaints(any())).thenReturn(1);
+ when(commonNurseServiceImpl.saveBenAdherenceDetails(any())).thenReturn(1);
+ when(commonNurseServiceImpl.saveBenInvestigationDetails(any())).thenReturn(1);
+ when(commonNurseServiceImpl.saveBeneficiaryPhysicalAnthropometryDetails(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBeneficiaryPhysicalVitalDetails(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.savePhyGeneralExamination(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.savePhyHeadToToeExamination(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveSysCardiovascularExamination(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveSysRespiratoryExamination(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveSysCentralNervousExamination(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveSysMusculoskeletalSystemExamination(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveSysGenitourinarySystemExamination(any())).thenReturn(1L);
+ when(ancNurseServiceImpl.saveSysObstetricExamination(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenPastHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenComorbidConditions(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenMedicationHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.savePersonalHistory(any())).thenReturn(1);
+ when(commonNurseServiceImpl.saveAllergyHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenFamilyHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenMenstrualHistory(any())).thenReturn(1);
+ when(commonNurseServiceImpl.saveFemaleObstetricHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveImmunizationHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveChildOptionalVaccineDetail(any())).thenReturn(1L);
+ when(ancNurseServiceImpl.saveBenAncCareDetails(any())).thenReturn(1L);
+ when(ancNurseServiceImpl.saveAncImmunizationDetails(any())).thenReturn(1L);
+ when(foetalMonitorRepo.getFoetalMonitorDetailsByFlowId(any())).thenReturn(new ArrayList<>());
+ when(commonBenStatusFlowServiceImpl.updateBenFlowNurseAfterNurseActivityANC(any(), anyLong(), anyLong(),
+ anyString(), anyString(), anyShort(), anyShort(), anyShort(), anyShort(), anyShort(), anyLong(), any(),
+ anyShort(), any(), any(), anyShort())).thenReturn(1);
+ }
+
+ @Nested
+ @DisplayName("saveANCNurseData")
+ class SaveNurseDataTests {
+
+ @Test
+ @DisplayName("saveANCNurseData should save the visit, ANC, history, vitals and examination")
+ void saveNurseData_shouldSaveEverySection() throws Exception {
+ String result = service.saveANCNurseData(nurseRequest(), AUTHORIZATION);
+
+ assertTrue(result.contains("Data saved successfully"));
+ assertTrue(result.contains("\"visitCode\":\"22\""));
+ }
+
+ @Test
+ @DisplayName("saveANCNurseData should report an already saved visit")
+ void saveNurseData_shouldReportAlreadySavedVisit() throws Exception {
+ when(commonNurseServiceImpl.getMaxCurrentdate(anyLong(), anyString(), anyString())).thenReturn(1);
+
+ assertTrue(service.saveANCNurseData(nurseRequest(), AUTHORIZATION).contains("Data already saved"));
+ }
+
+ @Test
+ @DisplayName("saveANCNurseData should reject a request without visit details")
+ void saveNurseData_shouldRejectRequestWithoutVisitDetails() {
+ assertThrows(Exception.class, () -> service.saveANCNurseData(json("{}"), AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveANCNurseData should fail when the visit could not be created")
+ void saveNurseData_shouldFailWhenVisitNotCreated() throws Exception {
+ when(commonNurseServiceImpl.saveBeneficiaryVisitDetails(any())).thenReturn(0L);
+
+ assertThrows(RuntimeException.class, () -> service.saveANCNurseData(nurseRequest(), AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveANCNurseData should fail when the ANC details could not be stored")
+ void saveNurseData_shouldFailWhenAncDetailsNotStored() throws Exception {
+ when(ancNurseServiceImpl.saveBenAncCareDetails(any())).thenReturn(null);
+
+ assertThrows(RuntimeException.class, () -> service.saveANCNurseData(nurseRequest(), AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveANCNurseData should notify a scheduled teleconsultation by SMS")
+ void saveNurseData_shouldNotifyScheduledTeleconsultation() throws Exception {
+ when(commonServiceImpl.createTcRequest(any(), any(), anyString()))
+ .thenReturn(teleconsultationRequest(false));
+
+ service.saveANCNurseData(nurseRequest(), AUTHORIZATION);
+
+ verify(sMSGatewayServiceImpl).smsSenderGateway(eq("schedule"), anyLong(), anyInt(), anyLong(), any(),
+ anyString(), anyString(), any(), eq(AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveANCNurseData should not notify a walk-in teleconsultation")
+ void saveNurseData_shouldNotNotifyWalkInTeleconsultation() throws Exception {
+ when(commonServiceImpl.createTcRequest(any(), any(), anyString())).thenReturn(teleconsultationRequest(true));
+
+ service.saveANCNurseData(nurseRequest(), AUTHORIZATION);
+
+ verify(sMSGatewayServiceImpl, never()).smsSenderGateway(anyString(), anyLong(), anyInt(), anyLong(), any(),
+ anyString(), anyString(), any(), anyString());
+ }
+ }
+
+ @Nested
+ @DisplayName("deleteVisitDetails")
+ class DeleteVisitDetailsTests {
+
+ @Test
+ @DisplayName("deleteVisitDetails should remove the visit rows for a created visit")
+ void deleteVisitDetails_shouldRemoveVisitRows() throws Exception {
+ when(benVisitDetailRepo.getVisitCode(BEN_REG_ID, 9)).thenReturn(VISIT_CODE);
+
+ service.deleteVisitDetails(nurseRequest());
+
+ verify(benVisitDetailRepo).deleteVisitDetails(VISIT_CODE);
+ }
+
+ @Test
+ @DisplayName("deleteVisitDetails should do nothing for a request without visit details")
+ void deleteVisitDetails_shouldDoNothingWithoutVisitDetails() throws Exception {
+ service.deleteVisitDetails(json("{}"));
+
+ verify(benVisitDetailRepo, never()).deleteVisitDetails(anyLong());
+ }
+ }
+
+ @Nested
+ @DisplayName("nurse section saves")
+ class SectionSaveTests {
+
+ @Test
+ @DisplayName("saveBenVisitDetails should return the new visit id and code")
+ void saveBenVisitDetails_shouldReturnVisitIdAndCode() throws Exception {
+ Map result = service.saveBenVisitDetails(nurseRequest().getAsJsonObject("visitDetails"),
+ utility());
+
+ assertEquals(VISIT_ID, result.get("visitID"));
+ assertEquals(VISIT_CODE, result.get("visitCode"));
+ }
+
+ @Test
+ @DisplayName("saveBenVisitDetails should return nothing when the visit was already recorded")
+ void saveBenVisitDetails_shouldReturnNothingForAlreadyRecordedVisit() throws Exception {
+ when(commonNurseServiceImpl.getMaxCurrentdate(anyLong(), anyString(), anyString())).thenReturn(1);
+
+ assertTrue(service.saveBenVisitDetails(nurseRequest().getAsJsonObject("visitDetails"), utility())
+ .isEmpty());
+ }
+
+ @Test
+ @DisplayName("saveBenANCDetails should store the obstetric details and the immunisation")
+ void saveAncDetails_shouldStoreObstetricAndImmunisation() throws Exception {
+ assertEquals(1L, service.saveBenANCDetails(
+ json("{\"ancObstetricDetails\":{},\"ancImmunization\":{}}"), VISIT_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("saveBenANCDetails should report a failure when the obstetric details were not captured")
+ void saveAncDetails_shouldReportFailureWithoutObstetricDetails() throws Exception {
+ assertNull(service.saveBenANCDetails(json("{}"), VISIT_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("saveBenANCHistoryDetails should report a failure when no history section was captured")
+ void saveHistory_shouldReportFailureWithoutCapturedSections() throws Exception {
+ assertNull(service.saveBenANCHistoryDetails(json("{}"), VISIT_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("saveBenANCHistoryDetails should store every captured history section")
+ void saveHistory_shouldStoreCapturedSections() throws Exception {
+ when(commonNurseServiceImpl.saveBenPastHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenComorbidConditions(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenMedicationHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.savePersonalHistory(any())).thenReturn(1);
+ when(commonNurseServiceImpl.saveAllergyHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenFamilyHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenMenstrualHistory(any())).thenReturn(1);
+ when(commonNurseServiceImpl.saveFemaleObstetricHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveImmunizationHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveChildOptionalVaccineDetail(any())).thenReturn(1L);
+
+ JsonObject history = json("{\"pastHistory\":{},\"comorbidConditions\":{},"
+ + "\"medicationHistory\":{\"medicationHistoryList\":[{\"currentMedication\":\"Iron\"}]},"
+ + "\"personalHistory\":{},\"familyHistory\":{},\"menstrualHistory\":{},"
+ + "\"femaleObstetricHistory\":{},\"immunizationHistory\":{},\"childVaccineDetails\":{}}");
+
+ assertEquals(1L, service.saveBenANCHistoryDetails(history, VISIT_ID, VISIT_CODE));
+ verify(commonNurseServiceImpl).saveBenPastHistory(any());
+ }
+
+ @Test
+ @DisplayName("saveBenANCVitalDetails should store the anthropometry and the physical vitals")
+ void saveVitals_shouldStoreAnthropometryAndPhysicalVitals() throws Exception {
+ assertEquals(1L, service.saveBenANCVitalDetails(json("{\"height_cm\":170}"), VISIT_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("saveBenANCVitalDetails should report a failure when the physical vitals were not stored")
+ void saveVitals_shouldReportFailureWhenPhysicalVitalsNotStored() throws Exception {
+ when(commonNurseServiceImpl.saveBeneficiaryPhysicalVitalDetails(any())).thenReturn(null);
+
+ assertNull(service.saveBenANCVitalDetails(json("{}"), VISIT_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("saveBenANCExaminationDetails should report a failure when no examination section was captured")
+ void saveExamination_shouldReportFailureWithoutCapturedSections() throws Exception {
+ assertNull(service.saveBenANCExaminationDetails(json("{}"), VISIT_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("saveBenANCExaminationDetails should store every captured examination section")
+ void saveExamination_shouldStoreCapturedSections() throws Exception {
+ when(commonNurseServiceImpl.savePhyHeadToToeExamination(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveSysCardiovascularExamination(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveSysRespiratoryExamination(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveSysCentralNervousExamination(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveSysMusculoskeletalSystemExamination(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveSysGenitourinarySystemExamination(any())).thenReturn(1L);
+ when(ancNurseServiceImpl.saveSysObstetricExamination(any())).thenReturn(1L);
+
+ JsonObject examination = json("{\"generalExamination\":{},\"headToToeExamination\":{},"
+ + "\"cardioVascularExamination\":{},\"respiratorySystemExamination\":{},"
+ + "\"centralNervousSystemExamination\":{},\"musculoskeletalSystemExamination\":{},"
+ + "\"genitoUrinarySystemExamination\":{},\"obstetricExamination\":{}}");
+
+ assertEquals(1L, service.saveBenANCExaminationDetails(examination, VISIT_ID, VISIT_CODE));
+ verify(commonNurseServiceImpl).savePhyHeadToToeExamination(any());
+ }
+ }
+
+ @Nested
+ @DisplayName("read endpoints")
+ class ReadTests {
+
+ @Test
+ @DisplayName("getBenVisitDetailsFrmNurseANC should assemble the visit, adherence, complaints and tests")
+ void getVisitDetails_shouldAssembleVisitSections() {
+ when(commonNurseServiceImpl.getBenAdherence(BEN_REG_ID, VISIT_CODE)).thenReturn("{}");
+ when(commonNurseServiceImpl.getBenChiefComplaints(BEN_REG_ID, VISIT_CODE)).thenReturn("[]");
+ when(commonNurseServiceImpl.getLabTestOrders(BEN_REG_ID, VISIT_CODE)).thenReturn("{}");
+
+ String result = service.getBenVisitDetailsFrmNurseANC(BEN_REG_ID, VISIT_CODE);
+
+ assertTrue(result.contains("ANCNurseVisitDetail"));
+ assertTrue(result.contains("BenAdherence"));
+ }
+
+ @Test
+ @DisplayName("getBenANCDetailsFrmNurseANC should assemble the ANC care and vaccine details")
+ void getAncDetails_shouldAssembleAncSections() {
+ when(ancNurseServiceImpl.getANCCareDetails(BEN_REG_ID, VISIT_CODE)).thenReturn("{}");
+ when(ancNurseServiceImpl.getANCWomenVaccineDetails(BEN_REG_ID, VISIT_CODE)).thenReturn("{}");
+
+ String result = service.getBenANCDetailsFrmNurseANC(BEN_REG_ID, VISIT_CODE);
+
+ assertTrue(result.contains("ANCCareDetail"));
+ assertTrue(result.contains("ANCWomenVaccineDetails"));
+ }
+
+ @Test
+ @DisplayName("getBenANCHistoryDetails should assemble every stored history section")
+ void getHistoryDetails_shouldAssembleStoredSections() {
+ when(commonNurseServiceImpl.getPastHistoryData(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(new com.iemr.tm.data.anc.BenMedHistory());
+
+ assertTrue(service.getBenANCHistoryDetails(BEN_REG_ID, VISIT_CODE).contains("PastHistory"));
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryVitalDetails should assemble the anthropometry and the physical vitals")
+ void getVitalDetails_shouldAssembleVitalSections() {
+ when(commonNurseServiceImpl.getBeneficiaryPhysicalAnthropometryDetails(BEN_REG_ID, VISIT_CODE))
+ .thenReturn("{}");
+ when(commonNurseServiceImpl.getBeneficiaryPhysicalVitalDetails(BEN_REG_ID, VISIT_CODE)).thenReturn("{}");
+
+ assertTrue(service.getBeneficiaryVitalDetails(BEN_REG_ID, VISIT_CODE).contains("benAnthropometryDetail"));
+ }
+
+ @Test
+ @DisplayName("getANCExaminationDetailsData should assemble every stored examination section")
+ void getExaminationDetails_shouldAssembleStoredSections() {
+ when(commonNurseServiceImpl.getGeneralExaminationData(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(new com.iemr.tm.data.anc.PhyGeneralExamination());
+
+ assertTrue(service.getANCExaminationDetailsData(BEN_REG_ID, VISIT_CODE).contains("generalExamination"));
+ }
+
+ @Test
+ @DisplayName("getBenANCNurseData should assemble the nurse captured sections")
+ void getNurseData_shouldAssembleNurseSections() {
+ assertTrue(service.getBenANCNurseData(BEN_REG_ID, VISIT_CODE).contains("history"));
+ }
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorANC should assemble the whole doctor case record")
+ void getCaseRecord_shouldAssembleDoctorCaseRecord() throws Exception {
+ when(commonNurseServiceImpl.getGraphicalTrendData(BEN_REG_ID, "anc")).thenReturn(new HashMap<>());
+
+ String result = service.getBenCaseRecordFromDoctorANC(BEN_REG_ID, VISIT_CODE);
+
+ assertTrue(result.contains("findings"));
+ assertTrue(result.contains("fetosenseData"));
+ assertTrue(result.contains("GraphData"));
+ }
+ }
+
+ @Nested
+ @DisplayName("saveANCDoctorData")
+ class SaveDoctorDataTests {
+
+ private JsonObject doctorRequest() {
+ return json("{" + "\"beneficiaryRegID\":11,\"benVisitID\":3,\"visitCode\":22,\"providerServiceMapID\":9,"
+ + "\"createdBy\":\"doctor1\",\"doctorSignatureFlag\":true,\"findings\":{},"
+ + "\"diagnosis\":{\"specialistDiagnosis\":\"ANC follow up\"},"
+ + "\"investigation\":{\"laboratoryList\":[{\"testID\":1}]},"
+ + "\"prescription\":[{\"drugID\":1,\"formName\":\"Tablet\"}],"
+ + "\"refer\":{\"referredToInstituteID\":1}" + "}");
+ }
+
+ @BeforeEach
+ void stubDoctorCollaborators() throws Exception {
+ when(commonDoctorServiceImpl.saveDocFindings(any())).thenReturn(1);
+ when(commonNurseServiceImpl.savePrescriptionDetailsAndGetPrescriptionID(any(), any(), any(), any(), any(),
+ any(), any(), any(), any(), any())).thenReturn(4L);
+ when(ancDoctorServiceImpl.saveBenANCDiagnosis(any(), any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenInvestigation(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenPrescribedDrugsList(any())).thenReturn(1);
+ when(commonDoctorServiceImpl.saveBenReferDetails(any())).thenReturn(1L);
+ when(commonDoctorServiceImpl.updateBenFlowtableAfterDocDataSave(any(), anyBoolean(), anyBoolean(), any(),
+ anyBoolean())).thenReturn(1);
+ }
+
+ @Test
+ @DisplayName("saveANCDoctorData should save the findings, diagnosis, tests, drugs and referral")
+ void saveDoctorData_shouldSaveWholeCaseRecord() throws Exception {
+ assertEquals(1L, service.saveANCDoctorData(doctorRequest(), AUTHORIZATION));
+
+ verify(commonDoctorServiceImpl).saveDocFindings(any());
+ verify(commonNurseServiceImpl).saveBenInvestigation(any());
+ }
+
+ @Test
+ @DisplayName("saveANCDoctorData should succeed for a case record with only an investigation section")
+ void saveDoctorData_shouldSucceedForMinimalCaseRecord() throws Exception {
+ assertEquals(1L,
+ service.saveANCDoctorData(json("{\"beneficiaryRegID\":11,\"investigation\":{}}"), AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveANCDoctorData should fail when the beneficiary flow could not be advanced")
+ void saveDoctorData_shouldFailWhenFlowNotAdvanced() throws Exception {
+ when(commonDoctorServiceImpl.updateBenFlowtableAfterDocDataSave(any(), anyBoolean(), anyBoolean(), any(),
+ anyBoolean())).thenReturn(0);
+
+ assertThrows(RuntimeException.class, () -> service.saveANCDoctorData(doctorRequest(), AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveANCDoctorData should notify a scheduled teleconsultation by SMS")
+ void saveDoctorData_shouldNotifyScheduledTeleconsultation() throws Exception {
+ when(commonServiceImpl.createTcRequest(any(), any(), anyString()))
+ .thenReturn(teleconsultationRequest(false));
+
+ service.saveANCDoctorData(doctorRequest(), AUTHORIZATION);
+
+ verify(sMSGatewayServiceImpl).smsSenderGateway(eq("schedule"), anyLong(), anyInt(), anyLong(), any(), any(),
+ anyString(), any(), eq(AUTHORIZATION));
+ }
+ }
+
+ @Nested
+ @DisplayName("update endpoints")
+ class UpdateTests {
+
+ @Test
+ @DisplayName("updateBenANCDetails should report no change when no ANC section was captured")
+ void updateAncDetails_shouldReportNoChangeWithoutCapturedSections() throws Exception {
+ assertEquals(0, service.updateBenANCDetails(json("{}")));
+ }
+
+ @Test
+ @DisplayName("updateBenANCHistoryDetails should succeed when no history section was captured")
+ void updateHistory_shouldSucceedWithoutCapturedSections() throws Exception {
+ assertEquals(1, service.updateBenANCHistoryDetails(json("{}")));
+ }
+
+ @Test
+ @DisplayName("updateBenANCVitalDetails should confirm the update when both sections changed")
+ void updateVitals_shouldConfirmUpdate() throws Exception {
+ when(commonNurseServiceImpl.updateANCAnthropometryDetails(any())).thenReturn(1);
+ when(commonNurseServiceImpl.updateANCPhysicalVitalDetails(any())).thenReturn(1);
+
+ assertEquals(1, service.updateBenANCVitalDetails(json("{\"height_cm\":170}")));
+ }
+
+ @Test
+ @DisplayName("updateBenANCExaminationDetails should report no change when no section was captured")
+ void updateExamination_shouldReportNoChangeWithoutCapturedSections() throws Exception {
+ assertEquals(0, service.updateBenANCExaminationDetails(json("{}")));
+ }
+
+ @Test
+ @DisplayName("updateANCDoctorData should return nothing for a null request")
+ void updateDoctorData_shouldReturnNothingForNullRequest() throws Exception {
+ assertNull(service.updateANCDoctorData(null, AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("updateANCDoctorData should update the whole case record")
+ void updateDoctorData_shouldUpdateWholeCaseRecord() throws Exception {
+ when(commonDoctorServiceImpl.updateDocFindings(any())).thenReturn(1);
+ when(commonNurseServiceImpl.updatePrescription(any())).thenReturn(1);
+ when(ancDoctorServiceImpl.updateBenANCDiagnosis(any())).thenReturn(1);
+ when(commonNurseServiceImpl.saveBenInvestigation(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenPrescribedDrugsList(any())).thenReturn(1);
+ when(commonDoctorServiceImpl.updateBenReferDetails(any())).thenReturn(1L);
+ when(commonDoctorServiceImpl.updateBenFlowtableAfterDocDataUpdate(any(), anyBoolean(), anyBoolean(), any(),
+ anyBoolean())).thenReturn(1);
+
+ JsonObject request = json("{" + "\"beneficiaryRegID\":11,\"benVisitID\":3,\"visitCode\":22,"
+ + "\"findings\":{},\"diagnosis\":{\"prescriptionID\":4},"
+ + "\"investigation\":{\"laboratoryList\":[{\"testID\":1}]},"
+ + "\"prescription\":[{\"drugID\":1,\"formName\":\"Tablet\"}],"
+ + "\"refer\":{\"referredToInstituteID\":1}" + "}");
+
+ assertEquals(1L, service.updateANCDoctorData(request, AUTHORIZATION));
+ }
+ }
+
+ @Nested
+ @DisplayName("getHRPStatus")
+ class HighRiskPregnancyTests {
+
+ @Test
+ @DisplayName("getHRPStatus should flag a beneficiary who is younger than twenty")
+ void getHRPStatus_shouldFlagYoungBeneficiary() throws Exception {
+ java.time.LocalDate dob = java.time.LocalDate.now().minusYears(18);
+ when(beneficiaryFlowStatusRepo.getBenAgeVal(BEN_REG_ID))
+ .thenReturn(Timestamp.valueOf(dob.atStartOfDay()));
+
+ assertTrue(service.getHRPStatus(BEN_REG_ID, VISIT_CODE).contains("true"));
+ }
+
+ @Test
+ @DisplayName("getHRPStatus should flag a beneficiary shorter than 145 cm")
+ void getHRPStatus_shouldFlagShortBeneficiary() throws Exception {
+ when(benAnthropometryRepo.getBenLatestHeight(BEN_REG_ID)).thenReturn(140d);
+
+ assertTrue(service.getHRPStatus(BEN_REG_ID, VISIT_CODE).contains("true"));
+ }
+
+ @Test
+ @DisplayName("getHRPStatus should flag a beneficiary with a risk marker in the ANC care screen")
+ void getHRPStatus_shouldFlagAncCareRiskMarker() throws Exception {
+ when(ancCareRepo.getANCCareDataForHRP(BEN_REG_ID))
+ .thenReturn(new ArrayList<>(Collections.singletonList(new ANCCareDetails())));
+
+ assertTrue(service.getHRPStatus(BEN_REG_ID, VISIT_CODE).contains("true"));
+ }
+
+ @Test
+ @DisplayName("getHRPStatus should flag a beneficiary with a relevant past illness")
+ void getHRPStatus_shouldFlagPastIllness() throws Exception {
+ when(benMedHistoryRepo.getHRPStatus(BEN_REG_ID))
+ .thenReturn(new ArrayList<>(Collections.singletonList(1L)));
+
+ assertTrue(service.getHRPStatus(BEN_REG_ID, VISIT_CODE).contains("true"));
+ }
+
+ @Test
+ @DisplayName("getHRPStatus should flag a beneficiary with a relevant comorbidity")
+ void getHRPStatus_shouldFlagComorbidity() throws Exception {
+ when(bencomrbidityCondRepo.getHRPStatus(BEN_REG_ID))
+ .thenReturn(new ArrayList<>(Collections.singletonList(1L)));
+
+ assertTrue(service.getHRPStatus(BEN_REG_ID, VISIT_CODE).contains("true"));
+ }
+
+ @Test
+ @DisplayName("getHRPStatus should flag a beneficiary with a relevant obstetric history")
+ void getHRPStatus_shouldFlagObstetricHistory() throws Exception {
+ when(femaleObstetricHistoryRepo.getPastObestetricDataForHRP(anyLong(), anyString(), anyString(),
+ anyString(), anyString(), anyString(), anyString(), anyString(), anyString(), anyString(),
+ anyString(), anyString(), anyString(), anyString(), anyString(), any()))
+ .thenReturn(new ArrayList<>(Collections.singletonList(new FemaleObstetricHistory())));
+
+ assertTrue(service.getHRPStatus(BEN_REG_ID, VISIT_CODE).contains("true"));
+ }
+
+ @Test
+ @DisplayName("getHRPStatus should flag a beneficiary with a relevant recorded diagnosis")
+ void getHRPStatus_shouldFlagRecordedDiagnosis() throws Exception {
+ when(aNCDiagnosisRepo.getANCDiagnosisDataForHRP(anyLong(), anyString(), anyString(), anyString(),
+ anyString(), anyString(), anyString(), anyString(), anyString(), anyString(), anyString(),
+ anyString(), anyString())).thenReturn(new ArrayList<>(Collections.singletonList(1L)));
+
+ assertTrue(service.getHRPStatus(BEN_REG_ID, VISIT_CODE).contains("true"));
+ }
+
+ @Test
+ @DisplayName("getHRPStatus should not flag a beneficiary without any risk marker")
+ void getHRPStatus_shouldNotFlagWithoutRiskMarker() throws Exception {
+ java.time.LocalDate dob = java.time.LocalDate.now().minusYears(28);
+ when(beneficiaryFlowStatusRepo.getBenAgeVal(BEN_REG_ID))
+ .thenReturn(Timestamp.valueOf(dob.atStartOfDay()));
+ when(benAnthropometryRepo.getBenLatestHeight(BEN_REG_ID)).thenReturn(160d);
+
+ assertTrue(service.getHRPStatus(BEN_REG_ID, VISIT_CODE).contains("false"));
+ }
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("ANC captured-section updates")
+ class CapturedSectionUpdateTests {
+
+ @Test
+ @DisplayName("updateBenANCHistoryDetails should update every captured history section")
+ void updateBenANCHistoryDetails_shouldUpdateEveryCapturedSection() throws Exception {
+ org.junit.jupiter.api.Assertions.assertDoesNotThrow(() -> service.updateBenANCHistoryDetails(
+ com.google.gson.JsonParser.parseString("{\"pastHistory\":{},\"comorbidConditions\":{},\"medicationHistory\":{},\"personalHistory\":{},\"familyHistory\":{},\"menstrualHistory\":{},\"femaleObstetricHistory\":{},\"immunizationHistory\":{},\"childVaccineDetails\":{},\"developmentHistory\":{},\"feedingHistory\":{},\"perinatalHistroy\":{},\"allergyHistory\":{}}").getAsJsonObject()));
+ }
+
+ @Test
+ @DisplayName("updateBenANCExaminationDetails should update every captured examination section")
+ void updateBenANCExaminationDetails_shouldUpdateEveryCapturedSection() throws Exception {
+ org.junit.jupiter.api.Assertions.assertDoesNotThrow(() -> service.updateBenANCExaminationDetails(
+ com.google.gson.JsonParser.parseString("{\"generalExamination\":{},\"headToToeExamination\":{},\"gastroIntestinalExamination\":{},\"cardioVascularExamination\":{},\"respiratorySystemExamination\":{},\"centralNervousSystemExamination\":{},\"musculoskeletalSystemExamination\":{},\"genitoUrinarySystemExamination\":{},\"obstetricExamination\":{}}").getAsJsonObject()));
+ }
+
+ @Test
+ @DisplayName("updateBenANCDetails should update every captured ANC section")
+ void updateBenANCDetails_shouldUpdateEveryCapturedSection() throws Exception {
+ org.junit.jupiter.api.Assertions.assertDoesNotThrow(() -> service.updateBenANCDetails(
+ com.google.gson.JsonParser.parseString(
+ "{\"ancObstetricDetails\":{},\"ancImmunization\":{}}").getAsJsonObject()));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/benFlowStatus/CommonBenStatusFlowServiceImplTest.java b/src/test/java/com/iemr/tm/service/benFlowStatus/CommonBenStatusFlowServiceImplTest.java
new file mode 100644
index 00000000..0f05529e
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/benFlowStatus/CommonBenStatusFlowServiceImplTest.java
@@ -0,0 +1,345 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.benFlowStatus;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.benFlowStatus.BeneficiaryFlowStatusRepo;
+import com.iemr.tm.repo.nurse.BenVisitDetailRepo;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("CommonBenStatusFlowServiceImpl Test Suite")
+class CommonBenStatusFlowServiceImplTest {
+
+ @Mock
+ private BeneficiaryFlowStatusRepo beneficiaryFlowStatusRepo;
+ @Mock
+ private BenVisitDetailRepo benVisitDetailRepo;
+
+ @InjectMocks
+ private CommonBenStatusFlowServiceImpl service;
+
+ @Test
+ @DisplayName("createBenFlowRecord should answer for a well formed request")
+ void createBenFlowRecord_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.createBenFlowRecord("{}", 11L, 11L));
+ }
+
+ @Test
+ @DisplayName("updateBenFlowNurseAfterNurseActivity should answer for a well formed request")
+ void updateBenFlowNurseAfterNurseActivity_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateBenFlowNurseAfterNurseActivity(11L, 11L, 11L, "{}", "{}", (short) 1, (short) 1, (short) 1, (short) 1, (short) 1, 11L, 9, (short) 1, new java.sql.Timestamp(1_700_000_000_000L), 9));
+ }
+
+ @Test
+ @DisplayName("updateBenFlowNurseAfterNurseActivityANC should answer for a well formed request")
+ void updateBenFlowNurseAfterNurseActivityANC_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateBenFlowNurseAfterNurseActivityANC(11L, 11L, 11L, "{}", "{}", (short) 1, (short) 1, (short) 1, (short) 1, (short) 1, 11L, 9, (short) 1, new java.sql.Timestamp(1_700_000_000_000L), 9, (short) 1));
+ }
+
+ @Test
+ @DisplayName("updateBenFlowNurseAfterNurseUpdateNCD_Screening should answer for a well formed request")
+ void updateBenFlowNurseAfterNurseUpdateNCD_Screening_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateBenFlowNurseAfterNurseUpdateNCD_Screening(11L, 11L, (short) 1));
+ }
+
+ @Test
+ @DisplayName("updateBenFlowAfterDocData should answer for a well formed request")
+ void updateBenFlowAfterDocData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateBenFlowAfterDocData(11L, 11L, 11L, 11L, (short) 1, (short) 1, (short) 1, (short) 1, 9, new java.sql.Timestamp(1_700_000_000_000L), (short) 1, Boolean.FALSE));
+ }
+
+ @Test
+ @DisplayName("updateBenFlowAfterDocDataFromSpecialist should answer for a well formed request")
+ void updateBenFlowAfterDocDataFromSpecialist_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateBenFlowAfterDocDataFromSpecialist(11L, 11L, 11L, 11L, (short) 1, (short) 1, (short) 1, (short) 1, (short) 1, Boolean.FALSE));
+ }
+
+ @Test
+ @DisplayName("updateBenFlowAfterDocDataFromSpecialistANC should answer for a well formed request")
+ void updateBenFlowAfterDocDataFromSpecialistANC_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateBenFlowAfterDocDataFromSpecialistANC(11L, 11L, 11L, 11L, (short) 1, (short) 1, (short) 1, (short) 1, (short) 1, Boolean.FALSE));
+ }
+
+ @Test
+ @DisplayName("updateBenFlowAfterDocDataUpdate should answer for a well formed request")
+ void updateBenFlowAfterDocDataUpdate_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateBenFlowAfterDocDataUpdate(11L, 11L, 11L, 11L, (short) 1, (short) 1, (short) 1, (short) 1, 9, new java.sql.Timestamp(1_700_000_000_000L), (short) 1, Boolean.FALSE));
+ }
+
+ @Test
+ @DisplayName("updateBenFlowAfterDocDataUpdateTCSpecialist should answer for a well formed request")
+ void updateBenFlowAfterDocDataUpdateTCSpecialist_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateBenFlowAfterDocDataUpdateTCSpecialist(11L, 11L, 11L, 11L, (short) 1, (short) 1, (short) 1, (short) 1, 9, new java.sql.Timestamp(1_700_000_000_000L), (short) 1, Boolean.FALSE));
+ }
+
+ @Test
+ @DisplayName("updateFlowAfterLabResultEntry should answer for a well formed request")
+ void updateFlowAfterLabResultEntry_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateFlowAfterLabResultEntry(11L, 11L, 11L, (short) 1, (short) 1, (short) 1));
+ }
+
+ @Test
+ @DisplayName("updateFlowAfterLabResultEntryForTCSpecialist should answer for a well formed request")
+ void updateFlowAfterLabResultEntryForTCSpecialist_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateFlowAfterLabResultEntryForTCSpecialist(11L, 11L, (short) 1));
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("beneficiary flow record creation")
+ class FlowRecordCreationTests {
+
+ private static final String REGISTRATION = "{\"beneficiaryRegID\":11,\"beneficiaryID\":9,"
+ + "\"providerServiceMapID\":3,\"vanID\":7,\"firstName\":\"Asha\",\"lastName\":\"Devi\","
+ + "\"createdBy\":\"registrar1\",\"genderID\":2,\"genderName\":\"Female\","
+ + "\"dOB\":\"1990-05-14T00:00:00.000Z\","
+ + "\"i_bendemographics\":{\"districtID\":21,\"districtName\":\"Nagpur\","
+ + "\"districtBranchID\":31,\"districtBranchName\":\"Kamptee\","
+ + "\"servicePointID\":41,\"servicePointName\":\"PHC Kamptee\"},"
+ + "\"benPhoneMaps\":[{\"phoneNo\":\"9999999999\"}],"
+ + "\"m_gender\":{\"genderID\":2,\"genderName\":\"Female\"}}";
+
+ @org.junit.jupiter.api.BeforeEach
+ void stubVisitCount() {
+ org.mockito.Mockito.when(benVisitDetailRepo
+ .getVisitCountForBeneficiary(org.mockito.ArgumentMatchers.anyLong())).thenReturn((short) 2);
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.save(org.mockito.ArgumentMatchers.any()))
+ .thenAnswer(invocation -> invocation.getArgument(0));
+ }
+
+ @Test
+ @DisplayName("createBenFlowRecord should store the flow record for a registered beneficiary")
+ void createFlowRecord_shouldStoreRecordForRegisteredBeneficiary() {
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.createBenFlowRecord(REGISTRATION, 11L, 9L));
+
+ org.mockito.ArgumentCaptor captor =
+ org.mockito.ArgumentCaptor.forClass(com.iemr.tm.data.benFlowStatus.BeneficiaryFlowStatus.class);
+ org.mockito.Mockito.verify(beneficiaryFlowStatusRepo).save(captor.capture());
+ com.iemr.tm.data.benFlowStatus.BeneficiaryFlowStatus stored = captor.getValue();
+ org.junit.jupiter.api.Assertions.assertEquals("Asha Devi", stored.getBenName());
+ org.junit.jupiter.api.Assertions.assertEquals(21, stored.getDistrictID());
+ org.junit.jupiter.api.Assertions.assertEquals(31, stored.getVillageID());
+ org.junit.jupiter.api.Assertions.assertEquals("PHC Kamptee", stored.getServicePointName());
+ org.junit.jupiter.api.Assertions.assertEquals("9999999999", stored.getPreferredPhoneNum());
+ org.junit.jupiter.api.Assertions.assertEquals((short) 3, stored.getBenVisitNo());
+ org.junit.jupiter.api.Assertions.assertEquals((short) 1, stored.getNurseFlag());
+ org.junit.jupiter.api.Assertions.assertTrue(stored.getAge().contains("years"));
+ org.junit.jupiter.api.Assertions.assertNotNull(stored.getRegistrationDate());
+ }
+
+ @Test
+ @DisplayName("createBenFlowRecord should report a beneficiary already in the nurse worklist")
+ void createFlowRecord_shouldReportBeneficiaryAlreadyInWorklist() {
+ org.springframework.test.util.ReflectionTestUtils.setField(service, "nurseWL", 10);
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.checkBenAlreadyInNurseWorkList(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any()))
+ .thenReturn(new java.util.ArrayList<>(java.util.Collections.singletonList(5L)));
+
+ org.junit.jupiter.api.Assertions.assertEquals(3, service.createBenFlowRecord(REGISTRATION, null, null));
+ }
+
+ @Test
+ @DisplayName("createBenFlowRecord should store a fresh record when the beneficiary is not in the worklist")
+ void createFlowRecord_shouldStoreFreshRecordWhenNotInWorklist() {
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.checkBenAlreadyInNurseWorkList(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any()))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.createBenFlowRecord(REGISTRATION, null, null));
+ }
+
+ @Test
+ @DisplayName("createBenFlowRecord should report a failure when the record could not be stored")
+ void createFlowRecord_shouldReportStoreFailure() {
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.save(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(null);
+
+ org.junit.jupiter.api.Assertions.assertEquals(0, service.createBenFlowRecord(REGISTRATION, 11L, 9L));
+ }
+
+ @Test
+ @DisplayName("createBenFlowRecord should describe a beneficiary aged in months")
+ void createFlowRecord_shouldDescribeAgeInMonths() {
+ String dob = java.time.LocalDate.now().minusMonths(4).toString() + "T00:00:00.000Z";
+
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.createBenFlowRecord(
+ REGISTRATION.replace("1990-05-14T00:00:00.000Z", dob), 11L, 9L));
+
+ org.mockito.ArgumentCaptor captor =
+ org.mockito.ArgumentCaptor.forClass(com.iemr.tm.data.benFlowStatus.BeneficiaryFlowStatus.class);
+ org.mockito.Mockito.verify(beneficiaryFlowStatusRepo).save(captor.capture());
+ org.junit.jupiter.api.Assertions.assertTrue(captor.getValue().getAge().contains("months"));
+ }
+
+ @Test
+ @DisplayName("createBenFlowRecord should describe a beneficiary aged in days")
+ void createFlowRecord_shouldDescribeAgeInDays() {
+ String dob = java.time.LocalDate.now().minusDays(9).toString() + "T00:00:00.000Z";
+
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.createBenFlowRecord(
+ REGISTRATION.replace("1990-05-14T00:00:00.000Z", dob), 11L, 9L));
+
+ org.mockito.ArgumentCaptor captor =
+ org.mockito.ArgumentCaptor.forClass(com.iemr.tm.data.benFlowStatus.BeneficiaryFlowStatus.class);
+ org.mockito.Mockito.verify(beneficiaryFlowStatusRepo).save(captor.capture());
+ org.junit.jupiter.api.Assertions.assertTrue(captor.getValue().getAge().contains("days"));
+ }
+
+ @Test
+ @DisplayName("createBenFlowRecord should use the beneficiary first name alone when there is no surname")
+ void createFlowRecord_shouldUseFirstNameAloneWithoutSurname() {
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.createBenFlowRecord(
+ REGISTRATION.replace(",\"lastName\":\"Devi\"", ""), 11L, 9L));
+
+ org.mockito.ArgumentCaptor captor =
+ org.mockito.ArgumentCaptor.forClass(com.iemr.tm.data.benFlowStatus.BeneficiaryFlowStatus.class);
+ org.mockito.Mockito.verify(beneficiaryFlowStatusRepo).save(captor.capture());
+ org.junit.jupiter.api.Assertions.assertEquals("Asha", captor.getValue().getBenName());
+ }
+
+ @Test
+ @DisplayName("createBenFlowRecord should take the gender from the master when the request omits it")
+ void createFlowRecord_shouldTakeGenderFromMaster() {
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.createBenFlowRecord(
+ REGISTRATION.replace("\"genderID\":2,\"genderName\":\"Female\",", ""), 11L, 9L));
+
+ org.mockito.ArgumentCaptor captor =
+ org.mockito.ArgumentCaptor.forClass(com.iemr.tm.data.benFlowStatus.BeneficiaryFlowStatus.class);
+ org.mockito.Mockito.verify(beneficiaryFlowStatusRepo).save(captor.capture());
+ org.junit.jupiter.api.Assertions.assertEquals("Female", captor.getValue().getGenderName());
+ }
+
+ @Test
+ @DisplayName("createBenFlowRecord should count the first visit for a new beneficiary")
+ void createFlowRecord_shouldCountFirstVisitForNewBeneficiary() {
+ org.mockito.Mockito.when(benVisitDetailRepo
+ .getVisitCountForBeneficiary(org.mockito.ArgumentMatchers.anyLong())).thenReturn(null);
+
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.createBenFlowRecord(REGISTRATION, 11L, 9L));
+
+ org.mockito.ArgumentCaptor captor =
+ org.mockito.ArgumentCaptor.forClass(com.iemr.tm.data.benFlowStatus.BeneficiaryFlowStatus.class);
+ org.mockito.Mockito.verify(beneficiaryFlowStatusRepo).save(captor.capture());
+ org.junit.jupiter.api.Assertions.assertEquals((short) 1, captor.getValue().getBenVisitNo());
+ }
+
+ @Test
+ @DisplayName("createBenFlowRecord should absorb a malformed registration request")
+ void createFlowRecord_shouldAbsorbMalformedRequest() {
+ org.junit.jupiter.api.Assertions.assertEquals(0, service.createBenFlowRecord("{}", 11L, 9L));
+ }
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("pharmacist flag carry over")
+ class PharmacistFlagTests {
+
+ @Test
+ @DisplayName("updateBenFlowAfterDocDataUpdate should keep a pharmacist flag already raised on the flow")
+ void updateAfterDocUpdate_shouldKeepRaisedPharmacistFlag() throws Exception {
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.getPharmaFlag(5L)).thenReturn((short) 1);
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.updateBenFlowStatusAfterDoctorActivity(
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyShort(),
+ org.mockito.ArgumentMatchers.anyShort(), org.mockito.ArgumentMatchers.anyShort(),
+ org.mockito.ArgumentMatchers.anyShort(), org.mockito.ArgumentMatchers.anyInt(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.anyShort(),
+ org.mockito.ArgumentMatchers.anyBoolean())).thenReturn(1);
+
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.updateBenFlowAfterDocDataUpdate(5L, 11L, 9L, 3L,
+ (short) 9, (short) 0, (short) 0, (short) 0, 0, null, (short) 0, Boolean.TRUE));
+
+ org.mockito.Mockito.verify(beneficiaryFlowStatusRepo).updateBenFlowStatusAfterDoctorActivity(
+ org.mockito.ArgumentMatchers.eq(5L), org.mockito.ArgumentMatchers.eq(11L),
+ org.mockito.ArgumentMatchers.eq(9L), org.mockito.ArgumentMatchers.anyShort(),
+ org.mockito.ArgumentMatchers.eq((short) 1), org.mockito.ArgumentMatchers.anyShort(),
+ org.mockito.ArgumentMatchers.anyShort(), org.mockito.ArgumentMatchers.anyInt(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.anyShort(),
+ org.mockito.ArgumentMatchers.anyBoolean());
+ }
+
+ @Test
+ @DisplayName("updateBenFlowAfterDocDataUpdate should raise the pharmacist flag from the request")
+ void updateAfterDocUpdate_shouldRaisePharmacistFlagFromRequest() throws Exception {
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.getPharmaFlag(5L)).thenReturn((short) 0);
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.updateBenFlowStatusAfterDoctorActivity(
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyShort(),
+ org.mockito.ArgumentMatchers.anyShort(), org.mockito.ArgumentMatchers.anyShort(),
+ org.mockito.ArgumentMatchers.anyShort(), org.mockito.ArgumentMatchers.anyInt(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.anyShort(),
+ org.mockito.ArgumentMatchers.anyBoolean())).thenReturn(1);
+
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.updateBenFlowAfterDocDataUpdate(5L, 11L, 9L, 3L,
+ (short) 9, (short) 1, (short) 0, (short) 0, 0, null, (short) 0, Boolean.TRUE));
+ }
+
+ @Test
+ @DisplayName("updateBenFlowAfterDocDataUpdate should surface a repository failure")
+ void updateAfterDocUpdate_shouldSurfaceRepositoryFailure() {
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.getPharmaFlag(5L))
+ .thenThrow(new RuntimeException("flow table locked"));
+
+ org.junit.jupiter.api.Assertions.assertThrows(Exception.class,
+ () -> service.updateBenFlowAfterDocDataUpdate(5L, 11L, 9L, 3L, (short) 9, (short) 0, (short) 0,
+ (short) 0, 0, null, (short) 0, Boolean.TRUE));
+ }
+
+ @Test
+ @DisplayName("updateBenFlowAfterDocDataUpdateTCSpecialist should keep a pharmacist flag already raised")
+ void updateAfterSpecialistUpdate_shouldKeepRaisedPharmacistFlag() throws Exception {
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.getPharmaFlag(5L)).thenReturn((short) 1);
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.updateBenFlowStatusAfterDoctorActivityTCSpecialist(
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyShort(),
+ org.mockito.ArgumentMatchers.anyShort(), org.mockito.ArgumentMatchers.anyShort(),
+ org.mockito.ArgumentMatchers.anyShort(), org.mockito.ArgumentMatchers.anyBoolean()))
+ .thenReturn(1);
+
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.updateBenFlowAfterDocDataUpdateTCSpecialist(5L,
+ 11L, 9L, 3L, (short) 0, (short) 0, (short) 0, (short) 9, 0, null, (short) 0, Boolean.TRUE));
+ }
+
+ @Test
+ @DisplayName("updateBenFlowAfterDocDataUpdateTCSpecialist should surface a repository failure")
+ void updateAfterSpecialistUpdate_shouldSurfaceRepositoryFailure() {
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.getPharmaFlag(5L))
+ .thenThrow(new RuntimeException("flow table locked"));
+
+ org.junit.jupiter.api.Assertions.assertThrows(Exception.class,
+ () -> service.updateBenFlowAfterDocDataUpdateTCSpecialist(5L, 11L, 9L, 3L, (short) 0, (short) 0,
+ (short) 0, (short) 9, 0, null, (short) 0, Boolean.TRUE));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/cancerScreening/CSCarestreamServiceImplTest.java b/src/test/java/com/iemr/tm/service/cancerScreening/CSCarestreamServiceImplTest.java
new file mode 100644
index 00000000..72aabd44
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/cancerScreening/CSCarestreamServiceImplTest.java
@@ -0,0 +1,53 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.cancerScreening;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.utils.CookieUtil;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("CSCarestreamServiceImpl Test Suite")
+class CSCarestreamServiceImplTest {
+
+ @Mock
+ private CookieUtil cookieUtil;
+
+ @InjectMocks
+ private CSCarestreamServiceImpl service;
+
+ @Test
+ @DisplayName("createMamographyRequest should answer for a well formed request")
+ void createMamographyRequest_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.createMamographyRequest(new java.util.ArrayList<>(), 11L, 11L, "{}"));
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/cancerScreening/CSDoctorServiceImplTest.java b/src/test/java/com/iemr/tm/service/cancerScreening/CSDoctorServiceImplTest.java
new file mode 100644
index 00000000..02682cdf
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/cancerScreening/CSDoctorServiceImplTest.java
@@ -0,0 +1,77 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.cancerScreening;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.doctor.CancerDiagnosisRepo;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("CSDoctorServiceImpl Test Suite")
+class CSDoctorServiceImplTest {
+
+ @Mock
+ private CancerDiagnosisRepo cancerDiagnosisRepo;
+
+ @InjectMocks
+ private CSDoctorServiceImpl service;
+
+ @Test
+ @DisplayName("saveCancerDiagnosisData should answer for a well formed request")
+ void saveCancerDiagnosisData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.saveCancerDiagnosisData(new com.iemr.tm.data.doctor.CancerDiagnosis()));
+ }
+
+ @Test
+ @DisplayName("getCancerDiagnosisObj should answer for a well formed request")
+ void getCancerDiagnosisObj_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getCancerDiagnosisObj(new com.iemr.tm.data.doctor.CancerDiagnosis()));
+ }
+
+ @Test
+ @DisplayName("getBenDoctorEnteredDataForCaseSheet should answer for a well formed request")
+ void getBenDoctorEnteredDataForCaseSheet_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenDoctorEnteredDataForCaseSheet(11L, 11L));
+ }
+
+ @Test
+ @DisplayName("getBenCancerDiagnosisData should answer for a well formed request")
+ void getBenCancerDiagnosisData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenCancerDiagnosisData(11L, 11L));
+ }
+
+ @Test
+ @DisplayName("updateCancerDiagnosisDetailsByDoctor should answer for a well formed request")
+ void updateCancerDiagnosisDetailsByDoctor_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateCancerDiagnosisDetailsByDoctor(new com.iemr.tm.data.doctor.CancerDiagnosis()));
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/cancerScreening/CSNurseServiceImplTest.java b/src/test/java/com/iemr/tm/service/cancerScreening/CSNurseServiceImplTest.java
new file mode 100644
index 00000000..5de31bd4
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/cancerScreening/CSNurseServiceImplTest.java
@@ -0,0 +1,929 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.cancerScreening;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.data.nurse.BenCancerVitalDetail;
+import com.iemr.tm.data.nurse.BeneficiaryVisitDetail;
+import com.iemr.tm.data.doctor.CancerAbdominalExamination;
+import com.iemr.tm.data.doctor.CancerBreastExamination;
+import com.iemr.tm.data.doctor.CancerExaminationImageAnnotation;
+import com.iemr.tm.data.doctor.CancerGynecologicalExamination;
+import com.iemr.tm.data.doctor.CancerLymphNodeDetails;
+import com.iemr.tm.data.doctor.CancerOralExamination;
+import com.iemr.tm.data.doctor.CancerSignAndSymptoms;
+import com.iemr.tm.data.doctor.WrapperCancerExamImgAnotasn;
+import com.iemr.tm.data.nurse.BenFamilyCancerHistory;
+import com.iemr.tm.data.nurse.BenObstetricCancerHistory;
+import com.iemr.tm.data.nurse.BenPersonalCancerDietHistory;
+import com.iemr.tm.data.nurse.BenPersonalCancerHistory;
+import com.iemr.tm.repo.nurse.BenCancerVitalDetailRepo;
+import com.iemr.tm.repo.nurse.BenVisitDetailRepo;
+import com.iemr.tm.repo.doctor.CancerAbdominalExaminationRepo;
+import com.iemr.tm.repo.doctor.CancerBreastExaminationRepo;
+import com.iemr.tm.repo.doctor.CancerExaminationImageAnnotationRepo;
+import com.iemr.tm.repo.doctor.CancerGynecologicalExaminationRepo;
+import com.iemr.tm.repo.doctor.CancerLymphNodeExaminationRepo;
+import com.iemr.tm.repo.doctor.CancerOralExaminationRepo;
+import com.iemr.tm.repo.doctor.CancerSignAndSymptomsRepo;
+import com.iemr.tm.repo.nurse.BenFamilyCancerHistoryRepo;
+import com.iemr.tm.repo.nurse.BenObstetricCancerHistoryRepo;
+import com.iemr.tm.repo.nurse.BenPersonalCancerDietHistoryRepo;
+import com.iemr.tm.repo.nurse.BenPersonalCancerHistoryRepo;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("CSNurseServiceImpl Test Suite")
+class CSNurseServiceImplTest {
+
+ private static final Long BEN_REG_ID = 11L;
+ private static final Long VISIT_ID = 3L;
+ private static final Long VISIT_CODE = 22L;
+
+ @Mock
+ private BenFamilyCancerHistoryRepo benFamilyCancerHistoryRepo;
+ @Mock
+ private BenPersonalCancerHistoryRepo benPersonalCancerHistoryRepo;
+ @Mock
+ private BenPersonalCancerDietHistoryRepo benPersonalCancerDietHistoryRepo;
+ @Mock
+ private BenObstetricCancerHistoryRepo benObstetricCancerHistoryRepo;
+ @Mock
+ private BenCancerVitalDetailRepo benCancerVitalDetailRepo;
+ @Mock
+ private BenVisitDetailRepo benVisitDetailRepo;
+ @Mock
+ private CancerAbdominalExaminationRepo cancerAbdominalExaminationRepo;
+ @Mock
+ private CancerBreastExaminationRepo cancerBreastExaminationRepo;
+ @Mock
+ private CancerGynecologicalExaminationRepo cancerGynecologicalExaminationRepo;
+ @Mock
+ private CancerSignAndSymptomsRepo cancerSignAndSymptomsRepo;
+ @Mock
+ private CancerLymphNodeExaminationRepo cancerLymphNodeExaminationRepo;
+ @Mock
+ private CancerOralExaminationRepo cancerOralExaminationRepo;
+ @Mock
+ private CancerExaminationImageAnnotationRepo cancerExaminationImageAnnotationRepo;
+
+ @InjectMocks
+ private CSNurseServiceImpl service;
+
+ /** One already-processed row and one fresh row, as a re-edited visit returns. */
+ private ArrayList statuses() {
+ ArrayList rows = new ArrayList<>();
+ rows.add(new Object[] { 1L, "P" });
+ rows.add(new Object[] { 2L, "N" });
+ return rows;
+ }
+
+ private static org.mockito.stubbing.Answer echoList() {
+ return invocation -> invocation.getArgument(0);
+ }
+
+ private BenFamilyCancerHistory familyHistory(List familyMembers) {
+ BenFamilyCancerHistory history = new BenFamilyCancerHistory();
+ history.setBeneficiaryRegID(BEN_REG_ID);
+ history.setVisitCode(VISIT_CODE);
+ history.setFamilyMemberList(familyMembers);
+ return history;
+ }
+
+ @Nested
+ @DisplayName("history saves")
+ class HistorySaveTests {
+
+ @Test
+ @DisplayName("saveBenFamilyCancerHistory should flatten the family member list before storing")
+ void saveFamilyHistory_shouldFlattenFamilyMembers() {
+ BenFamilyCancerHistory history = familyHistory(Arrays.asList("Mother", "Father"));
+ when(benFamilyCancerHistoryRepo.saveAll(any())).thenAnswer(echoList());
+
+ assertEquals(1, service.saveBenFamilyCancerHistory(Collections.singletonList(history)));
+ assertEquals("Mother,Father", history.getFamilyMember());
+ }
+
+ @Test
+ @DisplayName("saveBenFamilyCancerHistory should skip an entry without any family member")
+ void saveFamilyHistory_shouldSkipEntryWithoutFamilyMember() {
+ when(benFamilyCancerHistoryRepo.saveAll(any())).thenAnswer(echoList());
+
+ assertEquals(1, service.saveBenFamilyCancerHistory(
+ Collections.singletonList(familyHistory(Collections.emptyList()))));
+ }
+
+ @Test
+ @DisplayName("saveBenPersonalCancerHistory should flatten the tobacco product list before storing")
+ void savePersonalHistory_shouldFlattenTobaccoProducts() {
+ BenPersonalCancerHistory history = new BenPersonalCancerHistory();
+ history.setTypeOfTobaccoProductList(Arrays.asList("Cigarette", "Beedi"));
+ BenPersonalCancerHistory saved = new BenPersonalCancerHistory();
+ saved.setID(4L);
+ when(benPersonalCancerHistoryRepo.save(history)).thenReturn(saved);
+
+ assertEquals(4L, service.saveBenPersonalCancerHistory(history));
+ assertEquals("Cigarette,Beedi,", history.getTypeOfTobaccoProduct());
+ }
+
+ @Test
+ @DisplayName("saveBenPersonalCancerHistory should return null when nothing was stored")
+ void savePersonalHistory_shouldReturnNullWhenNothingStored() {
+ BenPersonalCancerHistory history = new BenPersonalCancerHistory();
+ when(benPersonalCancerHistoryRepo.save(history)).thenReturn(null);
+
+ assertNull(service.saveBenPersonalCancerHistory(history));
+ }
+
+ @Test
+ @DisplayName("saveBenPersonalCancerDietHistory should flatten the oil list before storing")
+ void savePersonalDietHistory_shouldFlattenOilList() {
+ BenPersonalCancerDietHistory history = new BenPersonalCancerDietHistory();
+ history.setTypeOfOilConsumedList(Arrays.asList("Mustard", "Sunflower"));
+ BenPersonalCancerDietHistory saved = new BenPersonalCancerDietHistory();
+ saved.setID(4L);
+ when(benPersonalCancerDietHistoryRepo.save(history)).thenReturn(saved);
+
+ assertEquals(4L, service.saveBenPersonalCancerDietHistory(history));
+ assertEquals("Mustard,Sunflower,", history.getTypeOfOilConsumed());
+ }
+
+ @Test
+ @DisplayName("saveBenPersonalCancerDietHistory should return null when nothing was stored")
+ void savePersonalDietHistory_shouldReturnNullWhenNothingStored() {
+ BenPersonalCancerDietHistory history = new BenPersonalCancerDietHistory();
+ when(benPersonalCancerDietHistoryRepo.save(history)).thenReturn(null);
+
+ assertNull(service.saveBenPersonalCancerDietHistory(history));
+ }
+
+ @Test
+ @DisplayName("saveBenObstetricCancerHistory should return the stored row id")
+ void saveObstetricHistory_shouldReturnStoredId() {
+ BenObstetricCancerHistory history = new BenObstetricCancerHistory();
+ BenObstetricCancerHistory saved = new BenObstetricCancerHistory();
+ saved.setID(4L);
+ when(benObstetricCancerHistoryRepo.save(history)).thenReturn(saved);
+
+ assertEquals(4L, service.saveBenObstetricCancerHistory(history));
+ }
+
+ @Test
+ @DisplayName("saveBenObstetricCancerHistory should return null when nothing was stored")
+ void saveObstetricHistory_shouldReturnNullWhenNothingStored() {
+ BenObstetricCancerHistory history = new BenObstetricCancerHistory();
+ when(benObstetricCancerHistoryRepo.save(history)).thenReturn(null);
+
+ assertNull(service.saveBenObstetricCancerHistory(history));
+ }
+
+ @Test
+ @DisplayName("saveBenVitalDetail should return the stored row id")
+ void saveVitalDetail_shouldReturnStoredId() {
+ BenCancerVitalDetail vital = new BenCancerVitalDetail();
+ BenCancerVitalDetail saved = new BenCancerVitalDetail();
+ saved.setID(4L);
+ when(benCancerVitalDetailRepo.save(vital)).thenReturn(saved);
+
+ assertEquals(4L, service.saveBenVitalDetail(vital));
+ }
+
+ @Test
+ @DisplayName("saveBenVitalDetail should return null when nothing was stored")
+ void saveVitalDetail_shouldReturnNullWhenNothingStored() {
+ BenCancerVitalDetail vital = new BenCancerVitalDetail();
+ when(benCancerVitalDetailRepo.save(vital)).thenReturn(null);
+
+ assertNull(service.saveBenVitalDetail(vital));
+ }
+ }
+
+ @Nested
+ @DisplayName("examination saves")
+ class ExaminationSaveTests {
+
+ @Test
+ @DisplayName("saveLymphNodeDetails should stamp the visit onto every lymph node row")
+ void saveLymphNodeDetails_shouldStampVisitOntoRows() {
+ CancerLymphNodeDetails node = new CancerLymphNodeDetails();
+ node.setID(4L);
+ when(cancerLymphNodeExaminationRepo.saveAll(any())).thenAnswer(echoList());
+
+ assertEquals(4L, service.saveLymphNodeDetails(Collections.singletonList(node), VISIT_ID, VISIT_CODE));
+ assertEquals(VISIT_ID, node.getBenVisitID());
+ assertEquals(VISIT_CODE, node.getVisitCode());
+ }
+
+ @Test
+ @DisplayName("saveLymphNodeDetails should return null when nothing was stored")
+ void saveLymphNodeDetails_shouldReturnNullWhenNothingStored() {
+ when(cancerLymphNodeExaminationRepo.saveAll(any())).thenReturn(new ArrayList<>());
+
+ assertNull(service.saveLymphNodeDetails(Collections.singletonList(new CancerLymphNodeDetails()), VISIT_ID,
+ VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("saveCancerSignAndSymptomsData should stamp the visit before storing")
+ void saveSignAndSymptoms_shouldStampVisitBeforeStoring() {
+ CancerSignAndSymptoms symptoms = new CancerSignAndSymptoms();
+ CancerSignAndSymptoms saved = new CancerSignAndSymptoms();
+ saved.setID(4L);
+ when(cancerSignAndSymptomsRepo.save(symptoms)).thenReturn(saved);
+
+ assertEquals(4L, service.saveCancerSignAndSymptomsData(symptoms, VISIT_ID, VISIT_CODE));
+ assertEquals(VISIT_ID, symptoms.getBenVisitID());
+ }
+
+ @Test
+ @DisplayName("saveCancerSignAndSymptomsData should return the stored row id")
+ void saveSignAndSymptoms_shouldReturnStoredId() {
+ CancerSignAndSymptoms symptoms = new CancerSignAndSymptoms();
+ CancerSignAndSymptoms saved = new CancerSignAndSymptoms();
+ saved.setID(4L);
+ when(cancerSignAndSymptomsRepo.save(symptoms)).thenReturn(saved);
+
+ assertEquals(4L, service.saveCancerSignAndSymptomsData(symptoms));
+ }
+
+ @Test
+ @DisplayName("saveCancerSignAndSymptomsData should return null when nothing was stored")
+ void saveSignAndSymptoms_shouldReturnNullWhenNothingStored() {
+ CancerSignAndSymptoms symptoms = new CancerSignAndSymptoms();
+ when(cancerSignAndSymptomsRepo.save(symptoms)).thenReturn(null);
+
+ assertNull(service.saveCancerSignAndSymptomsData(symptoms));
+ }
+
+ @Test
+ @DisplayName("saveCancerOralExaminationData should return the stored row id")
+ void saveOralExamination_shouldReturnStoredId() {
+ CancerOralExamination examination = new CancerOralExamination();
+ CancerOralExamination saved = new CancerOralExamination();
+ saved.setID(4L);
+ when(cancerOralExaminationRepo.save(examination)).thenReturn(saved);
+
+ assertEquals(4L, service.saveCancerOralExaminationData(examination));
+ }
+
+ @Test
+ @DisplayName("saveCancerOralExaminationData should return null when nothing was stored")
+ void saveOralExamination_shouldReturnNullWhenNothingStored() {
+ CancerOralExamination examination = new CancerOralExamination();
+ when(cancerOralExaminationRepo.save(examination)).thenReturn(null);
+
+ assertNull(service.saveCancerOralExaminationData(examination));
+ }
+
+ @Test
+ @DisplayName("saveCancerBreastExaminationData should return the stored row id")
+ void saveBreastExamination_shouldReturnStoredId() {
+ CancerBreastExamination examination = new CancerBreastExamination();
+ CancerBreastExamination saved = new CancerBreastExamination();
+ saved.setID(4L);
+ when(cancerBreastExaminationRepo.save(examination)).thenReturn(saved);
+
+ assertEquals(4L, service.saveCancerBreastExaminationData(examination));
+ }
+
+ @Test
+ @DisplayName("saveCancerBreastExaminationData should return null when nothing was stored")
+ void saveBreastExamination_shouldReturnNullWhenNothingStored() {
+ CancerBreastExamination examination = new CancerBreastExamination();
+ when(cancerBreastExaminationRepo.save(examination)).thenReturn(null);
+
+ assertNull(service.saveCancerBreastExaminationData(examination));
+ }
+
+ @Test
+ @DisplayName("saveCancerAbdominalExaminationData should return the stored row id")
+ void saveAbdominalExamination_shouldReturnStoredId() {
+ CancerAbdominalExamination examination = new CancerAbdominalExamination();
+ CancerAbdominalExamination saved = new CancerAbdominalExamination();
+ saved.setID(4L);
+ when(cancerAbdominalExaminationRepo.save(examination)).thenReturn(saved);
+
+ assertEquals(4L, service.saveCancerAbdominalExaminationData(examination));
+ }
+
+ @Test
+ @DisplayName("saveCancerAbdominalExaminationData should return null when nothing was stored")
+ void saveAbdominalExamination_shouldReturnNullWhenNothingStored() {
+ CancerAbdominalExamination examination = new CancerAbdominalExamination();
+ when(cancerAbdominalExaminationRepo.save(examination)).thenReturn(null);
+
+ assertNull(service.saveCancerAbdominalExaminationData(examination));
+ }
+
+ @Test
+ @DisplayName("saveCancerGynecologicalExaminationData should return the stored row id")
+ void saveGynecologicalExamination_shouldReturnStoredId() {
+ CancerGynecologicalExamination examination = new CancerGynecologicalExamination();
+ CancerGynecologicalExamination saved = new CancerGynecologicalExamination();
+ saved.setID(4L);
+ when(cancerGynecologicalExaminationRepo.save(examination)).thenReturn(saved);
+
+ assertEquals(4L, service.saveCancerGynecologicalExaminationData(examination));
+ }
+
+ @Test
+ @DisplayName("saveDocExaminationImageAnnotation should expand every marker of the annotation")
+ void saveImageAnnotation_shouldExpandMarkers() {
+ WrapperCancerExamImgAnotasn wrapper = new WrapperCancerExamImgAnotasn();
+ wrapper.setBeneficiaryRegID(BEN_REG_ID);
+ wrapper.setVisitID(VISIT_ID);
+ ArrayList> markers = new ArrayList<>();
+ Map marker = new HashMap<>();
+ marker.put("xCord", 10d);
+ marker.put("yCord", 20d);
+ marker.put("point", 1d);
+ marker.put("description", "Lesion");
+ markers.add(marker);
+ wrapper.setMarkers(markers);
+ CancerExaminationImageAnnotation saved = new CancerExaminationImageAnnotation();
+ saved.setID(4L);
+ when(cancerExaminationImageAnnotationRepo.saveAll(any()))
+ .thenReturn(Collections.singletonList(saved));
+
+ assertNotNull(service.saveDocExaminationImageAnnotation(Collections.singletonList(wrapper), VISIT_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getCancerExaminationImageAnnotationList should return nothing for an annotation without markers")
+ void getImageAnnotationList_shouldReturnNothingWithoutMarkers() {
+ WrapperCancerExamImgAnotasn wrapper = new WrapperCancerExamImgAnotasn();
+
+ assertTrue(service.getCancerExaminationImageAnnotationList(Collections.singletonList(wrapper), VISIT_CODE)
+ .isEmpty());
+ }
+ }
+
+ @Nested
+ @DisplayName("per visit lookups")
+ class PerVisitLookupTests {
+
+ @Test
+ @DisplayName("getBenFamilyHisData should expand the comma separated family members")
+ void getFamilyHistory_shouldExpandFamilyMembers() {
+ BenFamilyCancerHistory stored = new BenFamilyCancerHistory();
+ stored.setFamilyMember("Mother,Father");
+ when(benFamilyCancerHistoryRepo.getBenFamilyHistory(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(new ArrayList<>(Collections.singletonList(stored)));
+
+ List result = service.getBenFamilyHisData(BEN_REG_ID, VISIT_CODE);
+
+ assertEquals(2, result.get(0).getFamilyMemberList().size());
+ }
+
+ @Test
+ @DisplayName("getBenFamilyHisData should leave the family member list empty when none is stored")
+ void getFamilyHistory_shouldLeaveListEmptyWhenNoneStored() {
+ when(benFamilyCancerHistoryRepo.getBenFamilyHistory(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(new ArrayList<>(Collections.singletonList(new BenFamilyCancerHistory())));
+
+ assertTrue(service.getBenFamilyHisData(BEN_REG_ID, VISIT_CODE).get(0).getFamilyMemberList().isEmpty());
+ }
+
+ @Test
+ @DisplayName("getBenObstetricDetailsData should delegate to the obstetric history repository")
+ void getObstetricDetails_shouldDelegateToRepo() {
+ BenObstetricCancerHistory stored = new BenObstetricCancerHistory();
+ when(benObstetricCancerHistoryRepo.getBenObstetricCancerHistory(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(stored);
+
+ assertEquals(stored, service.getBenObstetricDetailsData(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getBenPersonalCancerHistoryData should expand the comma separated tobacco products")
+ void getPersonalHistory_shouldExpandTobaccoProducts() {
+ BenPersonalCancerHistory stored = new BenPersonalCancerHistory();
+ stored.setTypeOfTobaccoProduct("Cigarette,Beedi");
+ when(benPersonalCancerHistoryRepo.getBenPersonalHistory(BEN_REG_ID, VISIT_CODE)).thenReturn(stored);
+
+ BenPersonalCancerHistory result = service.getBenPersonalCancerHistoryData(BEN_REG_ID, VISIT_CODE);
+
+ assertEquals(2, result.getTypeOfTobaccoProductList().size());
+ }
+
+ @Test
+ @DisplayName("getBenPersonalCancerHistoryData should return null when the visit has no personal history")
+ void getPersonalHistory_shouldReturnNullWithoutStoredHistory() {
+ when(benPersonalCancerHistoryRepo.getBenPersonalHistory(BEN_REG_ID, VISIT_CODE)).thenReturn(null);
+
+ assertNull(service.getBenPersonalCancerHistoryData(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getBenPersonalCancerDietHistoryData should expand the comma separated oil list")
+ void getPersonalDietHistory_shouldExpandOilList() {
+ BenPersonalCancerDietHistory stored = new BenPersonalCancerDietHistory();
+ stored.setTypeOfOilConsumed("Mustard,Sunflower");
+ when(benPersonalCancerDietHistoryRepo.getBenPersonaDietHistory(BEN_REG_ID, VISIT_CODE)).thenReturn(stored);
+
+ BenPersonalCancerDietHistory result = service.getBenPersonalCancerDietHistoryData(BEN_REG_ID, VISIT_CODE);
+
+ assertEquals(2, result.getTypeOfOilConsumedList().size());
+ }
+
+ @Test
+ @DisplayName("getBenPersonalCancerDietHistoryData should return null when the visit has no diet history")
+ void getPersonalDietHistory_shouldReturnNullWithoutStoredHistory() {
+ when(benPersonalCancerDietHistoryRepo.getBenPersonaDietHistory(BEN_REG_ID, VISIT_CODE)).thenReturn(null);
+
+ assertNull(service.getBenPersonalCancerDietHistoryData(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getBenCancerVitalDetailData should delegate to the cancer vitals repository")
+ void getVitalDetail_shouldDelegateToRepo() {
+ BenCancerVitalDetail stored = new BenCancerVitalDetail();
+ when(benCancerVitalDetailRepo.getBenCancerVitalDetail(BEN_REG_ID, VISIT_CODE)).thenReturn(stored);
+
+ assertEquals(stored, service.getBenCancerVitalDetailData(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getBenCancerAbdominalExaminationData should delegate to the abdominal repository")
+ void getAbdominalExamination_shouldDelegateToRepo() {
+ CancerAbdominalExamination stored = new CancerAbdominalExamination();
+ when(cancerAbdominalExaminationRepo.getBenCancerAbdominalExaminationDetails(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(stored);
+
+ assertEquals(stored, service.getBenCancerAbdominalExaminationData(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getBenCancerBreastExaminationData should delegate to the breast repository")
+ void getBreastExamination_shouldDelegateToRepo() {
+ CancerBreastExamination stored = new CancerBreastExamination();
+ when(cancerBreastExaminationRepo.getBenCancerBreastExaminationDetails(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(stored);
+
+ assertEquals(stored, service.getBenCancerBreastExaminationData(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getBenCancerGynecologicalExaminationData should delegate to the gynecological repository")
+ void getGynecologicalExamination_shouldDelegateToRepo() {
+ CancerGynecologicalExamination stored = new CancerGynecologicalExamination();
+ when(cancerGynecologicalExaminationRepo.getBenCancerGynecologicalExaminationDetails(BEN_REG_ID,
+ VISIT_CODE)).thenReturn(stored);
+
+ assertEquals(stored, service.getBenCancerGynecologicalExaminationData(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getBenCancerSignAndSymptomsData should delegate to the sign and symptoms repository")
+ void getSignAndSymptoms_shouldDelegateToRepo() {
+ CancerSignAndSymptoms stored = new CancerSignAndSymptoms();
+ when(cancerSignAndSymptomsRepo.getBenCancerSignAndSymptomsDetails(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(stored);
+
+ assertEquals(stored, service.getBenCancerSignAndSymptomsData(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getBenCancerLymphNodeDetailsData should delegate to the lymph node repository")
+ void getLymphNodeDetails_shouldDelegateToRepo() {
+ List stored = Collections.singletonList(new CancerLymphNodeDetails());
+ when(cancerLymphNodeExaminationRepo.getBenCancerLymphNodeDetails(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(stored);
+
+ assertEquals(stored, service.getBenCancerLymphNodeDetailsData(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getBenCancerOralExaminationData should delegate to the oral repository")
+ void getOralExamination_shouldDelegateToRepo() {
+ CancerOralExamination stored = new CancerOralExamination();
+ when(cancerOralExaminationRepo.getBenCancerOralExaminationDetails(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(stored);
+
+ assertEquals(stored, service.getBenCancerOralExaminationData(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getCancerExaminationImageAnnotationCasesheet should group the stored markers by image")
+ void getImageAnnotationCasesheet_shouldGroupMarkersByImage() {
+ CancerExaminationImageAnnotation stored = new CancerExaminationImageAnnotation();
+ stored.setBeneficiaryRegID(BEN_REG_ID);
+ stored.setVisitCode(VISIT_CODE);
+ stored.setCancerImageID(1);
+ stored.setxCoordinate(10);
+ stored.setyCoordinate(20);
+ stored.setPoint(1);
+ when(cancerExaminationImageAnnotationRepo.getCancerExaminationImageAnnotationList(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(Collections.singletonList(stored));
+
+ assertNotNull(service.getCancerExaminationImageAnnotationCasesheet(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getCancerExaminationImageAnnotationCasesheet should return nothing when no annotation is stored")
+ void getImageAnnotationCasesheet_shouldReturnNothingWhenNoneStored() {
+ when(cancerExaminationImageAnnotationRepo.getCancerExaminationImageAnnotationList(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(new ArrayList<>());
+
+ assertTrue(service.getCancerExaminationImageAnnotationCasesheet(BEN_REG_ID, VISIT_CODE).isEmpty());
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryVisitDetails should build the visit from the stored row")
+ void getBeneficiaryVisitDetails_shouldBuildVisitFromRow() {
+ ArrayList rows = new ArrayList<>();
+ rows.add(new Object[40]);
+ when(benVisitDetailRepo.getBeneficiaryVisitDetails(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(new ArrayList<>(rows));
+
+ assertNotNull(service.getBeneficiaryVisitDetails(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getBenNurseDataForCaseSheet should assemble every nurse captured section")
+ void getNurseDataForCaseSheet_shouldAssembleEverySection() {
+ when(benFamilyCancerHistoryRepo.getBenFamilyHistory(BEN_REG_ID, VISIT_CODE)).thenReturn(new ArrayList<>());
+ when(benVisitDetailRepo.getBeneficiaryVisitDetails(BEN_REG_ID, VISIT_CODE)).thenReturn(new ArrayList<>());
+
+ Map result = service.getBenNurseDataForCaseSheet(BEN_REG_ID, VISIT_CODE);
+
+ assertTrue(result.containsKey("benVisitDetail"));
+ assertTrue(result.containsKey("oralExamination"));
+ }
+ }
+
+ @Nested
+ @DisplayName("cross visit history reports")
+ class HistoryReportTests {
+
+ private ArrayList oneEmptyRow() {
+ ArrayList rows = new ArrayList<>();
+ rows.add(new Object[40]);
+ return rows;
+ }
+
+ @Test
+ @DisplayName("getBenCancerFamilyHistory should render the stored rows with the report columns")
+ void getFamilyHistoryReport_shouldRenderRowsWithColumns() {
+ when(benFamilyCancerHistoryRepo.getBenCancerFamilyHistory(BEN_REG_ID)).thenReturn(oneEmptyRow());
+
+ assertTrue(service.getBenCancerFamilyHistory(BEN_REG_ID).contains("\"columns\""));
+ }
+
+ @Test
+ @DisplayName("getBenCancerFamilyHistory should render only the columns when nothing is stored")
+ void getFamilyHistoryReport_shouldRenderColumnsOnlyWhenEmpty() {
+ when(benFamilyCancerHistoryRepo.getBenCancerFamilyHistory(BEN_REG_ID)).thenReturn(null);
+
+ assertTrue(service.getBenCancerFamilyHistory(BEN_REG_ID).contains("\"columns\""));
+ }
+
+ @Test
+ @DisplayName("getBenCancerPersonalHistory should render the stored rows with the report columns")
+ void getPersonalHistoryReport_shouldRenderRowsWithColumns() {
+ when(benPersonalCancerHistoryRepo.getBenPersonalHistory(BEN_REG_ID)).thenReturn(oneEmptyRow());
+
+ assertTrue(service.getBenCancerPersonalHistory(BEN_REG_ID).contains("\"columns\""));
+ }
+
+ @Test
+ @DisplayName("getBenCancerPersonalDietHistory should render the stored rows with the report columns")
+ void getPersonalDietHistoryReport_shouldRenderRowsWithColumns() {
+ when(benPersonalCancerDietHistoryRepo.getBenPersonaDietHistory(BEN_REG_ID)).thenReturn(oneEmptyRow());
+
+ assertTrue(service.getBenCancerPersonalDietHistory(BEN_REG_ID).contains("\"columns\""));
+ }
+
+ @Test
+ @DisplayName("getBenCancerObstetricHistory should render the stored rows with the report columns")
+ void getObstetricHistoryReport_shouldRenderRowsWithColumns() {
+ when(benObstetricCancerHistoryRepo.getBenObstetricCancerHistoryData(BEN_REG_ID))
+ .thenReturn(oneEmptyRow());
+
+ assertTrue(service.getBenCancerObstetricHistory(BEN_REG_ID).contains("\"columns\""));
+ }
+ }
+
+ @Nested
+ @DisplayName("history and examination updates")
+ class UpdateTests {
+
+ @Test
+ @DisplayName("updateBeneficiaryFamilyCancerHistory should soft delete the stored rows before writing")
+ void updateFamilyHistory_shouldSoftDeleteBeforeWriting() {
+ BenFamilyCancerHistory history = familyHistory(Arrays.asList("Mother"));
+ when(benFamilyCancerHistoryRepo.getFamilyCancerHistoryStatus(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(statuses());
+ when(benFamilyCancerHistoryRepo.deleteExistingFamilyRecord(anyLong(), anyString())).thenReturn(1);
+ when(benFamilyCancerHistoryRepo.saveAll(any())).thenAnswer(echoList());
+
+ assertEquals(1, service.updateBeneficiaryFamilyCancerHistory(new ArrayList<>(
+ Collections.singletonList(history))));
+ verify(benFamilyCancerHistoryRepo).deleteExistingFamilyRecord(1L, "U");
+ verify(benFamilyCancerHistoryRepo).deleteExistingFamilyRecord(2L, "N");
+ }
+
+ @Test
+ @DisplayName("updateBenObstetricCancerHistory should read the processed flag before updating")
+ void updateObstetricHistory_shouldReadProcessedFlag() {
+ BenObstetricCancerHistory history = new BenObstetricCancerHistory();
+ history.setBeneficiaryRegID(BEN_REG_ID);
+ history.setVisitCode(VISIT_CODE);
+ when(benObstetricCancerHistoryRepo.getObstetricCancerHistoryStatus(BEN_REG_ID, VISIT_CODE)).thenReturn("P");
+
+ assertEquals(0, service.updateBenObstetricCancerHistory(history));
+ }
+
+ @Test
+ @DisplayName("updateBenPersonalCancerHistory should read the processed flag before updating")
+ void updatePersonalHistory_shouldReadProcessedFlag() {
+ BenPersonalCancerHistory history = new BenPersonalCancerHistory();
+ history.setBeneficiaryRegID(BEN_REG_ID);
+ history.setVisitCode(VISIT_CODE);
+ when(benPersonalCancerHistoryRepo.getPersonalCancerHistoryStatus(BEN_REG_ID, VISIT_CODE)).thenReturn("P");
+
+ assertEquals(0, service.updateBenPersonalCancerHistory(history));
+ }
+
+ @Test
+ @DisplayName("updateBenPersonalCancerDietHistory should read the processed flag before updating")
+ void updatePersonalDietHistory_shouldReadProcessedFlag() {
+ BenPersonalCancerDietHistory history = new BenPersonalCancerDietHistory();
+ history.setBeneficiaryRegID(BEN_REG_ID);
+ history.setVisitCode(VISIT_CODE);
+ when(benPersonalCancerDietHistoryRepo.getPersonalCancerDietHistoryStatus(BEN_REG_ID, VISIT_CODE)).thenReturn("P");
+
+ assertEquals(0, service.updateBenPersonalCancerDietHistory(history));
+ }
+
+ @Test
+ @DisplayName("updateBenVitalDetail should read the processed flag before updating")
+ void updateVitalDetail_shouldReadProcessedFlag() {
+ BenCancerVitalDetail vital = new BenCancerVitalDetail();
+ vital.setBeneficiaryRegID(BEN_REG_ID);
+ vital.setVisitCode(VISIT_CODE);
+ when(benCancerVitalDetailRepo.getCancerVitalStatus(BEN_REG_ID, VISIT_CODE)).thenReturn("P");
+
+ assertEquals(0, service.updateBenVitalDetail(vital));
+ }
+
+ @Test
+ @DisplayName("updateSignAndSymptomsExaminationDetails should read the processed flag before updating")
+ void updateSignAndSymptoms_shouldReadProcessedFlag() {
+ CancerSignAndSymptoms symptoms = new CancerSignAndSymptoms();
+ symptoms.setBeneficiaryRegID(BEN_REG_ID);
+ symptoms.setVisitCode(VISIT_CODE);
+ when(cancerSignAndSymptomsRepo.getCancerSignAndSymptomsStatus(BEN_REG_ID, VISIT_CODE)).thenReturn("P");
+
+ assertEquals(0, service.updateSignAndSymptomsExaminationDetails(symptoms));
+ }
+
+ @Test
+ @DisplayName("updateCancerOralDetails should read the processed flag before updating")
+ void updateOralExamination_shouldReadProcessedFlag() {
+ CancerOralExamination examination = new CancerOralExamination();
+ examination.setBeneficiaryRegID(BEN_REG_ID);
+ examination.setVisitCode(VISIT_CODE);
+ when(cancerOralExaminationRepo.getCancerOralExaminationStatus(BEN_REG_ID, VISIT_CODE)).thenReturn("P");
+
+ assertEquals(0, service.updateCancerOralDetails(examination));
+ }
+
+ @Test
+ @DisplayName("updateCancerBreastDetails should read the processed flag before updating")
+ void updateBreastExamination_shouldReadProcessedFlag() {
+ CancerBreastExamination examination = new CancerBreastExamination();
+ examination.setBeneficiaryRegID(BEN_REG_ID);
+ examination.setVisitCode(VISIT_CODE);
+ when(cancerBreastExaminationRepo.getCancerBreastExaminationStatus(BEN_REG_ID, VISIT_CODE)).thenReturn("P");
+
+ assertEquals(0, service.updateCancerBreastDetails(examination));
+ }
+
+ @Test
+ @DisplayName("updateCancerAbdominalExaminationDetails should read the processed flag before updating")
+ void updateAbdominalExamination_shouldReadProcessedFlag() {
+ CancerAbdominalExamination examination = new CancerAbdominalExamination();
+ examination.setBeneficiaryRegID(BEN_REG_ID);
+ examination.setVisitCode(VISIT_CODE);
+ when(cancerAbdominalExaminationRepo.getCancerAbdominalExaminationStatus(BEN_REG_ID, VISIT_CODE)).thenReturn("P");
+
+ assertEquals(0, service.updateCancerAbdominalExaminationDetails(examination));
+ }
+
+ @Test
+ @DisplayName("updateCancerGynecologicalExaminationDetails should read the processed flag before updating")
+ void updateGynecologicalExamination_shouldReadProcessedFlag() {
+ CancerGynecologicalExamination examination = new CancerGynecologicalExamination();
+ examination.setBeneficiaryRegID(BEN_REG_ID);
+ examination.setVisitCode(VISIT_CODE);
+ when(cancerGynecologicalExaminationRepo.getCancerGynecologicalExaminationStatus(BEN_REG_ID, VISIT_CODE)).thenReturn("P");
+
+ assertEquals(0, service.updateCancerGynecologicalExaminationDetails(examination));
+ }
+ }
+
+ @Nested
+ @DisplayName("lymph node and image annotation updates")
+ class LymphNodeAndAnnotationUpdateTests {
+
+ private com.iemr.tm.data.doctor.WrapperCancerSymptoms symptoms(Boolean enlarged, boolean withMeasurements) {
+ com.iemr.tm.data.doctor.WrapperCancerSymptoms wrapper =
+ new com.iemr.tm.data.doctor.WrapperCancerSymptoms();
+ com.iemr.tm.data.doctor.CancerSignAndSymptoms signs = new com.iemr.tm.data.doctor.CancerSignAndSymptoms();
+ signs.setBeneficiaryRegID(BEN_REG_ID);
+ signs.setVisitCode(VISIT_CODE);
+ signs.setLymphNode_Enlarged(enlarged);
+ wrapper.setCancerSignAndSymptoms(signs);
+
+ com.iemr.tm.data.doctor.CancerLymphNodeDetails cervical =
+ new com.iemr.tm.data.doctor.CancerLymphNodeDetails();
+ cervical.setBeneficiaryRegID(BEN_REG_ID);
+ cervical.setVisitCode(VISIT_CODE);
+ cervical.setLymphNodeName("Cervical");
+ com.iemr.tm.data.doctor.CancerLymphNodeDetails axillary =
+ new com.iemr.tm.data.doctor.CancerLymphNodeDetails();
+ axillary.setBeneficiaryRegID(BEN_REG_ID);
+ axillary.setVisitCode(VISIT_CODE);
+ axillary.setLymphNodeName("Cervical");
+ if (withMeasurements) {
+ cervical.setMobility_Left(Boolean.TRUE);
+ cervical.setSize_Right("2 cm");
+ }
+ wrapper.setCancerLymphNodeDetails(Arrays.asList(cervical, axillary));
+ return wrapper;
+ }
+
+ @Test
+ @DisplayName("updateLymphNodeExaminationDetails should replace the measured nodes for the visit")
+ void updateLymphNode_shouldReplaceMeasuredNodes() {
+ when(cancerLymphNodeExaminationRepo.getCancerLymphNodeDetailsStatusForLymphnodeNameList(
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyList())).thenReturn(statuses());
+ when(cancerLymphNodeExaminationRepo.deleteExistingLymphNodeDetails(
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyString())).thenReturn(1);
+ when(cancerLymphNodeExaminationRepo.saveAll(any())).thenAnswer(echoList());
+
+ assertEquals(1, service.updateLymphNodeExaminationDetails(symptoms(Boolean.TRUE, true)));
+ }
+
+ @Test
+ @DisplayName("updateLymphNodeExaminationDetails should succeed when no node was measured")
+ void updateLymphNode_shouldSucceedWithoutMeasurements() {
+ when(cancerLymphNodeExaminationRepo.getCancerLymphNodeDetailsStatusForLymphnodeNameList(
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyList())).thenReturn(new ArrayList<>());
+
+ assertEquals(1, service.updateLymphNodeExaminationDetails(symptoms(Boolean.TRUE, false)));
+ }
+
+ @Test
+ @DisplayName("updateLymphNodeExaminationDetails should clear the stored nodes when none are enlarged")
+ void updateLymphNode_shouldClearStoredNodesWhenNoneEnlarged() {
+ when(cancerLymphNodeExaminationRepo.getCancerLymphNodeDetailsStatus(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(statuses());
+ when(cancerLymphNodeExaminationRepo.deleteExistingLymphNodeDetails(
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyString())).thenReturn(1);
+
+ assertEquals(1, service.updateLymphNodeExaminationDetails(symptoms(Boolean.FALSE, false)));
+ }
+
+ @Test
+ @DisplayName("updateLymphNodeExaminationDetails should succeed when nothing was stored to clear")
+ void updateLymphNode_shouldSucceedWhenNothingStoredToClear() {
+ when(cancerLymphNodeExaminationRepo.getCancerLymphNodeDetailsStatus(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(new ArrayList<>());
+
+ assertEquals(1, service.updateLymphNodeExaminationDetails(symptoms(Boolean.FALSE, false)));
+ }
+
+ @Test
+ @DisplayName("updateLymphNodeExaminationDetails should report a failure when the stored nodes cannot be cleared")
+ void updateLymphNode_shouldReportFailureWhenClearFails() {
+ when(cancerLymphNodeExaminationRepo.getCancerLymphNodeDetailsStatus(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(statuses());
+ when(cancerLymphNodeExaminationRepo.deleteExistingLymphNodeDetails(
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyString())).thenReturn(0);
+
+ assertEquals(0, service.updateLymphNodeExaminationDetails(symptoms(Boolean.FALSE, false)));
+ }
+
+ private com.iemr.tm.data.doctor.CancerExaminationImageAnnotation annotation(boolean complete) {
+ com.iemr.tm.data.doctor.CancerExaminationImageAnnotation annotation =
+ new com.iemr.tm.data.doctor.CancerExaminationImageAnnotation();
+ annotation.setBeneficiaryRegID(BEN_REG_ID);
+ annotation.setVisitCode(VISIT_CODE);
+ annotation.setCancerImageID(2);
+ if (complete) {
+ annotation.setxCoordinate(120);
+ annotation.setyCoordinate(240);
+ annotation.setCreatedBy("tester");
+ }
+ return annotation;
+ }
+
+ @Test
+ @DisplayName("updateCancerExamImgAnotasnDetails should replace the stored markers for the visit")
+ void updateImageAnnotation_shouldReplaceStoredMarkers() {
+ when(cancerExaminationImageAnnotationRepo.getCancerExaminationImageAnnotationDetailsStatus(
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyList())).thenReturn(statuses());
+ when(cancerExaminationImageAnnotationRepo.deleteExistingImageAnnotationDetails(
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyString())).thenReturn(1);
+ when(cancerExaminationImageAnnotationRepo.saveAll(any())).thenAnswer(echoList());
+
+ assertEquals(1, service.updateCancerExamImgAnotasnDetails(
+ new ArrayList<>(Collections.singletonList(annotation(true)))));
+ }
+
+ @Test
+ @DisplayName("updateCancerExamImgAnotasnDetails should succeed when no marker was stored before")
+ void updateImageAnnotation_shouldSucceedWhenNothingStoredBefore() {
+ when(cancerExaminationImageAnnotationRepo.getCancerExaminationImageAnnotationDetailsStatus(
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyList())).thenReturn(new ArrayList<>());
+ when(cancerExaminationImageAnnotationRepo.saveAll(any())).thenAnswer(echoList());
+
+ assertEquals(1, service.updateCancerExamImgAnotasnDetails(
+ new ArrayList<>(Collections.singletonList(annotation(true)))));
+ }
+
+ @Test
+ @DisplayName("updateCancerExamImgAnotasnDetails should skip markers without coordinates")
+ void updateImageAnnotation_shouldSkipMarkersWithoutCoordinates() {
+ when(cancerExaminationImageAnnotationRepo.getCancerExaminationImageAnnotationDetailsStatus(
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyList())).thenReturn(new ArrayList<>());
+ when(cancerExaminationImageAnnotationRepo.saveAll(any())).thenAnswer(echoList());
+
+ assertEquals(1, service.updateCancerExamImgAnotasnDetails(
+ new ArrayList<>(Collections.singletonList(annotation(false)))));
+ }
+
+ @Test
+ @DisplayName("updateCancerExamImgAnotasnDetails should succeed for an empty marker list")
+ void updateImageAnnotation_shouldSucceedForEmptyList() {
+ assertEquals(1, service.updateCancerExamImgAnotasnDetails(new ArrayList<>()));
+ }
+
+ @Test
+ @DisplayName("updateCancerExamImgAnotasnDetails should report a failure when the stored markers cannot be cleared")
+ void updateImageAnnotation_shouldReportFailureWhenClearFails() {
+ when(cancerExaminationImageAnnotationRepo.getCancerExaminationImageAnnotationDetailsStatus(
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyList())).thenReturn(statuses());
+ when(cancerExaminationImageAnnotationRepo.deleteExistingImageAnnotationDetails(
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyString())).thenReturn(0);
+
+ assertEquals(0, service.updateCancerExamImgAnotasnDetails(
+ new ArrayList<>(Collections.singletonList(annotation(true)))));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/cancerScreening/CSOncologistServiceImplTest.java b/src/test/java/com/iemr/tm/service/cancerScreening/CSOncologistServiceImplTest.java
new file mode 100644
index 00000000..886a1920
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/cancerScreening/CSOncologistServiceImplTest.java
@@ -0,0 +1,53 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.cancerScreening;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.doctor.CancerDiagnosisRepo;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("CSOncologistServiceImpl Test Suite")
+class CSOncologistServiceImplTest {
+
+ @Mock
+ private CancerDiagnosisRepo cancerDiagnosisRepo;
+
+ @InjectMocks
+ private CSOncologistServiceImpl service;
+
+ @Test
+ @DisplayName("updateCancerDiagnosisDetailsByOncologist should answer for a well formed request")
+ void updateCancerDiagnosisDetailsByOncologist_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateCancerDiagnosisDetailsByOncologist(new com.iemr.tm.data.doctor.CancerDiagnosis()));
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/cancerScreening/CSServiceImplTest.java b/src/test/java/com/iemr/tm/service/cancerScreening/CSServiceImplTest.java
new file mode 100644
index 00000000..b211fe4c
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/cancerScreening/CSServiceImplTest.java
@@ -0,0 +1,697 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.cancerScreening;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.benFlowStatus.BeneficiaryFlowStatusRepo;
+import com.iemr.tm.repo.nurse.BenVisitDetailRepo;
+import com.iemr.tm.repo.nurse.anc.BenAdherenceRepo;
+import com.iemr.tm.repo.quickConsultation.BenChiefComplaintRepo;
+import com.iemr.tm.repo.registrar.RegistrarRepoBenData;
+import com.iemr.tm.repo.tc_consultation.TCRequestModelRepo;
+import com.iemr.tm.service.benFlowStatus.CommonBenStatusFlowServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonDoctorServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonNurseServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonServiceImpl;
+import com.iemr.tm.service.tele_consultation.SMSGatewayServiceImpl;
+import com.iemr.tm.service.tele_consultation.TeleConsultationServiceImpl;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("CSServiceImpl Test Suite")
+class CSServiceImplTest {
+
+ @Mock
+ private CSNurseServiceImpl cSNurseServiceImpl;
+ @Mock
+ private CSDoctorServiceImpl cSDoctorServiceImpl;
+ @Mock
+ private CSOncologistServiceImpl csOncologistServiceImpl;
+ @Mock
+ private CommonNurseServiceImpl commonNurseServiceImpl;
+ @Mock
+ private CSCarestreamServiceImpl cSCarestreamServiceImpl;
+ @Mock
+ private RegistrarRepoBenData registrarRepoBenData;
+ @Mock
+ private CommonBenStatusFlowServiceImpl commonBenStatusFlowServiceImpl;
+ @Mock
+ private BeneficiaryFlowStatusRepo beneficiaryFlowStatusRepo;
+ @Mock
+ private TeleConsultationServiceImpl teleConsultationServiceImpl;
+ @Mock
+ private CommonDoctorServiceImpl commonDoctorServiceImpl;
+ @Mock
+ private CommonServiceImpl commonServiceImpl;
+ @Mock
+ private TCRequestModelRepo tCRequestModelRepo;
+ @Mock
+ private BenVisitDetailRepo benVisitDetailRepo;
+ @Mock
+ private BenChiefComplaintRepo benChiefComplaintRepo;
+ @Mock
+ private BenAdherenceRepo benAdherenceRepo;
+ @Mock
+ private SMSGatewayServiceImpl sMSGatewayServiceImpl;
+
+ @InjectMocks
+ private CSServiceImpl service;
+
+ @Test
+ @DisplayName("saveCancerScreeningNurseData should reject a request it cannot act on")
+ void saveCancerScreeningNurseData_shouldRejectRequestItCannotActOn() {
+ assertThrows(Exception.class, () -> service.saveCancerScreeningNurseData(new com.google.gson.JsonObject(), "{}"));
+ }
+
+ @Test
+ @DisplayName("deleteVisitDetails should answer for a well formed request")
+ void deleteVisitDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.deleteVisitDetails(new com.google.gson.JsonObject()));
+ }
+
+ @Test
+ @DisplayName("saveBenVisitDetails should answer for a well formed request")
+ void saveBenVisitDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.saveBenVisitDetails(new com.iemr.tm.data.nurse.BeneficiaryVisitDetail(), org.mockito.Mockito.mock(com.iemr.tm.data.nurse.CommonUtilityClass.class)));
+ }
+
+ @Test
+ @DisplayName("saveBenHistoryDetails should answer for a well formed request")
+ void saveBenHistoryDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.saveBenHistoryDetails(new com.google.gson.JsonObject(), 11L, 11L));
+ }
+
+ @Test
+ @DisplayName("saveBenFamilyHistoryDetails should answer for a well formed request")
+ void saveBenFamilyHistoryDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.saveBenFamilyHistoryDetails());
+ }
+
+ @Test
+ @DisplayName("saveBenVitalsDetails should answer for a well formed request")
+ void saveBenVitalsDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.saveBenVitalsDetails(new com.google.gson.JsonObject(), 11L, 11L));
+ }
+
+ @Test
+ @DisplayName("UpdateCSHistoryNurseData should answer for a well formed request")
+ void UpdateCSHistoryNurseData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.UpdateCSHistoryNurseData(new com.google.gson.JsonObject()));
+ }
+
+ @Test
+ @DisplayName("updateBenExaminationDetail should answer for a well formed request")
+ void updateBenExaminationDetail_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateBenExaminationDetail(new com.google.gson.JsonObject()));
+ }
+
+ @Test
+ @DisplayName("updateBenVitalDetail should answer for a well formed request")
+ void updateBenVitalDetail_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateBenVitalDetail(new com.iemr.tm.data.nurse.BenCancerVitalDetail()));
+ }
+
+ @Test
+ @DisplayName("getBenDataFrmNurseToDocVisitDetailsScreen should answer for a well formed request")
+ void getBenDataFrmNurseToDocVisitDetailsScreen_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenDataFrmNurseToDocVisitDetailsScreen(11L, 11L));
+ }
+
+ @Test
+ @DisplayName("getBenDataFrmNurseToDocHistoryScreen should answer for a well formed request")
+ void getBenDataFrmNurseToDocHistoryScreen_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenDataFrmNurseToDocHistoryScreen(11L, 11L));
+ }
+
+ @Test
+ @DisplayName("getBenDataFrmNurseToDocVitalScreen should answer for a well formed request")
+ void getBenDataFrmNurseToDocVitalScreen_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenDataFrmNurseToDocVitalScreen(11L, 11L));
+ }
+
+ @Test
+ @DisplayName("getBenDataFrmNurseToDocExaminationScreen should answer for a well formed request")
+ void getBenDataFrmNurseToDocExaminationScreen_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenDataFrmNurseToDocExaminationScreen(11L, 11L));
+ }
+
+ @Test
+ @DisplayName("saveCancerScreeningDoctorData should answer for a well formed request")
+ void saveCancerScreeningDoctorData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.saveCancerScreeningDoctorData(new com.google.gson.JsonObject(), "{}"));
+ }
+
+ @Test
+ @DisplayName("saveBenExaminationDetails should answer for a well formed request")
+ void saveBenExaminationDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.saveBenExaminationDetails(new com.google.gson.JsonObject(), 11L, "{}", 11L, 11L));
+ }
+
+ @Test
+ @DisplayName("saveBenDiagnosisDetails should answer for a well formed request")
+ void saveBenDiagnosisDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.saveBenDiagnosisDetails(new com.google.gson.JsonObject()));
+ }
+
+ @Test
+ @DisplayName("getCancerCasesheetData should answer for a well formed request")
+ void getCancerCasesheetData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getCancerCasesheetData(new org.json.JSONObject(), "{}"));
+ }
+
+ @Test
+ @DisplayName("getBenDataForCaseSheet should answer for a well formed request")
+ void getBenDataForCaseSheet_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenDataForCaseSheet(11L, 11L, 11L, "{}"));
+ }
+
+ @Test
+ @DisplayName("getBenNurseDataForCaseSheet should answer for a well formed request")
+ void getBenNurseDataForCaseSheet_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenNurseDataForCaseSheet(11L, 11L));
+ }
+
+ @Test
+ @DisplayName("getBenFamilyHistoryData should answer for a well formed request")
+ void getBenFamilyHistoryData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenFamilyHistoryData(11L));
+ }
+
+ @Test
+ @DisplayName("getBenPersonalHistoryData should answer for a well formed request")
+ void getBenPersonalHistoryData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenPersonalHistoryData(11L));
+ }
+
+ @Test
+ @DisplayName("getBenPersonalDietHistoryData should answer for a well formed request")
+ void getBenPersonalDietHistoryData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenPersonalDietHistoryData(11L));
+ }
+
+ @Test
+ @DisplayName("getBenObstetricHistoryData should answer for a well formed request")
+ void getBenObstetricHistoryData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenObstetricHistoryData(11L));
+ }
+
+ @Test
+ @DisplayName("updateCancerDiagnosisDetailsByOncologist should answer for a well formed request")
+ void updateCancerDiagnosisDetailsByOncologist_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateCancerDiagnosisDetailsByOncologist(new com.iemr.tm.data.doctor.CancerDiagnosis()));
+ }
+
+ @Test
+ @DisplayName("getBenDoctorDiagnosisData should answer for a well formed request")
+ void getBenDoctorDiagnosisData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenDoctorDiagnosisData(11L, 11L));
+ }
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorCS should answer for a well formed request")
+ void getBenCaseRecordFromDoctorCS_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenCaseRecordFromDoctorCS(11L, 11L));
+ }
+
+ @Test
+ @DisplayName("updateCancerScreeningDoctorData should reject a request it cannot act on")
+ void updateCancerScreeningDoctorData_shouldRejectRequestItCannotActOn() {
+ assertThrows(RuntimeException.class, () -> service.updateCancerScreeningDoctorData(new com.google.gson.JsonObject()));
+ }
+
+ /** A nurse request carrying a visit, history, examination and vitals. */
+ private com.google.gson.JsonObject nurseRequest() {
+ return com.google.gson.JsonParser.parseString("{"
+ + "\"beneficiaryRegID\":11,\"providerServiceMapID\":9,\"vanID\":7,\"sessionID\":1,"
+ + "\"benFlowID\":5,\"createdBy\":\"nurse1\",\"sendToDoctorWorklist\":true,"
+ + "\"visitDetails\":{\"beneficiaryRegID\":11,\"visitReason\":\"New Chief Complaint\","
+ + " \"visitCategory\":\"Cancer Screening\"},"
+ + "\"historyDetails\":{\"familyHistory\":{\"diseases\":[{\"cancerDiseaseType\":\"Breast\"}]},\"personalHistory\":{},"
+ + " \"pastObstetricHistory\":{}},"
+ + "\"examinationDetails\":{\"signsDetails\":{},\"oralDetails\":{},"
+ + " \"breastDetails\":{\"referredToMammogram\":false},"
+ + " \"abdominalDetails\":{},\"gynecologicalDetails\":{}},"
+ + "\"vitalsDetails\":{\"height_cm\":170}}").getAsJsonObject();
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("nurse data capture")
+ class NurseDataCaptureTests {
+
+ @org.junit.jupiter.api.BeforeEach
+ void stubNurseCollaborators() throws Exception {
+ org.mockito.Mockito.when(commonNurseServiceImpl.getMaxCurrentdate(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyString(), org.mockito.ArgumentMatchers.anyString())).thenReturn(0);
+ org.mockito.Mockito.when(commonNurseServiceImpl
+ .saveBeneficiaryVisitDetails(org.mockito.ArgumentMatchers.any())).thenReturn(3L);
+ org.mockito.Mockito.when(commonNurseServiceImpl.generateVisitCode(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any())).thenReturn(22L);
+ org.mockito.Mockito.when(cSNurseServiceImpl
+ .saveBenFamilyCancerHistory(org.mockito.ArgumentMatchers.any())).thenReturn(1);
+ org.mockito.Mockito.when(cSNurseServiceImpl
+ .saveBenPersonalCancerHistory(org.mockito.ArgumentMatchers.any())).thenReturn(1L);
+ org.mockito.Mockito.when(cSNurseServiceImpl
+ .saveBenPersonalCancerDietHistory(org.mockito.ArgumentMatchers.any())).thenReturn(1L);
+ org.mockito.Mockito.when(cSNurseServiceImpl
+ .saveBenObstetricCancerHistory(org.mockito.ArgumentMatchers.any())).thenReturn(1L);
+ org.mockito.Mockito.when(cSNurseServiceImpl
+ .saveBenVitalDetail(org.mockito.ArgumentMatchers.any())).thenReturn(1L);
+ org.mockito.Mockito.when(cSNurseServiceImpl.saveCancerSignAndSymptomsData(
+ org.mockito.ArgumentMatchers.any(com.iemr.tm.data.doctor.CancerSignAndSymptoms.class)))
+ .thenReturn(1L);
+ org.mockito.Mockito.when(cSNurseServiceImpl
+ .saveCancerOralExaminationData(org.mockito.ArgumentMatchers.any())).thenReturn(1L);
+ org.mockito.Mockito.when(cSNurseServiceImpl
+ .saveCancerBreastExaminationData(org.mockito.ArgumentMatchers.any())).thenReturn(1L);
+ org.mockito.Mockito.when(cSNurseServiceImpl
+ .saveCancerAbdominalExaminationData(org.mockito.ArgumentMatchers.any())).thenReturn(1L);
+ org.mockito.Mockito.when(cSNurseServiceImpl
+ .saveCancerGynecologicalExaminationData(org.mockito.ArgumentMatchers.any())).thenReturn(1L);
+ org.mockito.Mockito.when(commonBenStatusFlowServiceImpl.updateBenFlowNurseAfterNurseActivity(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyString(),
+ org.mockito.ArgumentMatchers.anyString(), org.mockito.ArgumentMatchers.anyShort(),
+ org.mockito.ArgumentMatchers.anyShort(), org.mockito.ArgumentMatchers.anyShort(),
+ org.mockito.ArgumentMatchers.anyShort(), org.mockito.ArgumentMatchers.anyShort(),
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.anyShort(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any())).thenReturn(1);
+ }
+
+ @Test
+ @DisplayName("saveCancerScreeningNurseData should save the visit, history, examination and vitals")
+ void saveNurseData_shouldSaveEverySection() throws Exception {
+ String result = service.saveCancerScreeningNurseData(nurseRequest(), "Bearer session-token");
+
+ assertTrue(result.contains("Data saved successfully"));
+ assertTrue(result.contains("\"visitCode\":\"22\""));
+ }
+
+ @Test
+ @DisplayName("saveCancerScreeningNurseData should report an already saved visit")
+ void saveNurseData_shouldReportAlreadySavedVisit() throws Exception {
+ org.mockito.Mockito.when(commonNurseServiceImpl.getMaxCurrentdate(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyString(), org.mockito.ArgumentMatchers.anyString())).thenReturn(1);
+
+ assertTrue(service.saveCancerScreeningNurseData(nurseRequest(), "Bearer session-token")
+ .contains("Data already saved"));
+ }
+
+ @Test
+ @DisplayName("saveCancerScreeningNurseData should fail when the visit could not be created")
+ void saveNurseData_shouldFailWhenVisitNotCreated() throws Exception {
+ org.mockito.Mockito.when(commonNurseServiceImpl
+ .saveBeneficiaryVisitDetails(org.mockito.ArgumentMatchers.any())).thenReturn(0L);
+
+ org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class,
+ () -> service.saveCancerScreeningNurseData(nurseRequest(), "Bearer session-token"));
+ }
+
+ @Test
+ @DisplayName("saveBenVisitDetails should return the new visit id and code")
+ void saveBenVisitDetails_shouldReturnVisitIdAndCode() throws Exception {
+ com.iemr.tm.data.nurse.BeneficiaryVisitDetail visit = new com.iemr.tm.data.nurse.BeneficiaryVisitDetail();
+ visit.setBeneficiaryRegID(11L);
+ visit.setVisitReason("New Chief Complaint");
+ visit.setVisitCategory("Cancer Screening");
+ com.iemr.tm.data.nurse.CommonUtilityClass utility = new com.iemr.tm.data.nurse.CommonUtilityClass();
+ utility.setVanID(7);
+ utility.setSessionID(1);
+
+ java.util.Map result = service.saveBenVisitDetails(visit, utility);
+
+ assertTrue(result.containsKey("visitID"));
+ assertTrue(result.containsKey("visitCode"));
+ }
+
+ @Test
+ @DisplayName("saveBenHistoryDetails should store every captured history section")
+ void saveHistory_shouldStoreCapturedSections() throws Exception {
+ assertTrue(service.saveBenHistoryDetails(nurseRequest(), 3L, 22L) > 0);
+ }
+
+ @Test
+ @DisplayName("saveBenHistoryDetails should succeed when no history section was captured")
+ void saveHistory_shouldSucceedWithoutCapturedSections() throws Exception {
+ assertTrue(service.saveBenHistoryDetails(
+ com.google.gson.JsonParser.parseString("{}").getAsJsonObject(), 3L, 22L) > 0);
+ }
+
+ @Test
+ @DisplayName("saveBenVitalsDetails should store the captured vitals")
+ void saveVitals_shouldStoreCapturedVitals() throws Exception {
+ assertTrue(service.saveBenVitalsDetails(nurseRequest(), 3L, 22L) > 0);
+ }
+
+ @Test
+ @DisplayName("saveBenVitalsDetails should succeed when no vitals were captured")
+ void saveVitals_shouldSucceedWithoutCapturedVitals() throws Exception {
+ assertTrue(service.saveBenVitalsDetails(
+ com.google.gson.JsonParser.parseString("{}").getAsJsonObject(), 3L, 22L) > 0);
+ }
+
+ @Test
+ @DisplayName("saveBenExaminationDetails should store every captured examination section")
+ void saveExamination_shouldStoreCapturedSections() throws Exception {
+ assertTrue(service.saveBenExaminationDetails(nurseRequest(), 3L, "Bearer session-token", 22L, 5L) > 0);
+ }
+
+ @Test
+ @DisplayName("saveBenExaminationDetails should succeed when no examination section was captured")
+ void saveExamination_shouldSucceedWithoutCapturedSections() throws Exception {
+ assertTrue(service.saveBenExaminationDetails(
+ com.google.gson.JsonParser.parseString("{}").getAsJsonObject(), 3L, "Bearer session-token", 22L,
+ 5L) > 0);
+ }
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("doctor data capture")
+ class DoctorDataCaptureTests {
+
+ private com.google.gson.JsonObject doctorRequest(boolean specialist, boolean withTcRequest) {
+ StringBuilder request = new StringBuilder("{\"doctorSignatureFlag\":true,\"diagnosis\":{"
+ + "\"beneficiaryRegID\":11,\"beneficiaryID\":9,\"benVisitID\":3,\"visitCode\":22,"
+ + "\"benFlowID\":5,\"createdBy\":\"tester\",\"vanID\":7,\"serviceID\":4,"
+ + "\"provisionalDiagnosisPrimaryDoctor\":\"suspected\",\"isSpecialist\":" + specialist + "}");
+ if (withTcRequest) {
+ request.append(",\"tcRequest\":{\"userID\":41,\"specializationID\":3,\"walkIn\":false,"
+ + "\"allocationDate\":\"2026-08-26\",\"fromTime\":\"10:00:00\",\"toTime\":\"10:30:00\"}");
+ }
+ return com.google.gson.JsonParser.parseString(request.append("}").toString()).getAsJsonObject();
+ }
+
+ @org.junit.jupiter.api.BeforeEach
+ void stubDoctorCollaborators() throws Exception {
+ org.mockito.Mockito.when(cSDoctorServiceImpl
+ .saveCancerDiagnosisData(org.mockito.ArgumentMatchers.any())).thenReturn(4L);
+ org.mockito.Mockito.when(commonDoctorServiceImpl.callTmForSpecialistSlotBook(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.anyString())).thenReturn(1);
+ org.mockito.Mockito.when(teleConsultationServiceImpl
+ .createTCRequest(org.mockito.ArgumentMatchers.any())).thenReturn(77L);
+ org.mockito.Mockito.when(commonBenStatusFlowServiceImpl.updateBenFlowAfterDocData(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.anyShort(), org.mockito.ArgumentMatchers.anyShort(),
+ org.mockito.ArgumentMatchers.anyShort(), org.mockito.ArgumentMatchers.anyShort(),
+ org.mockito.ArgumentMatchers.anyInt(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.anyShort(), org.mockito.ArgumentMatchers.anyBoolean()))
+ .thenReturn(1);
+ org.mockito.Mockito.when(commonBenStatusFlowServiceImpl.updateBenFlowAfterDocDataFromSpecialist(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.anyShort(), org.mockito.ArgumentMatchers.anyShort(),
+ org.mockito.ArgumentMatchers.anyShort(), org.mockito.ArgumentMatchers.anyShort(),
+ org.mockito.ArgumentMatchers.anyShort(), org.mockito.ArgumentMatchers.anyBoolean()))
+ .thenReturn(1);
+ org.mockito.Mockito.when(tCRequestModelRepo.updateStatusIfConsultationCompleted(
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyString())).thenReturn(1);
+ }
+
+ @Test
+ @DisplayName("saveCancerScreeningDoctorData should save the diagnosis for a general doctor")
+ void saveDoctorData_shouldSaveDiagnosisForGeneralDoctor() throws Exception {
+ org.junit.jupiter.api.Assertions.assertEquals(Long.valueOf(4L), service.saveCancerScreeningDoctorData(doctorRequest(false, false),
+ "Bearer session-token"));
+ }
+
+ @Test
+ @DisplayName("saveCancerScreeningDoctorData should route a specialist consultation through the flow update")
+ void saveDoctorData_shouldRouteSpecialistConsultation() throws Exception {
+ org.junit.jupiter.api.Assertions.assertEquals(Long.valueOf(4L), service.saveCancerScreeningDoctorData(doctorRequest(true, false),
+ "Bearer session-token"));
+ }
+
+ @Test
+ @DisplayName("saveCancerScreeningDoctorData should book a slot and raise the teleconsultation request")
+ void saveDoctorData_shouldBookSlotAndRaiseTcRequest() throws Exception {
+ org.junit.jupiter.api.Assertions.assertEquals(Long.valueOf(4L), service.saveCancerScreeningDoctorData(doctorRequest(false, true),
+ "Bearer session-token"));
+
+ org.mockito.Mockito.verify(teleConsultationServiceImpl).createTCRequest(org.mockito.ArgumentMatchers.any());
+ org.mockito.Mockito.verify(sMSGatewayServiceImpl).smsSenderGateway(
+ org.mockito.ArgumentMatchers.eq("schedule"), org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyInt(), org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.anyString(),
+ org.mockito.ArgumentMatchers.anyString(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.anyString());
+ }
+
+ @Test
+ @DisplayName("saveCancerScreeningDoctorData should fail when the specialist slot could not be booked")
+ void saveDoctorData_shouldFailWhenSlotBookingFails() {
+ org.mockito.Mockito.when(commonDoctorServiceImpl.callTmForSpecialistSlotBook(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.anyString())).thenReturn(0);
+
+ org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class,
+ () -> service.saveCancerScreeningDoctorData(doctorRequest(false, true), "Bearer session-token"));
+ }
+
+ @Test
+ @DisplayName("saveCancerScreeningDoctorData should fail when the beneficiary flow update fails")
+ void saveDoctorData_shouldFailWhenFlowUpdateFails() {
+ org.mockito.Mockito.when(commonBenStatusFlowServiceImpl.updateBenFlowAfterDocData(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.anyShort(), org.mockito.ArgumentMatchers.anyShort(),
+ org.mockito.ArgumentMatchers.anyShort(), org.mockito.ArgumentMatchers.anyShort(),
+ org.mockito.ArgumentMatchers.anyInt(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.anyShort(), org.mockito.ArgumentMatchers.anyBoolean()))
+ .thenReturn(0);
+
+ org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class,
+ () -> service.saveCancerScreeningDoctorData(doctorRequest(false, false), "Bearer session-token"));
+ }
+
+ @Test
+ @DisplayName("saveBenDiagnosisDetails should succeed when no diagnosis was captured")
+ void saveDiagnosis_shouldSucceedWithoutCapturedDiagnosis() throws Exception {
+ org.junit.jupiter.api.Assertions.assertEquals(Long.valueOf(1L), service.saveBenDiagnosisDetails(
+ com.google.gson.JsonParser.parseString("{}").getAsJsonObject()));
+ }
+
+ @Test
+ @DisplayName("updateCancerScreeningDoctorData should close the specialist consultation")
+ void updateDoctorData_shouldCloseSpecialistConsultation() throws Exception {
+ org.mockito.Mockito.when(cSDoctorServiceImpl
+ .updateCancerDiagnosisDetailsByDoctor(org.mockito.ArgumentMatchers.any())).thenReturn(1);
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo
+ .updateBenFlowAfterTCSpcialistDoneForCanceScreening(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyLong()))
+ .thenReturn(1);
+
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.updateCancerScreeningDoctorData(doctorRequest(false, false)));
+ }
+
+ @Test
+ @DisplayName("updateCancerScreeningDoctorData should fail when the flow status update fails")
+ void updateDoctorData_shouldFailWhenFlowStatusUpdateFails() {
+ org.mockito.Mockito.when(cSDoctorServiceImpl
+ .updateCancerDiagnosisDetailsByDoctor(org.mockito.ArgumentMatchers.any())).thenReturn(1);
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo
+ .updateBenFlowAfterTCSpcialistDoneForCanceScreening(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyLong()))
+ .thenReturn(0);
+
+ org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class,
+ () -> service.updateCancerScreeningDoctorData(doctorRequest(false, false)));
+ }
+
+ @Test
+ @DisplayName("updateCancerScreeningDoctorData should fail when the diagnosis could not be updated")
+ void updateDoctorData_shouldFailWhenDiagnosisUpdateFails() {
+ org.mockito.Mockito.when(cSDoctorServiceImpl
+ .updateCancerDiagnosisDetailsByDoctor(org.mockito.ArgumentMatchers.any())).thenReturn(0);
+
+ org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class,
+ () -> service.updateCancerScreeningDoctorData(doctorRequest(false, false)));
+ }
+
+ @Test
+ @DisplayName("updateCancerScreeningDoctorData should reject a null request")
+ void updateDoctorData_shouldRejectNullRequest() {
+ org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class,
+ () -> service.updateCancerScreeningDoctorData(null));
+ }
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("captured section updates")
+ class CapturedSectionUpdateTests {
+
+ private static final String FULL_HISTORY = "{\"familyHistory\":[{\"beneficiaryRegID\":11,\"visitCode\":22,"
+ + " \"deleted\":false,\"familyMembers\":[\"Mother\"]}],"
+ + "\"pastObstetricHistory\":{\"beneficiaryRegID\":11,\"visitCode\":22},"
+ + "\"personalHistory\":{\"beneficiaryRegID\":11,\"visitCode\":22}}";
+
+ private static final String FULL_EXAMINATION = "{\"beneficiaryRegID\":11,\"visitCode\":22,"
+ + "\"signsDetails\":{\"cancerSignAndSymptoms\":{\"beneficiaryRegID\":11,\"visitCode\":22,"
+ + " \"lymphNode_Enlarged\":true},"
+ + " \"cancerLymphNodeDetails\":[{\"beneficiaryRegID\":11,\"visitCode\":22,"
+ + " \"lymphNodeName\":\"Cervical\",\"mobility_Left\":true,\"size_Right\":\"2 cm\"}]},"
+ + "\"oralDetails\":{\"beneficiaryRegID\":11,\"visitCode\":22},"
+ + "\"breastDetails\":{\"beneficiaryRegID\":11,\"visitCode\":22},"
+ + "\"abdominalDetails\":{\"beneficiaryRegID\":11,\"visitCode\":22},"
+ + "\"gynecologicalDetails\":{\"beneficiaryRegID\":11,\"visitCode\":22},"
+ + "\"imageCoordinates\":[{\"cancerImageID\":2,\"createdBy\":\"nurse1\","
+ + " \"markers\":[{\"xCord\":120,\"yCord\":240,\"point\":\"1\"}]}]}";
+
+ private com.google.gson.JsonObject json(String raw) {
+ return com.google.gson.JsonParser.parseString(raw).getAsJsonObject();
+ }
+
+ @org.junit.jupiter.api.BeforeEach
+ void stubUpdateCollaborators() {
+ org.mockito.Mockito.when(cSNurseServiceImpl
+ .updateBeneficiaryFamilyCancerHistory(org.mockito.ArgumentMatchers.any())).thenReturn(1);
+ org.mockito.Mockito.when(cSNurseServiceImpl
+ .updateBenObstetricCancerHistory(org.mockito.ArgumentMatchers.any())).thenReturn(1);
+ org.mockito.Mockito.when(cSNurseServiceImpl
+ .updateBenPersonalCancerHistory(org.mockito.ArgumentMatchers.any())).thenReturn(1);
+ org.mockito.Mockito.when(cSNurseServiceImpl
+ .updateBenPersonalCancerDietHistory(org.mockito.ArgumentMatchers.any())).thenReturn(1);
+ org.mockito.Mockito.when(cSNurseServiceImpl
+ .updateSignAndSymptomsExaminationDetails(org.mockito.ArgumentMatchers.any())).thenReturn(1);
+ org.mockito.Mockito.when(cSNurseServiceImpl
+ .updateLymphNodeExaminationDetails(org.mockito.ArgumentMatchers.any())).thenReturn(1);
+ org.mockito.Mockito.when(cSNurseServiceImpl
+ .updateCancerOralDetails(org.mockito.ArgumentMatchers.any())).thenReturn(1);
+ org.mockito.Mockito.when(cSNurseServiceImpl
+ .updateCancerBreastDetails(org.mockito.ArgumentMatchers.any())).thenReturn(1);
+ org.mockito.Mockito.when(cSNurseServiceImpl
+ .updateCancerAbdominalExaminationDetails(org.mockito.ArgumentMatchers.any())).thenReturn(1);
+ org.mockito.Mockito.when(cSNurseServiceImpl
+ .updateCancerGynecologicalExaminationDetails(org.mockito.ArgumentMatchers.any())).thenReturn(1);
+ org.mockito.Mockito.when(cSNurseServiceImpl.getCancerExaminationImageAnnotationList(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any()))
+ .thenReturn(new java.util.ArrayList<>());
+ org.mockito.Mockito.when(cSNurseServiceImpl
+ .updateCancerExamImgAnotasnDetails(org.mockito.ArgumentMatchers.any())).thenReturn(1);
+ }
+
+ @Test
+ @DisplayName("UpdateCSHistoryNurseData should update every captured history section")
+ void updateHistory_shouldUpdateEveryCapturedSection() throws Exception {
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.UpdateCSHistoryNurseData(json(FULL_HISTORY)));
+
+ org.mockito.Mockito.verify(cSNurseServiceImpl)
+ .updateBeneficiaryFamilyCancerHistory(org.mockito.ArgumentMatchers.any());
+ org.mockito.Mockito.verify(cSNurseServiceImpl)
+ .updateBenPersonalCancerDietHistory(org.mockito.ArgumentMatchers.any());
+ }
+
+ @Test
+ @DisplayName("UpdateCSHistoryNurseData should succeed when no history section was captured")
+ void updateHistory_shouldSucceedWithoutCapturedSections() throws Exception {
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.UpdateCSHistoryNurseData(json("{}")));
+ }
+
+ @Test
+ @DisplayName("UpdateCSHistoryNurseData should succeed when the family history list is empty")
+ void updateHistory_shouldSucceedWithEmptyFamilyHistory() throws Exception {
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.UpdateCSHistoryNurseData(json("{\"familyHistory\":[]}")));
+ }
+
+ @Test
+ @DisplayName("UpdateCSHistoryNurseData should report history it could not update")
+ void updateHistory_shouldReportUnupdatedHistory() throws Exception {
+ org.mockito.Mockito.when(cSNurseServiceImpl
+ .updateBenObstetricCancerHistory(org.mockito.ArgumentMatchers.any())).thenReturn(0);
+
+ org.junit.jupiter.api.Assertions.assertEquals(0, service.UpdateCSHistoryNurseData(json(FULL_HISTORY)));
+ }
+
+ @Test
+ @DisplayName("updateBenExaminationDetail should update every captured examination section")
+ void updateExamination_shouldUpdateEveryCapturedSection() throws Exception {
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.updateBenExaminationDetail(json(FULL_EXAMINATION)));
+
+ org.mockito.Mockito.verify(cSNurseServiceImpl)
+ .updateSignAndSymptomsExaminationDetails(org.mockito.ArgumentMatchers.any());
+ org.mockito.Mockito.verify(cSNurseServiceImpl)
+ .updateLymphNodeExaminationDetails(org.mockito.ArgumentMatchers.any());
+ org.mockito.Mockito.verify(cSNurseServiceImpl)
+ .updateCancerOralDetails(org.mockito.ArgumentMatchers.any());
+ org.mockito.Mockito.verify(cSNurseServiceImpl)
+ .updateCancerBreastDetails(org.mockito.ArgumentMatchers.any());
+ org.mockito.Mockito.verify(cSNurseServiceImpl)
+ .updateCancerAbdominalExaminationDetails(org.mockito.ArgumentMatchers.any());
+ org.mockito.Mockito.verify(cSNurseServiceImpl)
+ .updateCancerGynecologicalExaminationDetails(org.mockito.ArgumentMatchers.any());
+ org.mockito.Mockito.verify(cSNurseServiceImpl)
+ .updateCancerExamImgAnotasnDetails(org.mockito.ArgumentMatchers.any());
+ }
+
+ @Test
+ @DisplayName("updateBenExaminationDetail should succeed when no examination section was captured")
+ void updateExamination_shouldSucceedWithoutCapturedSections() throws Exception {
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.updateBenExaminationDetail(json("{}")));
+ }
+
+ @Test
+ @DisplayName("updateBenExaminationDetail should report an examination it could not update")
+ void updateExamination_shouldReportUnupdatedExamination() throws Exception {
+ org.mockito.Mockito.when(cSNurseServiceImpl
+ .updateCancerOralDetails(org.mockito.ArgumentMatchers.any())).thenReturn(0);
+
+ org.junit.jupiter.api.Assertions.assertEquals(0, service.updateBenExaminationDetail(json(FULL_EXAMINATION)));
+ }
+
+ @Test
+ @DisplayName("saveBenExaminationDetails should store the lymph nodes captured with the signs")
+ void saveExamination_shouldStoreLymphNodesWithSigns() throws Exception {
+ org.mockito.Mockito.when(cSNurseServiceImpl.saveCancerSignAndSymptomsData(
+ org.mockito.ArgumentMatchers.any(com.iemr.tm.data.doctor.CancerSignAndSymptoms.class),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any())).thenReturn(1L);
+ org.mockito.Mockito.when(cSNurseServiceImpl.saveLymphNodeDetails(org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any())).thenReturn(1L);
+ org.mockito.Mockito.when(cSNurseServiceImpl
+ .saveCancerOralExaminationData(org.mockito.ArgumentMatchers.any())).thenReturn(1L);
+ org.mockito.Mockito.when(cSNurseServiceImpl
+ .saveCancerBreastExaminationData(org.mockito.ArgumentMatchers.any())).thenReturn(1L);
+ org.mockito.Mockito.when(cSNurseServiceImpl
+ .saveCancerAbdominalExaminationData(org.mockito.ArgumentMatchers.any())).thenReturn(1L);
+ org.mockito.Mockito.when(cSNurseServiceImpl
+ .saveCancerGynecologicalExaminationData(org.mockito.ArgumentMatchers.any())).thenReturn(1L);
+ org.mockito.Mockito.when(cSNurseServiceImpl.saveDocExaminationImageAnnotation(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any())).thenReturn(1L);
+
+ assertTrue(service.saveBenExaminationDetails(
+ json("{\"examinationDetails\":" + FULL_EXAMINATION + "}"), 3L, "Bearer session-token", 22L,
+ 5L) > 0);
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/common/master/ANCMasterDataServiceImplTest.java b/src/test/java/com/iemr/tm/service/common/master/ANCMasterDataServiceImplTest.java
new file mode 100644
index 00000000..f47e28dd
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/common/master/ANCMasterDataServiceImplTest.java
@@ -0,0 +1,210 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.common.master;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.doctor.ChiefComplaintMasterRepo;
+import com.iemr.tm.repo.doctor.DrugDoseMasterRepo;
+import com.iemr.tm.repo.doctor.DrugDurationUnitMasterRepo;
+import com.iemr.tm.repo.doctor.DrugFrequencyMasterRepo;
+import com.iemr.tm.repo.foetalmonitor.FoetalMonitorTestsRepo;
+import com.iemr.tm.repo.labModule.ProcedureRepo;
+import com.iemr.tm.repo.login.MasterVanRepo;
+import com.iemr.tm.repo.masterrepo.anc.AllergicReactionTypesRepo;
+import com.iemr.tm.repo.masterrepo.anc.BloodGroupsRepo;
+import com.iemr.tm.repo.masterrepo.anc.ChildVaccinationsRepo;
+import com.iemr.tm.repo.masterrepo.anc.ComorbidConditionRepo;
+import com.iemr.tm.repo.masterrepo.anc.CompFeedsRepo;
+import com.iemr.tm.repo.masterrepo.anc.ComplicationTypesRepo;
+import com.iemr.tm.repo.masterrepo.anc.CounsellingTypeRepo;
+import com.iemr.tm.repo.masterrepo.anc.DeliveryPlaceRepo;
+import com.iemr.tm.repo.masterrepo.anc.DeliveryTypeRepo;
+import com.iemr.tm.repo.masterrepo.anc.DevelopmentProblemsRepo;
+import com.iemr.tm.repo.masterrepo.anc.DiseaseTypeRepo;
+import com.iemr.tm.repo.masterrepo.anc.FundalHeightRepo;
+import com.iemr.tm.repo.masterrepo.anc.GestationRepo;
+import com.iemr.tm.repo.masterrepo.anc.GrossMotorMilestoneRepo;
+import com.iemr.tm.repo.masterrepo.anc.IllnessTypesRepo;
+import com.iemr.tm.repo.masterrepo.anc.JointTypesRepo;
+import com.iemr.tm.repo.masterrepo.anc.MenstrualCycleRangeRepo;
+import com.iemr.tm.repo.masterrepo.anc.MenstrualCycleStatusRepo;
+import com.iemr.tm.repo.masterrepo.anc.MenstrualProblemRepo;
+import com.iemr.tm.repo.masterrepo.anc.MusculoskeletalRepo;
+import com.iemr.tm.repo.masterrepo.anc.OptionalVaccinationsRepo;
+import com.iemr.tm.repo.masterrepo.anc.PersonalHabitTypeRepo;
+import com.iemr.tm.repo.masterrepo.anc.PregDurationRepo;
+import com.iemr.tm.repo.masterrepo.anc.PregOutcomeRepo;
+import com.iemr.tm.repo.masterrepo.anc.ServiceFacilityMasterRepo;
+import com.iemr.tm.repo.masterrepo.anc.ServiceMasterRepo;
+import com.iemr.tm.repo.masterrepo.anc.SurgeryTypesRepo;
+import com.iemr.tm.repo.masterrepo.covid19.CovidContactHistoryMasterRepo;
+import com.iemr.tm.repo.masterrepo.covid19.CovidRecommnedationMasterRepo;
+import com.iemr.tm.repo.masterrepo.covid19.CovidSymptomsMasterRepo;
+import com.iemr.tm.repo.masterrepo.doctor.InstituteRepo;
+import com.iemr.tm.repo.masterrepo.doctor.ItemFormMasterRepo;
+import com.iemr.tm.repo.masterrepo.doctor.ItemMasterRepo;
+import com.iemr.tm.repo.masterrepo.doctor.RouteOfAdminRepo;
+import com.iemr.tm.repo.masterrepo.doctor.V_DrugPrescriptionRepo;
+import com.iemr.tm.repo.masterrepo.ncdCare.NCDCareTypeRepo;
+import com.iemr.tm.repo.masterrepo.nurse.FamilyMemberMasterRepo;
+import com.iemr.tm.repo.masterrepo.pnc.NewbornHealthStatusRepo;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("ANCMasterDataServiceImpl Test Suite")
+class ANCMasterDataServiceImplTest {
+
+ @Mock
+ private AllergicReactionTypesRepo allergicReactionTypesRepo;
+ @Mock
+ private BloodGroupsRepo bloodGroupsRepo;
+ @Mock
+ private ChildVaccinationsRepo childVaccinationsRepo;
+ @Mock
+ private DeliveryPlaceRepo deliveryPlaceRepo;
+ @Mock
+ private DeliveryTypeRepo deliveryTypeRepo;
+ @Mock
+ private DevelopmentProblemsRepo developmentProblemsRepo;
+ @Mock
+ private GestationRepo gestationRepo;
+ @Mock
+ private IllnessTypesRepo illnessTypesRepo;
+ @Mock
+ private JointTypesRepo jointTypesRepo;
+ @Mock
+ private MenstrualCycleRangeRepo menstrualCycleRangeRepo;
+ @Mock
+ private MenstrualCycleStatusRepo menstrualCycleStatusRepo;
+ @Mock
+ private MenstrualProblemRepo menstrualProblemRepo;
+ @Mock
+ private MusculoskeletalRepo musculoskeletalRepo;
+ @Mock
+ private PregDurationRepo pregDurationRepo;
+ @Mock
+ private SurgeryTypesRepo surgeryTypesRepo;
+ @Mock
+ private ComorbidConditionRepo comorbidConditionRepo;
+ @Mock
+ private CompFeedsRepo compFeedsRepo;
+ @Mock
+ private FundalHeightRepo fundalHeightRepo;
+ @Mock
+ private GrossMotorMilestoneRepo grossMotorMilestoneRepo;
+ @Mock
+ private ServiceMasterRepo serviceMasterRepo;
+ @Mock
+ private CounsellingTypeRepo counsellingTypeRepo;
+ @Mock
+ private InstituteRepo instituteRepo;
+ @Mock
+ private PersonalHabitTypeRepo personalHabitTypeRepo;
+ @Mock
+ private PregOutcomeRepo pregOutcomeRepo;
+ @Mock
+ private DiseaseTypeRepo diseaseTypeRepo;
+ @Mock
+ private ComplicationTypesRepo complicationTypesRepo;
+ @Mock
+ private ChiefComplaintMasterRepo chiefComplaintMasterRepo;
+ @Mock
+ private FamilyMemberMasterRepo familyMemberMasterRepo;
+ @Mock
+ private DrugDoseMasterRepo drugDoseMasterRepo;
+ @Mock
+ private DrugDurationUnitMasterRepo drugDurationUnitMasterRepo;
+ @Mock
+ private DrugFrequencyMasterRepo drugFrequencyMasterRepo;
+ @Mock
+ private NewbornHealthStatusRepo newbornHealthStatusRepo;
+ @Mock
+ private NCDCareTypeRepo ncdCareTypeRepo;
+ @Mock
+ private ProcedureRepo procedureRepo;
+ @Mock
+ private OptionalVaccinationsRepo optionalVaccinationsRepo;
+ @Mock
+ private ItemMasterRepo itemMasterRepo;
+ @Mock
+ private ItemFormMasterRepo itemFormMasterRepo;
+ @Mock
+ private RouteOfAdminRepo routeOfAdminRepo;
+ @Mock
+ private V_DrugPrescriptionRepo v_DrugPrescriptionRepo;
+ @Mock
+ private CovidSymptomsMasterRepo covidSymptomsMasterRepo;
+ @Mock
+ private CovidContactHistoryMasterRepo covidContactHistoryMasterRepo;
+ @Mock
+ private CovidRecommnedationMasterRepo covidRecommnedationMasterRepo;
+ @Mock
+ private MasterVanRepo masterVanRepo;
+ @Mock
+ private FoetalMonitorTestsRepo foetakMonitorTestRepo;
+ @Mock
+ private ServiceFacilityMasterRepo serviceFacilityMasterRepo;
+
+ @InjectMocks
+ private ANCMasterDataServiceImpl service;
+
+ @Test
+ @DisplayName("getCommonNurseMasterDataForGenopdAncNcdcarePnc should assemble the nurse master data")
+ void getNurseMasterData_shouldAssembleMasterData() {
+ String result = service.getCommonNurseMasterDataForGenopdAncNcdcarePnc(1, 9, "Female");
+
+ assertNotNull(result);
+ assertTrue(result.contains("bloodGroups"));
+ }
+
+ @Test
+ @DisplayName("getCommonNurseMasterDataForGenopdAncNcdcarePnc should assemble the master data for a male")
+ void getNurseMasterData_shouldAssembleMasterDataForMale() {
+ assertNotNull(service.getCommonNurseMasterDataForGenopdAncNcdcarePnc(1, 9, "Male"));
+ }
+
+ @Test
+ @DisplayName("getCommonDoctorMasterDataForGenopdAncNcdcarePnc should assemble the doctor master data")
+ void getDoctorMasterData_shouldAssembleMasterData() {
+ String result = service.getCommonDoctorMasterDataForGenopdAncNcdcarePnc(1, 9, "Female", 3, 7);
+
+ assertNotNull(result);
+ assertTrue(result.contains("additionalServices"));
+ }
+
+ @Test
+ @DisplayName("getCommonDoctorMasterDataForGenopdAncNcdcarePnc should assemble the cancer screening master data")
+ void getDoctorMasterData_shouldAssembleCancerScreeningMasterData() {
+ assertNotNull(service.getCommonDoctorMasterDataForGenopdAncNcdcarePnc(7, 9, "Female", 3, 7));
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/common/master/CommonMasterServiceImplTest.java b/src/test/java/com/iemr/tm/service/common/master/CommonMasterServiceImplTest.java
new file mode 100644
index 00000000..93c8062e
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/common/master/CommonMasterServiceImplTest.java
@@ -0,0 +1,190 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/package com.iemr.tm.service.common.master;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.service.labtechnician.LabTechnicianServiceImpl;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("CommonMasterServiceImpl Test Suite")
+class CommonMasterServiceImplTest {
+
+ private static final Integer PROVIDER_SERVICE_MAP_ID = 9;
+ private static final Integer FACILITY_ID = 2;
+ private static final Integer VAN_ID = 7;
+ private static final String GENDER = "Female";
+
+ @Mock
+ private ANCMasterDataServiceImpl ancMasterDataServiceImpl;
+ @Mock
+ private NurseMasterDataServiceImpl nurseMasterDataServiceImpl;
+ @Mock
+ private DoctorMasterDataServiceImpl doctorMasterDataServiceImpl;
+ @Mock
+ private RegistrarServiceMasterDataImpl registrarServiceMasterDataImpl;
+ @Mock
+ private NCDScreeningMasterServiceImpl ncdScreeningServiceImpl;
+ @Mock
+ private QCMasterDataServiceImpl qCMasterDataServiceImpl;
+ @Mock
+ private NCDCareMasterDataServiceImpl ncdCareMasterDataServiceImpl;
+ @Mock
+ private LabTechnicianServiceImpl labTechnicianServiceImpl;
+
+ private CommonMasterServiceImpl service;
+
+ @BeforeEach
+ @DisplayName("Wire the service with the mocked master services")
+ void setUp() {
+ service = new CommonMasterServiceImpl();
+ service.setAncMasterDataServiceImpl(ancMasterDataServiceImpl);
+ service.setNurseMasterDataServiceImpl(nurseMasterDataServiceImpl);
+ service.setDoctorMasterDataServiceImpl(doctorMasterDataServiceImpl);
+ service.setRegistrarServiceMasterDataImpl(registrarServiceMasterDataImpl);
+ service.setNcdScreeningServiceImpl(ncdScreeningServiceImpl);
+ service.setqCMasterDataServiceImpl(qCMasterDataServiceImpl);
+ service.setNcdCareMasterDataServiceImpl(ncdCareMasterDataServiceImpl);
+ service.setLabTechnicianServiceImpl(labTechnicianServiceImpl);
+ }
+
+ @Test
+ @DisplayName("getVisitReasonAndCategories should return the visit master the nurse service assembled")
+ void getVisitReasonAndCategories_shouldReturnNurseMaster() {
+ when(nurseMasterDataServiceImpl.GetVisitReasonAndCategories()).thenReturn("{\"visitReasons\":[]}");
+
+ assertEquals("{\"visitReasons\":[]}", service.getVisitReasonAndCategories());
+ }
+
+ @Test
+ @DisplayName("getECGAbnormalFindings should return the findings master the lab service assembled")
+ void getECGAbnormalFindings_shouldReturnLabMaster() {
+ when(labTechnicianServiceImpl.getECGAbnormalFindings()).thenReturn("{\"findings\":[]}");
+
+ assertEquals("{\"findings\":[]}", service.getECGAbnormalFindings());
+ }
+
+ @Nested
+ @DisplayName("nurse master data")
+ class NurseMasterTests {
+
+ @Test
+ @DisplayName("getMasterDataForNurse should route cancer screening to the nurse master service")
+ void getMasterDataForNurse_shouldRouteCancerScreening() {
+ when(nurseMasterDataServiceImpl.getCancerScreeningMasterDataForNurse()).thenReturn("cancer-master");
+
+ assertEquals("cancer-master",
+ service.getMasterDataForNurse(1, PROVIDER_SERVICE_MAP_ID, GENDER));
+ }
+
+ @Test
+ @DisplayName("getMasterDataForNurse should route NCD screening to the screening master service")
+ void getMasterDataForNurse_shouldRouteNcdScreening() {
+ when(ncdScreeningServiceImpl.getNCDScreeningMasterData(anyInt(), anyInt(), anyString()))
+ .thenReturn("ncd-screening-master");
+
+ assertEquals("ncd-screening-master",
+ service.getMasterDataForNurse(2, PROVIDER_SERVICE_MAP_ID, GENDER));
+ }
+
+ @ParameterizedTest
+ @ValueSource(ints = { 3, 4, 5, 6, 7, 8, 10 })
+ @DisplayName("getMasterDataForNurse should route the remaining visit categories to the shared master service")
+ void getMasterDataForNurse_shouldRouteRemainingCategories(int visitCategoryID) {
+ when(ancMasterDataServiceImpl.getCommonNurseMasterDataForGenopdAncNcdcarePnc(anyInt(), anyInt(),
+ anyString())).thenReturn("shared-nurse-master");
+
+ assertEquals("shared-nurse-master",
+ service.getMasterDataForNurse(visitCategoryID, PROVIDER_SERVICE_MAP_ID, GENDER));
+ }
+
+ @Test
+ @DisplayName("getMasterDataForNurse should reject a visit category it does not know")
+ void getMasterDataForNurse_shouldRejectUnknownCategory() {
+ assertEquals("Invalid VisitCategoryID",
+ service.getMasterDataForNurse(99, PROVIDER_SERVICE_MAP_ID, GENDER));
+ }
+
+ @Test
+ @DisplayName("getMasterDataForNurse should reject a request with no visit category")
+ void getMasterDataForNurse_shouldRejectMissingCategory() {
+ assertEquals("Invalid VisitCategoryID",
+ service.getMasterDataForNurse(null, PROVIDER_SERVICE_MAP_ID, GENDER));
+ }
+ }
+
+ @Nested
+ @DisplayName("doctor master data")
+ class DoctorMasterTests {
+
+ @Test
+ @DisplayName("getMasterDataForDoctor should route cancer screening to the doctor master service")
+ void getMasterDataForDoctor_shouldRouteCancerScreening() {
+ when(doctorMasterDataServiceImpl.getCancerScreeningMasterDataForDoctor(PROVIDER_SERVICE_MAP_ID))
+ .thenReturn("cancer-doctor-master");
+
+ assertEquals("cancer-doctor-master",
+ service.getMasterDataForDoctor(1, PROVIDER_SERVICE_MAP_ID, GENDER, FACILITY_ID, VAN_ID));
+ }
+
+ @ParameterizedTest
+ @ValueSource(ints = { 2, 3, 4, 5, 6, 7, 8, 10 })
+ @DisplayName("getMasterDataForDoctor should route the remaining visit categories to the shared master service")
+ void getMasterDataForDoctor_shouldRouteRemainingCategories(int visitCategoryID) {
+ when(ancMasterDataServiceImpl.getCommonDoctorMasterDataForGenopdAncNcdcarePnc(anyInt(), anyInt(),
+ anyString(), any(), any())).thenReturn("shared-doctor-master");
+
+ assertEquals("shared-doctor-master", service.getMasterDataForDoctor(visitCategoryID,
+ PROVIDER_SERVICE_MAP_ID, GENDER, FACILITY_ID, VAN_ID));
+ }
+
+ @Test
+ @DisplayName("getMasterDataForDoctor should reject a visit category it does not know")
+ void getMasterDataForDoctor_shouldRejectUnknownCategory() {
+ assertEquals("Invalid VisitCategoryID",
+ service.getMasterDataForDoctor(99, PROVIDER_SERVICE_MAP_ID, GENDER, FACILITY_ID, VAN_ID));
+ }
+
+ @Test
+ @DisplayName("getMasterDataForDoctor should reject a request with no visit category")
+ void getMasterDataForDoctor_shouldRejectMissingCategory() {
+ assertEquals("Invalid VisitCategoryID",
+ service.getMasterDataForDoctor(null, PROVIDER_SERVICE_MAP_ID, GENDER, FACILITY_ID, VAN_ID));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/common/master/DoctorMasterDataServiceImplTest.java b/src/test/java/com/iemr/tm/service/common/master/DoctorMasterDataServiceImplTest.java
new file mode 100644
index 00000000..6062ae7f
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/common/master/DoctorMasterDataServiceImplTest.java
@@ -0,0 +1,59 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.common.master;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.masterrepo.anc.ServiceMasterRepo;
+import com.iemr.tm.repo.masterrepo.doctor.InstituteRepo;
+import com.iemr.tm.repo.masterrepo.doctor.PreMalignantLesionMasterRepo;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("DoctorMasterDataServiceImpl Test Suite")
+class DoctorMasterDataServiceImplTest {
+
+ @Mock
+ private PreMalignantLesionMasterRepo preMalignantLesionMasterRepo;
+ @Mock
+ private InstituteRepo instituteRepo;
+ @Mock
+ private ServiceMasterRepo serviceMasterRepo;
+
+ @InjectMocks
+ private DoctorMasterDataServiceImpl service;
+
+ @Test
+ @DisplayName("getCancerScreeningMasterDataForDoctor should answer for a well formed request")
+ void getCancerScreeningMasterDataForDoctor_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getCancerScreeningMasterDataForDoctor(9));
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/common/master/NCDCareMasterDataServiceImplTest.java b/src/test/java/com/iemr/tm/service/common/master/NCDCareMasterDataServiceImplTest.java
new file mode 100644
index 00000000..ef9f120f
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/common/master/NCDCareMasterDataServiceImplTest.java
@@ -0,0 +1,59 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.common.master;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.masterrepo.ncdCare.NCDCareTypeRepo;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("NCDCareMasterDataServiceImpl Test Suite")
+class NCDCareMasterDataServiceImplTest {
+
+ @Mock
+ private NCDScreeningMasterServiceImpl ncdScreeningMasterServiceImpl;
+ @Mock
+ private NCDCareTypeRepo ncdCareTypeRepo;
+
+ @InjectMocks
+ private NCDCareMasterDataServiceImpl service;
+
+ @Test
+ @DisplayName("getNCDCareMasterData should answer for a well formed request")
+ void getNCDCareMasterData_shouldAnswerForWellFormedRequest() throws Exception {
+ when(ncdScreeningMasterServiceImpl.getNCDScreeningConditions()).thenReturn(new java.util.ArrayList<>());
+ when(ncdCareTypeRepo.getNCDCareTypes()).thenReturn(new java.util.ArrayList<>());
+
+ assertDoesNotThrow(() -> service.getNCDCareMasterData());
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/common/master/NCDScreeningMasterServiceImplTest.java b/src/test/java/com/iemr/tm/service/common/master/NCDScreeningMasterServiceImplTest.java
new file mode 100644
index 00000000..17240d7d
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/common/master/NCDScreeningMasterServiceImplTest.java
@@ -0,0 +1,116 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.common.master;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.doctor.ChiefComplaintMasterRepo;
+import com.iemr.tm.repo.doctor.LabTestMasterRepo;
+import com.iemr.tm.repo.labModule.ProcedureRepo;
+import com.iemr.tm.repo.masterrepo.anc.AllergicReactionTypesRepo;
+import com.iemr.tm.repo.masterrepo.anc.DiseaseTypeRepo;
+import com.iemr.tm.repo.masterrepo.anc.PersonalHabitTypeRepo;
+import com.iemr.tm.repo.masterrepo.ncdScreening.BPAndDiabeticStatusRepo;
+import com.iemr.tm.repo.masterrepo.ncdScreening.IDRS_ScreenQuestionsRepo;
+import com.iemr.tm.repo.masterrepo.ncdScreening.NCDScreeningConditionRepo;
+import com.iemr.tm.repo.masterrepo.ncdScreening.NCDScreeningReasonRepo;
+import com.iemr.tm.repo.masterrepo.ncdScreening.PhysicalActivityRepo;
+import com.iemr.tm.repo.masterrepo.nurse.FamilyMemberMasterRepo;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("NCDScreeningMasterServiceImpl Test Suite")
+class NCDScreeningMasterServiceImplTest {
+
+ @Mock
+ private NCDScreeningConditionRepo ncdScreeningConditionRepo;
+ @Mock
+ private NCDScreeningReasonRepo ncdScreeningReasonRepo;
+ @Mock
+ private BPAndDiabeticStatusRepo bpAndDiabeticStatusRepo;
+ @Mock
+ private LabTestMasterRepo labTestMasterRepo;
+ @Mock
+ private ChiefComplaintMasterRepo chiefComplaintMasterRepo;
+ @Mock
+ private ProcedureRepo procedureRepo;
+ @Mock
+ private IDRS_ScreenQuestionsRepo iDRS_ScreenQuestionsRepo;
+ @Mock
+ private PhysicalActivityRepo physicalActivityRepo;
+ @Mock
+ private DiseaseTypeRepo diseaseTypeRepo;
+ @Mock
+ private FamilyMemberMasterRepo familyMemberMasterRepo;
+ @Mock
+ private PersonalHabitTypeRepo personalHabitTypeRepo;
+ @Mock
+ private AllergicReactionTypesRepo allergicReactionTypesRepo;
+
+ @InjectMocks
+ private NCDScreeningMasterServiceImpl service;
+
+ @Test
+ @DisplayName("getNCDScreeningConditions should answer for a well formed request")
+ void getNCDScreeningConditions_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getNCDScreeningConditions());
+ }
+
+ @Test
+ @DisplayName("getNCDScreeningReasons should answer for a well formed request")
+ void getNCDScreeningReasons_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getNCDScreeningReasons());
+ }
+
+ @Test
+ @DisplayName("getBPAndDiabeticStatus should answer for a well formed request")
+ void getBPAndDiabeticStatus_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBPAndDiabeticStatus(Boolean.FALSE));
+ }
+
+ @Test
+ @DisplayName("getNCDTest should answer for a well formed request")
+ void getNCDTest_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getNCDTest());
+ }
+
+ @Test
+ @DisplayName("getChiefComplaintMaster should answer for a well formed request")
+ void getChiefComplaintMaster_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getChiefComplaintMaster());
+ }
+
+ @Test
+ @DisplayName("getNCDScreeningMasterData should answer for a well formed request")
+ void getNCDScreeningMasterData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getNCDScreeningMasterData(9, 9, "{}"));
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/common/master/NurseMasterDataServiceImplTest.java b/src/test/java/com/iemr/tm/service/common/master/NurseMasterDataServiceImplTest.java
new file mode 100644
index 00000000..8d842105
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/common/master/NurseMasterDataServiceImplTest.java
@@ -0,0 +1,71 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.common.master;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.masterrepo.nurse.CancerDiseaseMasterRepo;
+import com.iemr.tm.repo.masterrepo.nurse.CancerPersonalHabitMasterRepo;
+import com.iemr.tm.repo.masterrepo.nurse.FamilyMemberMasterRepo;
+import com.iemr.tm.repo.masterrepo.nurse.VisitCategoryMasterRepo;
+import com.iemr.tm.repo.masterrepo.nurse.VisitReasonMasterRepo;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("NurseMasterDataServiceImpl Test Suite")
+class NurseMasterDataServiceImplTest {
+
+ @Mock
+ private CancerDiseaseMasterRepo cancerDiseaseMasterRepo;
+ @Mock
+ private CancerPersonalHabitMasterRepo cancerPersonalHabitMasterRepo;
+ @Mock
+ private FamilyMemberMasterRepo familyMemberMasterRepo;
+ @Mock
+ private VisitCategoryMasterRepo visitCategoryMasterRepo;
+ @Mock
+ private VisitReasonMasterRepo visitReasonMasterRepo;
+
+ @InjectMocks
+ private NurseMasterDataServiceImpl service;
+
+ @Test
+ @DisplayName("GetVisitReasonAndCategories should answer for a well formed request")
+ void GetVisitReasonAndCategories_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.GetVisitReasonAndCategories());
+ }
+
+ @Test
+ @DisplayName("getCancerScreeningMasterDataForNurse should answer for a well formed request")
+ void getCancerScreeningMasterDataForNurse_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getCancerScreeningMasterDataForNurse());
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/common/master/QCMasterDataServiceImplTest.java b/src/test/java/com/iemr/tm/service/common/master/QCMasterDataServiceImplTest.java
new file mode 100644
index 00000000..82dc1575
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/common/master/QCMasterDataServiceImplTest.java
@@ -0,0 +1,74 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.common.master;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.doctor.ChiefComplaintMasterRepo;
+import com.iemr.tm.repo.doctor.DrugDoseMasterRepo;
+import com.iemr.tm.repo.doctor.DrugDurationUnitMasterRepo;
+import com.iemr.tm.repo.doctor.DrugFormMasterRepo;
+import com.iemr.tm.repo.doctor.DrugFrequencyMasterRepo;
+import com.iemr.tm.repo.doctor.LabTestMasterRepo;
+import com.iemr.tm.repo.doctor.TempMasterDrugRepo;
+import com.iemr.tm.repo.labModule.ProcedureRepo;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("QCMasterDataServiceImpl Test Suite")
+class QCMasterDataServiceImplTest {
+
+ @Mock
+ private ChiefComplaintMasterRepo chiefComplaintMasterRepo;
+ @Mock
+ private DrugDoseMasterRepo drugDoseMasterRepo;
+ @Mock
+ private DrugDurationUnitMasterRepo drugDurationUnitMasterRepo;
+ @Mock
+ private DrugFormMasterRepo drugFormMasterRepo;
+ @Mock
+ private DrugFrequencyMasterRepo drugFrequencyMasterRepo;
+ @Mock
+ private LabTestMasterRepo labTestMasterRepo;
+ @Mock
+ private TempMasterDrugRepo tempMasterDrugRepo;
+ @Mock
+ private ProcedureRepo procedureRepo;
+
+ @InjectMocks
+ private QCMasterDataServiceImpl service;
+
+ @Test
+ @DisplayName("getQuickConsultMasterData should answer for a well formed request")
+ void getQuickConsultMasterData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getQuickConsultMasterData(9, "{}"));
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/common/master/RegistrarServiceMasterDataImplTest.java b/src/test/java/com/iemr/tm/service/common/master/RegistrarServiceMasterDataImplTest.java
new file mode 100644
index 00000000..27dbcfbe
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/common/master/RegistrarServiceMasterDataImplTest.java
@@ -0,0 +1,94 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.common.master;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.benFlowStatus.BeneficiaryFlowStatusRepo;
+import com.iemr.tm.repo.masterrepo.CommunityMasterRepo;
+import com.iemr.tm.repo.masterrepo.GenderMasterRepo;
+import com.iemr.tm.repo.masterrepo.GovIdEntityTypeRepo;
+import com.iemr.tm.repo.masterrepo.IncomeStatusMasterRepo;
+import com.iemr.tm.repo.masterrepo.MaritalStatusMasterRepo;
+import com.iemr.tm.repo.masterrepo.OccupationMasterRepo;
+import com.iemr.tm.repo.masterrepo.QualificationMasterRepo;
+import com.iemr.tm.repo.masterrepo.ReligionMasterRepo;
+import com.iemr.tm.repo.nurse.anc.ANCCareRepo;
+import com.iemr.tm.repo.registrar.BeneficiaryImageRepo;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("RegistrarServiceMasterDataImpl Test Suite")
+class RegistrarServiceMasterDataImplTest {
+
+ @Mock
+ private CommunityMasterRepo communityMasterRepo;
+ @Mock
+ private GenderMasterRepo genderMasterRepo;
+ @Mock
+ private GovIdEntityTypeRepo govIdEntityTypeRepo;
+ @Mock
+ private IncomeStatusMasterRepo incomeStatusMasterRepo;
+ @Mock
+ private MaritalStatusMasterRepo maritalStatusMasterRepo;
+ @Mock
+ private OccupationMasterRepo occupationMasterRepo;
+ @Mock
+ private QualificationMasterRepo qualificationMasterRepo;
+ @Mock
+ private ReligionMasterRepo religionMasterRepo;
+ @Mock
+ private BeneficiaryImageRepo beneficiaryImageRepo;
+ @Mock
+ private BeneficiaryFlowStatusRepo beneficiaryFlowStatusRepo;
+ @Mock
+ private ANCCareRepo aNCCareRepo;
+
+ @Mock
+ private com.iemr.tm.repo.registrar.ReistrarRepoBenSearch reistrarRepoBenSearch;
+
+ @InjectMocks
+ private RegistrarServiceMasterDataImpl service;
+
+ @Test
+ @DisplayName("getRegMasterData should answer for a well formed request")
+ void getRegMasterData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getRegMasterData());
+ }
+
+
+ @Test
+ @DisplayName("getBenDetailsForLeftSideByRegIDNew should answer for a well formed request")
+ void getBenDetailsForLeftSideByRegIDNew_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenDetailsForLeftSideByRegIDNew(11L, 11L, "{}", "{}"));
+ }
+
+}
diff --git a/src/test/java/com/iemr/tm/service/common/transaction/CommonDoctorServiceImplTest.java b/src/test/java/com/iemr/tm/service/common/transaction/CommonDoctorServiceImplTest.java
new file mode 100644
index 00000000..6f919a46
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/common/transaction/CommonDoctorServiceImplTest.java
@@ -0,0 +1,755 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.common.transaction;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyShort;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.iemr.tm.data.anc.WrapperAncFindings;
+import com.iemr.tm.data.quickConsultation.BenClinicalObservations;
+import com.iemr.tm.data.login.Users;
+import com.iemr.tm.data.quickConsultation.BenChiefComplaint;
+import com.iemr.tm.data.snomedct.SCTDescription;
+import com.iemr.tm.repo.benFlowStatus.BeneficiaryFlowStatusRepo;
+import com.iemr.tm.repo.quickConsultation.BenClinicalObservationsRepo;
+import com.iemr.tm.repo.doctor.BenReferDetailsRepo;
+import com.iemr.tm.repo.login.UserLoginRepo;
+import com.iemr.tm.repo.nurse.BenVisitDetailRepo;
+import com.iemr.tm.repo.quickConsultation.BenChiefComplaintRepo;
+import com.iemr.tm.repo.quickConsultation.LabTestOrderDetailRepo;
+import com.iemr.tm.repo.quickConsultation.PrescribedDrugDetailRepo;
+import com.iemr.tm.repo.quickConsultation.PrescriptionDetailRepo;
+import com.iemr.tm.service.benFlowStatus.CommonBenStatusFlowServiceImpl;
+import com.iemr.tm.service.snomedct.SnomedServiceImpl;
+import com.iemr.tm.service.tele_consultation.SMSGatewayServiceImpl;
+import com.iemr.tm.utils.CookieUtil;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("CommonDoctorServiceImpl Test Suite")
+class CommonDoctorServiceImplTest {
+
+ private static final Long BEN_REG_ID = 11L;
+ private static final Long VISIT_CODE = 22L;
+
+ @Mock
+ private BenClinicalObservationsRepo benClinicalObservationsRepo;
+ @Mock
+ private BenChiefComplaintRepo benChiefComplaintRepo;
+ @Mock
+ private com.iemr.tm.repo.doctor.DocWorkListRepo docWorkListRepo;
+ @Mock
+ private BenReferDetailsRepo benReferDetailsRepo;
+ @Mock
+ private LabTestOrderDetailRepo labTestOrderDetailRepo;
+ @Mock
+ private PrescribedDrugDetailRepo prescribedDrugDetailRepo;
+ @Mock
+ private SnomedServiceImpl snomedServiceImpl;
+ @Mock
+ private CommonBenStatusFlowServiceImpl commonBenStatusFlowServiceImpl;
+ @Mock
+ private BeneficiaryFlowStatusRepo beneficiaryFlowStatusRepo;
+ @Mock
+ private com.iemr.tm.repo.tc_consultation.TCRequestModelRepo tCRequestModelRepo;
+ @Mock
+ private com.iemr.tm.repo.nurse.pnc.PNCDiagnosisRepo pNCDiagnosisRepo;
+ @Mock
+ private BenVisitDetailRepo benVisitDetailRepo;
+ @Mock
+ private UserLoginRepo userLoginRepo;
+ @Mock
+ private PrescriptionDetailRepo prescriptionDetailRepo;
+ @Mock
+ private com.iemr.tm.repo.nurse.ncdcare.NCDCareDiagnosisRepo NCDCareDiagnosisRepo;
+ @Mock
+ private SMSGatewayServiceImpl sMSGatewayServiceImpl;
+ @Mock
+ private com.iemr.tm.repo.foetalmonitor.FoetalMonitorRepo foetalMonitorRepo;
+ @Mock
+ private CookieUtil cookieUtil;
+ @Mock
+ private com.iemr.tm.repo.tc_consultation.TeleconsultationStatsRepo teleconsultationStatsRepo;
+
+ @InjectMocks
+ private CommonDoctorServiceImpl service;
+
+ private static org.mockito.stubbing.Answer echoList() {
+ return invocation -> invocation.getArgument(0);
+ }
+
+ private JsonObject json(String raw) {
+ return JsonParser.parseString(raw).getAsJsonObject();
+ }
+
+ private WrapperAncFindings findings(String complaint) {
+ ArrayList complaints = new ArrayList<>();
+ BenChiefComplaint chiefComplaint = new BenChiefComplaint();
+ chiefComplaint.setChiefComplaint(complaint);
+ complaints.add(chiefComplaint);
+ WrapperAncFindings wrapper = new WrapperAncFindings(BEN_REG_ID, 3L, 9, "Clinical observation", "Fever",
+ "Significant findings", complaints, Boolean.FALSE, VISIT_CODE);
+ wrapper.setCreatedBy("doctor1");
+ return wrapper;
+ }
+
+ private ArrayList oneEmptyRow() {
+ ArrayList rows = new ArrayList<>();
+ rows.add(new Object[60]);
+ return rows;
+ }
+
+ @Nested
+ @DisplayName("findings")
+ class FindingsTests {
+
+ @Test
+ @DisplayName("saveFindings should confirm the stored clinical observation")
+ void saveFindings_shouldConfirmStoredObservation() throws Exception {
+ when(benClinicalObservationsRepo.save(any())).thenReturn(new BenClinicalObservations());
+
+ assertEquals(1, service.saveFindings(json("{\"beneficiaryRegID\":11}")));
+ }
+
+ @Test
+ @DisplayName("saveFindings should report no change when nothing was stored")
+ void saveFindings_shouldReportNoChangeWhenNothingStored() throws Exception {
+ when(benClinicalObservationsRepo.save(any())).thenReturn(null);
+
+ assertEquals(0, service.saveFindings(json("{\"beneficiaryRegID\":11}")));
+ }
+
+ @Test
+ @DisplayName("saveDocFindings should store the observation and the named chief complaints")
+ void saveDocFindings_shouldStoreObservationAndComplaints() {
+ when(benClinicalObservationsRepo.save(any())).thenReturn(new BenClinicalObservations());
+ when(benChiefComplaintRepo.saveAll(any())).thenAnswer(echoList());
+
+ assertEquals(1, service.saveDocFindings(findings("Fever")));
+ verify(benChiefComplaintRepo).saveAll(any());
+ }
+
+ @Test
+ @DisplayName("saveDocFindings should skip an unnamed chief complaint")
+ void saveDocFindings_shouldSkipUnnamedComplaint() {
+ when(benClinicalObservationsRepo.save(any())).thenReturn(new BenClinicalObservations());
+
+ assertEquals(1, service.saveDocFindings(findings(null)));
+ verify(benChiefComplaintRepo, never()).saveAll(any());
+ }
+
+ @Test
+ @DisplayName("saveDocFindings should report no change when the observation was not stored")
+ void saveDocFindings_shouldReportNoChangeWhenObservationNotStored() {
+ when(benClinicalObservationsRepo.save(any())).thenReturn(null);
+
+ assertEquals(0, service.saveDocFindings(findings(null)));
+ }
+
+ @Test
+ @DisplayName("updateDocFindings should update the observation and replace the chief complaints")
+ void updateDocFindings_shouldUpdateObservationAndReplaceComplaints() {
+ when(benClinicalObservationsRepo.getBenClinicalObservationStatus(BEN_REG_ID, VISIT_CODE)).thenReturn("P");
+ when(benClinicalObservationsRepo.updateBenClinicalObservations(any(), any(), any(), any(), any(), any(),
+ any(), any(), any(), any())).thenReturn(1);
+ when(benChiefComplaintRepo.saveAll(any())).thenAnswer(echoList());
+
+ assertNotNull(service.updateDocFindings(findings("Fever")));
+ }
+
+ @Test
+ @DisplayName("fetchBenPreviousSignificantFindings should render the earlier findings")
+ void fetchPreviousFindings_shouldRenderEarlierFindings() {
+ when(benClinicalObservationsRepo.getPreviousSignificantFindings(BEN_REG_ID))
+ .thenReturn(new ArrayList<>());
+
+ assertNotNull(service.fetchBenPreviousSignificantFindings(BEN_REG_ID));
+ }
+
+ @Test
+ @DisplayName("getFindingsDetails should assemble the observation and the chief complaints")
+ void getFindingsDetails_shouldAssembleFindings() {
+ when(benClinicalObservationsRepo.getFindingsData(BEN_REG_ID, VISIT_CODE)).thenReturn(oneEmptyRow());
+ when(benChiefComplaintRepo.getBenChiefComplaints(BEN_REG_ID, VISIT_CODE)).thenReturn(oneEmptyRow());
+
+ assertNotNull(service.getFindingsDetails(BEN_REG_ID, VISIT_CODE));
+ }
+ }
+
+ @Nested
+ @DisplayName("SNOMED lookups")
+ class SnomedTests {
+
+ @Test
+ @DisplayName("getSnomedCTcode should map every term of a comma separated list")
+ void getSnomedCTcode_shouldMapEveryTerm() {
+ SCTDescription fever = new SCTDescription();
+ fever.setConceptID("386661006");
+ fever.setTerm("Fever");
+ when(snomedServiceImpl.findSnomedCTRecordFromTerm(anyString())).thenReturn(fever);
+
+ String[] result = service.getSnomedCTcode("Fever,Cough");
+
+ assertEquals("386661006,386661006", result[0]);
+ assertEquals("Fever,Fever", result[1]);
+ }
+
+ @Test
+ @DisplayName("getSnomedCTcode should leave an unmatched term blank")
+ void getSnomedCTcode_shouldLeaveUnmatchedTermBlank() {
+ when(snomedServiceImpl.findSnomedCTRecordFromTerm(anyString())).thenReturn(null);
+
+ assertNotNull(service.getSnomedCTcode("Fever"));
+ }
+
+ @Test
+ @DisplayName("getSnomedCTcode should return empty codes for a blank request")
+ void getSnomedCTcode_shouldReturnEmptyCodesForBlankRequest() {
+ assertNotNull(service.getSnomedCTcode(""));
+ }
+ }
+
+ @Nested
+ @DisplayName("worklists")
+ class WorklistTests {
+
+ @Test
+ @DisplayName("getDocWorkList should render the doctor worklist")
+ void getDocWorkList_shouldRenderWorklist() {
+ when(docWorkListRepo.getDocWorkList()).thenReturn(new ArrayList<>());
+
+ assertNotNull(service.getDocWorkList());
+ }
+
+ @Test
+ @DisplayName("getDocWorkListNew should render the general OPD doctor worklist")
+ void getDocWorkListNew_shouldRenderGeneralWorklist() {
+ when(beneficiaryFlowStatusRepo.getDocWorkListNew(9)).thenReturn(new ArrayList<>());
+
+ assertEquals("[]", service.getDocWorkListNew(9, 2, 7));
+ }
+
+ @Test
+ @DisplayName("getDocWorkListNew should render the teleconsultation doctor worklist")
+ void getDocWorkListNew_shouldRenderTeleconsultationWorklist() {
+ ReflectionTestUtils.setField(service, "docWL", 7);
+ when(beneficiaryFlowStatusRepo.getDocWorkListNewTC(any(), any(), any())).thenReturn(new ArrayList<>());
+
+ assertEquals("[]", service.getDocWorkListNew(9, 4, 7));
+ }
+
+ @Test
+ @DisplayName("getDocWorkListNew should render an empty worklist for an unknown service")
+ void getDocWorkListNew_shouldRenderEmptyWorklistForUnknownService() {
+ assertEquals("[]", service.getDocWorkListNew(9, 99, 7));
+ }
+
+ @Test
+ @DisplayName("getDocWorkListNewFutureScheduledForTM should render the future scheduled worklist")
+ void getDocWorkListFutureScheduled_shouldRenderWorklist() {
+ when(beneficiaryFlowStatusRepo.getDocWorkListNewFutureScheduledTC(any(), any()))
+ .thenReturn(new ArrayList<>());
+
+ assertNotNull(service.getDocWorkListNewFutureScheduledForTM(9, 4, 7));
+ }
+
+ @Test
+ @DisplayName("getTCSpecialistWorkListNewForTMPatientApp should render the patient app worklist")
+ void getTCSpecialistWorkListPatientApp_shouldRenderWorklist() {
+ ReflectionTestUtils.setField(service, "tcSpeclistWL", 7);
+ when(beneficiaryFlowStatusRepo.getTCSpecialistWorkListNewPatientApp(any(), any(), any(), any()))
+ .thenReturn(new ArrayList<>());
+
+ assertNotNull(service.getTCSpecialistWorkListNewForTMPatientApp(9, 42, 4, 7));
+ }
+
+ @Test
+ @DisplayName("getTCSpecialistWorkListNewForTM should render the specialist worklist")
+ void getTCSpecialistWorkList_shouldRenderWorklist() {
+ when(beneficiaryFlowStatusRepo.getTCSpecialistWorkListNew(any(), any(), any()))
+ .thenReturn(new ArrayList<>());
+
+ assertNotNull(service.getTCSpecialistWorkListNewForTM(9, 42, 4));
+ }
+
+ @Test
+ @DisplayName("getTCSpecialistWorkListNewFutureScheduledForTM should render the future specialist worklist")
+ void getTCSpecialistWorkListFutureScheduled_shouldRenderWorklist() {
+ when(beneficiaryFlowStatusRepo.getTCSpecialistWorkListNewFutureScheduled(any(), any()))
+ .thenReturn(new ArrayList<>());
+
+ assertNotNull(service.getTCSpecialistWorkListNewFutureScheduledForTM(9, 42, 4));
+ }
+ }
+
+ @Nested
+ @DisplayName("referrals and case record reads")
+ class ReferralAndReadTests {
+
+ @Test
+ @DisplayName("saveBenReferDetails should store the referral for every additional service")
+ void saveReferDetails_shouldStoreReferralPerService() throws Exception {
+ when(benReferDetailsRepo.saveAll(any())).thenAnswer(echoList());
+
+ Long result = service.saveBenReferDetails(json("{\"beneficiaryRegID\":11,\"visitCode\":22,"
+ + "\"refrredToAdditionalServiceList\":[{\"serviceName\":\"Radiology\"}],"
+ + "\"referredToInstituteName\":\"District Hospital\"}"));
+
+ assertNotNull(result);
+ }
+
+ @Test
+ @DisplayName("saveBenReferDetails should store a referral without any additional service")
+ void saveReferDetails_shouldStoreReferralWithoutAdditionalService() throws Exception {
+ when(benReferDetailsRepo.saveAll(any())).thenAnswer(echoList());
+
+ assertNotNull(service.saveBenReferDetails(json("{\"beneficiaryRegID\":11,\"visitCode\":22,"
+ + "\"referredToInstituteName\":\"District Hospital\"}")));
+ }
+
+ @Test
+ @DisplayName("getInvestigationDetails should render the ordered lab tests")
+ void getInvestigationDetails_shouldRenderOrderedTests() {
+ when(labTestOrderDetailRepo.getLabTestOrderDetails(BEN_REG_ID, VISIT_CODE)).thenReturn(new ArrayList<>());
+
+ assertNotNull(service.getInvestigationDetails(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getPrescribedDrugs should render the prescribed drugs")
+ void getPrescribedDrugs_shouldRenderPrescribedDrugs() {
+ when(prescribedDrugDetailRepo.getBenPrescribedDrugDetails(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(new ArrayList<>());
+
+ assertNotNull(service.getPrescribedDrugs(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getReferralDetails should render the referral")
+ void getReferralDetails_shouldRenderReferral() {
+ when(benReferDetailsRepo.getBenReferDetails(BEN_REG_ID, VISIT_CODE)).thenReturn(new ArrayList<>());
+
+ assertNotNull(service.getReferralDetails(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getFoetalMonitorData should render the foetal monitor readings")
+ void getFoetalMonitorData_shouldRenderReadings() {
+ when(foetalMonitorRepo.getFoetalMonitorDetailsForCaseRecord(BEN_REG_ID, VISIT_CODE)).thenReturn(new ArrayList<>());
+
+ assertNotNull(service.getFoetalMonitorData(BEN_REG_ID, VISIT_CODE));
+ }
+ }
+
+ @Nested
+ @DisplayName("updates")
+ class UpdateTests {
+
+ @Test
+ @DisplayName("updateDoctorBenChiefComplaints should replace the stored complaints")
+ void updateChiefComplaints_shouldReplaceStoredComplaints() {
+ BenChiefComplaint complaint = new BenChiefComplaint();
+ complaint.setBeneficiaryRegID(BEN_REG_ID);
+ complaint.setVisitCode(VISIT_CODE);
+ when(benChiefComplaintRepo.saveAll(any())).thenAnswer(echoList());
+
+ assertEquals(1, service.updateDoctorBenChiefComplaints(Collections.singletonList(complaint)));
+ }
+
+ @Test
+ @DisplayName("updateDoctorBenChiefComplaints should succeed for an empty list")
+ void updateChiefComplaints_shouldSucceedForEmptyList() {
+ assertEquals(1, service.updateDoctorBenChiefComplaints(Collections.emptyList()));
+ }
+
+ @Test
+ @DisplayName("updateBenClinicalObservations should mark an already processed observation as updated")
+ void updateClinicalObservations_shouldMarkProcessedAsUpdated() {
+ BenClinicalObservations observations = new BenClinicalObservations();
+ observations.setBeneficiaryRegID(BEN_REG_ID);
+ observations.setVisitCode(VISIT_CODE);
+ when(benClinicalObservationsRepo.getBenClinicalObservationStatus(BEN_REG_ID, VISIT_CODE)).thenReturn("P");
+
+ assertEquals(0, service.updateBenClinicalObservations(observations));
+ }
+
+ @Test
+ @DisplayName("updateBenClinicalObservations should report no change for a null payload")
+ void updateClinicalObservations_shouldReportNoChangeForNullPayload() {
+ assertEquals(0, service.updateBenClinicalObservations(null));
+ }
+
+ @Test
+ @DisplayName("updateBenReferDetails should update the referral for the visit")
+ void updateReferDetails_shouldUpdateReferral() throws Exception {
+ when(benReferDetailsRepo.saveAll(any())).thenAnswer(echoList());
+
+ assertNotNull(service.updateBenReferDetails(json("{\"beneficiaryRegID\":11,\"visitCode\":22,"
+ + "\"referredToInstituteName\":\"District Hospital\"}")));
+ }
+
+ @Test
+ @DisplayName("deletePrescribedMedicine should confirm the deletion")
+ void deletePrescribedMedicine_shouldConfirmDeletion() throws Exception {
+ when(prescribedDrugDetailRepo.deletePrescribedmedicine(4L)).thenReturn(1);
+
+ assertEquals("record deleted successfully",
+ service.deletePrescribedMedicine(new org.json.JSONObject().put("id", 4L)));
+ }
+
+ @Test
+ @DisplayName("deletePrescribedMedicine should return nothing when no row was deleted")
+ void deletePrescribedMedicine_shouldReturnNothingWhenNoRowDeleted() throws Exception {
+ when(prescribedDrugDetailRepo.deletePrescribedmedicine(4L)).thenReturn(0);
+
+ assertNull(service.deletePrescribedMedicine(new org.json.JSONObject().put("id", 4L)));
+ }
+
+ @Test
+ @DisplayName("deletePrescribedMedicine should return nothing for a request without an id")
+ void deletePrescribedMedicine_shouldReturnNothingWithoutId() {
+ assertNull(service.deletePrescribedMedicine(new org.json.JSONObject()));
+ }
+ }
+
+ @Nested
+ @DisplayName("beneficiary flow after doctor data")
+ class BeneficiaryFlowTests {
+
+ private com.iemr.tm.data.nurse.CommonUtilityClass utility(boolean isSpecialist) {
+ com.iemr.tm.data.nurse.CommonUtilityClass utility = new com.iemr.tm.data.nurse.CommonUtilityClass();
+ utility.setBenFlowID(5L);
+ utility.setBeneficiaryID(7L);
+ utility.setBenVisitID(3L);
+ utility.setBeneficiaryRegID(BEN_REG_ID);
+ utility.setVisitCode(VISIT_CODE);
+ utility.setVisitCategoryID(1);
+ utility.setIsSpecialist(isSpecialist);
+ utility.setCreatedBy("doctor1");
+ utility.setAuthorization("Bearer session-token");
+ return utility;
+ }
+
+ @Test
+ @DisplayName("updateBenFlowtableAfterDocDataSave should route a doctor visit that ordered a test to the lab")
+ void updateFlowAfterSave_shouldRouteTestToLab() throws Exception {
+ when(commonBenStatusFlowServiceImpl.updateBenFlowAfterDocData(any(), any(), any(), any(), anyShort(),
+ anyShort(), anyShort(), anyShort(), anyInt(), any(), anyShort(), any())).thenReturn(1);
+
+ assertEquals(1, service.updateBenFlowtableAfterDocDataSave(utility(false), true, true, null, false));
+ }
+
+ @Test
+ @DisplayName("updateBenFlowtableAfterDocDataSave should close the visit when nothing was prescribed")
+ void updateFlowAfterSave_shouldCloseVisitWithoutPrescriptions() throws Exception {
+ when(commonBenStatusFlowServiceImpl.updateBenFlowAfterDocData(any(), any(), any(), any(), anyShort(),
+ anyShort(), anyShort(), anyShort(), anyInt(), any(), anyShort(), any())).thenReturn(1);
+
+ assertEquals(1, service.updateBenFlowtableAfterDocDataSave(utility(false), false, false, null, false));
+ }
+
+ @Test
+ @DisplayName("updateBenFlowtableAfterDocDataSave should route a specialist visit through the specialist flow")
+ void updateFlowAfterSave_shouldRouteSpecialistVisit() throws Exception {
+ when(commonBenStatusFlowServiceImpl.updateBenFlowAfterDocDataFromSpecialist(any(), any(), any(), any(),
+ anyShort(), anyShort(), anyShort(), anyShort(), anyShort(), any())).thenReturn(1);
+
+ assertEquals(1, service.updateBenFlowtableAfterDocDataSave(utility(true), false, false, null, false));
+ }
+
+ @Test
+ @DisplayName("updateBenFlowtableAfterDocDataSave should read the foetal monitor state for an ANC visit")
+ void updateFlowAfterSave_shouldReadFoetalMonitorStateForAncVisit() throws Exception {
+ com.iemr.tm.data.nurse.CommonUtilityClass utility = utility(false);
+ utility.setVisitCategoryID(4);
+ com.iemr.tm.data.foetalmonitor.FoetalMonitor monitor = new com.iemr.tm.data.foetalmonitor.FoetalMonitor();
+ monitor.setResultState(false);
+ when(foetalMonitorRepo.getFoetalMonitorDetailsByFlowId(5L))
+ .thenReturn(new ArrayList<>(Collections.singletonList(monitor)));
+ when(commonBenStatusFlowServiceImpl.updateBenFlowAfterDocData(any(), any(), any(), any(), anyShort(),
+ anyShort(), anyShort(), anyShort(), anyInt(), any(), anyShort(), any())).thenReturn(1);
+
+ assertEquals(1, service.updateBenFlowtableAfterDocDataSave(utility, false, false, null, false));
+ verify(foetalMonitorRepo).updateVisitCode(VISIT_CODE, 5L);
+ }
+
+ @Test
+ @DisplayName("updateBenFlowtableAfterDocDataUpdate should advance the flow for a doctor visit")
+ void updateFlowAfterUpdate_shouldAdvanceFlow() throws Exception {
+ when(commonBenStatusFlowServiceImpl.updateBenFlowAfterDocDataUpdate(any(), any(), any(), any(), anyShort(),
+ anyShort(), anyShort(), anyShort(), anyInt(), any(), anyShort(), any())).thenReturn(1);
+
+ assertEquals(1, service.updateBenFlowtableAfterDocDataUpdate(utility(false), true, true, null, false));
+ }
+
+ @Test
+ @DisplayName("updateBenFlowtableAfterDocDataUpdate should advance the flow for a specialist visit")
+ void updateFlowAfterUpdate_shouldAdvanceSpecialistFlow() throws Exception {
+ when(commonBenStatusFlowServiceImpl.updateBenFlowAfterDocDataUpdateTCSpecialist(any(), any(), any(), any(),
+ anyShort(), anyShort(), anyShort(), anyShort(), anyInt(), any(), anyShort(), any())).thenReturn(1);
+
+ assertEquals(1, service.updateBenFlowtableAfterDocDataUpdate(utility(true), false, false, null, false));
+ }
+
+ @Test
+ @DisplayName("createTMPrescriptionSms should do nothing when the prescription has no drug")
+ void createPrescriptionSms_shouldDoNothingWithoutDrugs() throws Exception {
+ when(prescribedDrugDetailRepo.getPrescriptionDetails(any())).thenReturn(new ArrayList<>());
+
+ service.createTMPrescriptionSms(utility(false));
+
+ verify(sMSGatewayServiceImpl, never()).smsSenderGateway2(anyString(), any(), any(), any(), any(), any());
+ }
+ }
+
+ @Nested
+ @DisplayName("teleconsultation flow and prescription SMS")
+ class TeleconsultationFlowTests {
+
+ private com.iemr.tm.data.nurse.CommonUtilityClass utility(boolean isSpecialist, Integer visitCategoryID) {
+ com.iemr.tm.data.nurse.CommonUtilityClass utility = new com.iemr.tm.data.nurse.CommonUtilityClass();
+ utility.setBenFlowID(5L);
+ utility.setBeneficiaryID(7L);
+ utility.setBenVisitID(3L);
+ utility.setBeneficiaryRegID(BEN_REG_ID);
+ utility.setVisitCode(VISIT_CODE);
+ utility.setVisitCategoryID(visitCategoryID);
+ utility.setIsSpecialist(isSpecialist);
+ utility.setCreatedBy("doctor1");
+ utility.setPrescriptionID(31L);
+ utility.setAuthorization("Bearer session-token");
+ return utility;
+ }
+
+ private com.iemr.tm.data.tele_consultation.TeleconsultationRequestOBJ tcRequest() {
+ com.iemr.tm.data.tele_consultation.TeleconsultationRequestOBJ tcRequest =
+ new com.iemr.tm.data.tele_consultation.TeleconsultationRequestOBJ();
+ tcRequest.setUserID(41);
+ tcRequest.setSpecializationID(3);
+ tcRequest.setAllocationDate(new java.sql.Timestamp(System.currentTimeMillis()));
+ return tcRequest;
+ }
+
+ @Test
+ @DisplayName("updateBenFlowtableAfterDocDataSave should hand a scheduled visit to the specialist")
+ void updateFlowAfterSave_shouldHandScheduledVisitToSpecialist() throws Exception {
+ when(commonBenStatusFlowServiceImpl.updateBenFlowAfterDocData(any(), any(), any(), any(), anyShort(),
+ anyShort(), anyShort(), anyShort(), anyInt(), any(), anyShort(), any())).thenReturn(1);
+
+ assertEquals(1, service.updateBenFlowtableAfterDocDataSave(utility(false, 1), false, true, tcRequest(),
+ true));
+ }
+
+ @Test
+ @DisplayName("updateBenFlowtableAfterDocDataUpdate should hand a scheduled visit to the specialist")
+ void updateFlowAfterUpdate_shouldHandScheduledVisitToSpecialist() throws Exception {
+ when(commonBenStatusFlowServiceImpl.updateBenFlowAfterDocDataUpdate(any(), any(), any(), any(), anyShort(),
+ anyShort(), anyShort(), anyShort(), anyInt(), any(), anyShort(), any())).thenReturn(1);
+
+ assertEquals(1, service.updateBenFlowtableAfterDocDataUpdate(utility(false, 1), false, true, tcRequest(),
+ true));
+ }
+
+ @Test
+ @DisplayName("updateBenFlowtableAfterDocDataUpdate should close the specialist consultation and stamp its end time")
+ void updateFlowAfterUpdate_shouldCloseSpecialistConsultation() throws Exception {
+ com.iemr.tm.data.tele_consultation.TeleconsultationStats stats =
+ new com.iemr.tm.data.tele_consultation.TeleconsultationStats();
+ when(teleconsultationStatsRepo.getLatestStartTime(BEN_REG_ID, VISIT_CODE)).thenReturn(stats);
+ when(commonBenStatusFlowServiceImpl.updateBenFlowAfterDocDataUpdateTCSpecialist(any(), any(), any(), any(),
+ anyShort(), anyShort(), anyShort(), anyShort(), anyInt(), any(), anyShort(), any())).thenReturn(1);
+ when(prescribedDrugDetailRepo.getPrescriptionDetails(any())).thenReturn(new ArrayList<>());
+
+ assertEquals(1, service.updateBenFlowtableAfterDocDataUpdate(utility(true, 1), false, true, null, true));
+
+ verify(teleconsultationStatsRepo).save(stats);
+ verify(tCRequestModelRepo).updateStatusIfConsultationCompleted(BEN_REG_ID, VISIT_CODE, "D");
+ }
+
+ @Test
+ @DisplayName("updateBenFlowtableAfterDocDataUpdate should start a fresh stats entry when the last one is closed")
+ void updateFlowAfterUpdate_shouldStartFreshStatsEntry() throws Exception {
+ com.iemr.tm.data.tele_consultation.TeleconsultationStats stats =
+ new com.iemr.tm.data.tele_consultation.TeleconsultationStats();
+ stats.settMStatsID(8L);
+ stats.setEndTime(new java.sql.Timestamp(System.currentTimeMillis()));
+ when(teleconsultationStatsRepo.getLatestStartTime(BEN_REG_ID, VISIT_CODE)).thenReturn(stats);
+ when(commonBenStatusFlowServiceImpl.updateBenFlowAfterDocDataUpdateTCSpecialist(any(), any(), any(), any(),
+ anyShort(), anyShort(), anyShort(), anyShort(), anyInt(), any(), anyShort(), any())).thenReturn(1);
+
+ assertEquals(1, service.updateBenFlowtableAfterDocDataUpdate(utility(true, 1), true, false, null, true));
+
+ org.mockito.ArgumentCaptor captor =
+ org.mockito.ArgumentCaptor.forClass(com.iemr.tm.data.tele_consultation.TeleconsultationStats.class);
+ verify(teleconsultationStatsRepo).save(captor.capture());
+ org.junit.jupiter.api.Assertions.assertNull(captor.getValue().gettMStatsID());
+ }
+
+ @Test
+ @DisplayName("updateBenFlowtableAfterDocDataUpdate should read the foetal monitor state for an ANC visit")
+ void updateFlowAfterUpdate_shouldReadFoetalMonitorStateForAncVisit() throws Exception {
+ com.iemr.tm.data.foetalmonitor.FoetalMonitor monitor = new com.iemr.tm.data.foetalmonitor.FoetalMonitor();
+ monitor.setResultState(true);
+ when(foetalMonitorRepo.getFoetalMonitorDetailsByFlowId(5L))
+ .thenReturn(new ArrayList<>(Collections.singletonList(monitor)));
+ when(commonBenStatusFlowServiceImpl.updateBenFlowAfterDocDataUpdate(any(), any(), any(), any(), anyShort(),
+ anyShort(), anyShort(), anyShort(), anyInt(), any(), anyShort(), any())).thenReturn(1);
+ when(prescribedDrugDetailRepo.getPrescriptionDetails(any())).thenReturn(new ArrayList<>());
+
+ assertEquals(1, service.updateBenFlowtableAfterDocDataUpdate(utility(false, 4), false, false, null, true));
+ verify(foetalMonitorRepo).updateVisitCode(VISIT_CODE, 5L);
+ }
+
+ private java.util.List onePrescribedDrug() {
+ com.iemr.tm.data.quickConsultation.PrescribedDrugDetail drug = new com.iemr.tm.data.quickConsultation.PrescribedDrugDetail();
+ drug.setDrugName("Paracetamol");
+ return new ArrayList<>(Collections.singletonList(drug));
+ }
+
+ @Test
+ @DisplayName("createTMPrescriptionSms should read the provisional diagnosis for a general OPD prescription")
+ void createPrescriptionSms_shouldReadProvisionalDiagnosis() throws Exception {
+ when(prescribedDrugDetailRepo.getPrescriptionDetails(31L)).thenReturn(onePrescribedDrug());
+ when(prescriptionDetailRepo.getProvisionalDiagnosis(VISIT_CODE, 31L)).thenReturn(new ArrayList<>());
+ when(sMSGatewayServiceImpl.smsSenderGateway2(anyString(), any(), any(), any(), any(), any()))
+ .thenReturn(1);
+
+ service.createTMPrescriptionSms(utility(false, 6));
+
+ verify(sMSGatewayServiceImpl).smsSenderGateway2(eq("prescription"), any(), anyString(), eq(BEN_REG_ID),
+ anyString(), any());
+ }
+
+ @Test
+ @DisplayName("createTMPrescriptionSms should read the NCD condition for an NCD care prescription")
+ void createPrescriptionSms_shouldReadNcdCondition() throws Exception {
+ when(prescribedDrugDetailRepo.getPrescriptionDetails(31L)).thenReturn(onePrescribedDrug());
+ when(NCDCareDiagnosisRepo.getNCDcondition(VISIT_CODE, 31L)).thenReturn(new ArrayList<>());
+
+ service.createTMPrescriptionSms(utility(false, 3));
+
+ verify(NCDCareDiagnosisRepo).getNCDcondition(VISIT_CODE, 31L);
+ }
+
+ @Test
+ @DisplayName("createTMPrescriptionSms should read the PNC diagnosis for a PNC prescription")
+ void createPrescriptionSms_shouldReadPncDiagnosis() throws Exception {
+ when(prescribedDrugDetailRepo.getPrescriptionDetails(31L)).thenReturn(onePrescribedDrug());
+ when(pNCDiagnosisRepo.getProvisionalDiagnosis(VISIT_CODE, 31L)).thenReturn(new ArrayList<>());
+
+ service.createTMPrescriptionSms(utility(false, 5));
+
+ verify(pNCDiagnosisRepo).getProvisionalDiagnosis(VISIT_CODE, 31L);
+ }
+
+ @Test
+ @DisplayName("createTMPrescriptionSms should still send when the diagnosis lookup fails")
+ void createPrescriptionSms_shouldStillSendWhenDiagnosisLookupFails() throws Exception {
+ when(prescribedDrugDetailRepo.getPrescriptionDetails(31L)).thenReturn(onePrescribedDrug());
+ when(prescriptionDetailRepo.getProvisionalDiagnosis(VISIT_CODE, 31L))
+ .thenThrow(new RuntimeException("diagnosis unavailable"));
+
+ service.createTMPrescriptionSms(utility(false, 7));
+
+ verify(sMSGatewayServiceImpl).smsSenderGateway2(eq("prescription"), any(), anyString(), eq(BEN_REG_ID),
+ anyString(), any());
+ }
+
+ @Test
+ @DisplayName("createTMPrescriptionSms should absorb a failure from the SMS gateway")
+ void createPrescriptionSms_shouldAbsorbGatewayFailure() throws Exception {
+ when(prescribedDrugDetailRepo.getPrescriptionDetails(31L)).thenReturn(onePrescribedDrug());
+ when(sMSGatewayServiceImpl.smsSenderGateway2(anyString(), any(), any(), any(), any(), any()))
+ .thenThrow(new RuntimeException("gateway down"));
+
+ org.junit.jupiter.api.Assertions.assertDoesNotThrow(
+ () -> service.createTMPrescriptionSms(utility(false, 8)));
+ }
+
+ @Test
+ @DisplayName("callTmForSpecialistSlotBook should confirm a booked slot")
+ void callTmForSlotBook_shouldConfirmBookedSlot() {
+ new com.iemr.tm.utils.mapper.OutputMapper();
+ org.springframework.test.util.ReflectionTestUtils.setField(service, "tcSpecialistSlotBook",
+ "http://common/tc/specialistSlotBook");
+
+ try (org.mockito.MockedConstruction ignored =
+ org.mockito.Mockito.mockConstruction(org.springframework.web.client.RestTemplate.class,
+ (restTemplate, context) -> when(restTemplate.exchange(anyString(),
+ any(org.springframework.http.HttpMethod.class), any(),
+ org.mockito.ArgumentMatchers.>any()))
+ .thenReturn(new org.springframework.http.ResponseEntity<>(
+ "{\"statusCode\":200}", org.springframework.http.HttpStatus.OK)))) {
+ assertEquals(1, service.callTmForSpecialistSlotBook(
+ new com.iemr.tm.data.tele_consultation.TcSpecialistSlotBookingRequestOBJ(),
+ "Bearer session-token"));
+ }
+ }
+
+ @Test
+ @DisplayName("callTmForSpecialistSlotBook should report a slot the scheduler refused")
+ void callTmForSlotBook_shouldReportRefusedSlot() {
+ new com.iemr.tm.utils.mapper.OutputMapper();
+ org.springframework.test.util.ReflectionTestUtils.setField(service, "tcSpecialistSlotBook",
+ "http://common/tc/specialistSlotBook");
+
+ try (org.mockito.MockedConstruction ignored =
+ org.mockito.Mockito.mockConstruction(org.springframework.web.client.RestTemplate.class,
+ (restTemplate, context) -> when(restTemplate.exchange(anyString(),
+ any(org.springframework.http.HttpMethod.class), any(),
+ org.mockito.ArgumentMatchers.>any()))
+ .thenReturn(new org.springframework.http.ResponseEntity<>(
+ "{\"statusCode\":5000}", org.springframework.http.HttpStatus.OK)))) {
+ assertEquals(0, service.callTmForSpecialistSlotBook(
+ new com.iemr.tm.data.tele_consultation.TcSpecialistSlotBookingRequestOBJ(),
+ "Bearer session-token"));
+ }
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/common/transaction/CommonNurseServiceImplTest.java b/src/test/java/com/iemr/tm/service/common/transaction/CommonNurseServiceImplTest.java
new file mode 100644
index 00000000..4125616d
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/common/transaction/CommonNurseServiceImplTest.java
@@ -0,0 +1,3233 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.common.transaction;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyShort;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.data.anc.BenAdherence;
+import com.iemr.tm.data.anc.BenAllergyHistory;
+import com.iemr.tm.data.anc.BenChildDevelopmentHistory;
+import com.iemr.tm.data.anc.ChildFeedingDetails;
+import com.iemr.tm.data.anc.PerinatalHistory;
+import com.iemr.tm.data.anc.WrapperBenInvestigationANC;
+import com.iemr.tm.data.anc.BenFamilyHistory;
+import com.iemr.tm.data.anc.BenMedHistory;
+import com.iemr.tm.data.anc.BenMedicationHistory;
+import com.iemr.tm.data.anc.BenMenstrualDetails;
+import com.iemr.tm.data.anc.BenPersonalHabit;
+import com.iemr.tm.data.anc.BencomrbidityCondDetails;
+import com.iemr.tm.data.anc.ChildOptionalVaccineDetail;
+import com.iemr.tm.data.anc.ChildVaccineDetail1;
+import com.iemr.tm.data.anc.FemaleObstetricHistory;
+import com.iemr.tm.data.anc.PhyGeneralExamination;
+import com.iemr.tm.data.anc.PhyHeadToToeExamination;
+import com.iemr.tm.data.anc.SysCardiovascularExamination;
+import com.iemr.tm.data.anc.SysCentralNervousExamination;
+import com.iemr.tm.data.anc.SysGastrointestinalExamination;
+import com.iemr.tm.data.anc.SysGenitourinarySystemExamination;
+import com.iemr.tm.data.anc.SysMusculoskeletalSystemExamination;
+import com.iemr.tm.data.anc.SysRespiratoryExamination;
+import com.iemr.tm.data.anc.WrapperChildOptionalVaccineDetail;
+import com.iemr.tm.data.anc.WrapperComorbidCondDetails;
+import com.iemr.tm.data.anc.WrapperFemaleObstetricHistory;
+import com.iemr.tm.data.anc.WrapperImmunizationHistory;
+import com.iemr.tm.data.anc.WrapperMedicationHistory;
+import com.iemr.tm.data.login.Users;
+import com.iemr.tm.data.ncdScreening.IDRSData;
+import com.iemr.tm.data.nurse.BenAnthropometryDetail;
+import com.iemr.tm.data.nurse.BenPhysicalVitalDetail;
+import com.iemr.tm.data.nurse.BeneficiaryVisitDetail;
+import com.iemr.tm.data.ncdScreening.PhysicalActivityType;
+import com.iemr.tm.data.quickConsultation.BenChiefComplaint;
+import com.iemr.tm.data.quickConsultation.PrescribedDrugDetail;
+import com.iemr.tm.data.quickConsultation.PrescriptionDetail;
+import com.iemr.tm.data.snomedct.SCTDescription;
+import com.iemr.tm.repo.bmiCalculation.BMICalculationRepo;
+import com.iemr.tm.repo.login.UserLoginRepo;
+import com.iemr.tm.repo.nurse.BenAnthropometryRepo;
+import com.iemr.tm.repo.nurse.BenPhysicalVitalRepo;
+import com.iemr.tm.repo.nurse.BenVisitDetailRepo;
+import com.iemr.tm.repo.nurse.anc.BenAdherenceRepo;
+import com.iemr.tm.repo.nurse.anc.BenAllergyHistoryRepo;
+import com.iemr.tm.repo.nurse.anc.BenChildDevelopmentHistoryRepo;
+import com.iemr.tm.repo.nurse.anc.BenFamilyHistoryRepo;
+import com.iemr.tm.repo.nurse.anc.BenMedHistoryRepo;
+import com.iemr.tm.repo.nurse.anc.BenMedicationHistoryRepo;
+import com.iemr.tm.repo.nurse.anc.BenMenstrualDetailsRepo;
+import com.iemr.tm.repo.nurse.anc.BenPersonalHabitRepo;
+import com.iemr.tm.repo.nurse.anc.BencomrbidityCondRepo;
+import com.iemr.tm.repo.nurse.anc.ChildFeedingDetailsRepo;
+import com.iemr.tm.repo.nurse.anc.ChildOptionalVaccineDetailRepo;
+import com.iemr.tm.repo.nurse.anc.ChildVaccineDetail1Repo;
+import com.iemr.tm.repo.nurse.anc.FemaleObstetricHistoryRepo;
+import com.iemr.tm.repo.nurse.anc.PerinatalHistoryRepo;
+import com.iemr.tm.repo.nurse.anc.PhyGeneralExaminationRepo;
+import com.iemr.tm.repo.nurse.anc.PhyHeadToToeExaminationRepo;
+import com.iemr.tm.repo.nurse.anc.SysCardiovascularExaminationRepo;
+import com.iemr.tm.repo.nurse.anc.SysCentralNervousExaminationRepo;
+import com.iemr.tm.repo.nurse.anc.SysGastrointestinalExaminationRepo;
+import com.iemr.tm.repo.nurse.anc.SysGenitourinarySystemExaminationRepo;
+import com.iemr.tm.repo.nurse.anc.SysMusculoskeletalSystemExaminationRepo;
+import com.iemr.tm.repo.nurse.anc.SysRespiratoryExaminationRepo;
+import com.iemr.tm.utils.exception.IEMRException;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("CommonNurseServiceImpl Test Suite")
+class CommonNurseServiceImplTest {
+
+ private static final Long BEN_REG_ID = 11L;
+ private static final Long VISIT_CODE = 22L;
+
+ @Mock
+ private BenVisitDetailRepo benVisitDetailRepo;
+ @Mock
+ private UserLoginRepo userLoginRepo;
+ @Mock
+ private com.iemr.tm.repo.quickConsultation.BenChiefComplaintRepo benChiefComplaintRepo;
+ @Mock
+ private BenMedHistoryRepo benMedHistoryRepo;
+ @Mock
+ private BencomrbidityCondRepo bencomrbidityCondRepo;
+ @Mock
+ private BenMedicationHistoryRepo benMedicationHistoryRepo;
+ @Mock
+ private FemaleObstetricHistoryRepo femaleObstetricHistoryRepo;
+ @Mock
+ private BenMenstrualDetailsRepo benMenstrualDetailsRepo;
+ @Mock
+ private BenFamilyHistoryRepo benFamilyHistoryRepo;
+ @Mock
+ private BenPersonalHabitRepo benPersonalHabitRepo;
+ @Mock
+ private BenAllergyHistoryRepo benAllergyHistoryRepo;
+ @Mock
+ private ChildOptionalVaccineDetailRepo childOptionalVaccineDetailRepo;
+ @Mock
+ private ChildVaccineDetail1Repo childVaccineDetail1Repo;
+ @Mock
+ private BenAnthropometryRepo benAnthropometryRepo;
+ @Mock
+ private BenPhysicalVitalRepo benPhysicalVitalRepo;
+ @Mock
+ private PhyGeneralExaminationRepo phyGeneralExaminationRepo;
+ @Mock
+ private PhyHeadToToeExaminationRepo phyHeadToToeExaminationRepo;
+ @Mock
+ private SysGastrointestinalExaminationRepo sysGastrointestinalExaminationRepo;
+ @Mock
+ private SysCardiovascularExaminationRepo sysCardiovascularExaminationRepo;
+ @Mock
+ private SysRespiratoryExaminationRepo sysRespiratoryExaminationRepo;
+ @Mock
+ private SysCentralNervousExaminationRepo sysCentralNervousExaminationRepo;
+ @Mock
+ private SysMusculoskeletalSystemExaminationRepo sysMusculoskeletalSystemExaminationRepo;
+ @Mock
+ private SysGenitourinarySystemExaminationRepo sysGenitourinarySystemExaminationRepo;
+ @Mock
+ private com.iemr.tm.repo.registrar.RegistrarRepoBenData registrarRepoBenData;
+ @Mock
+ private com.iemr.tm.repo.quickConsultation.PrescriptionDetailRepo prescriptionDetailRepo;
+ @Mock
+ private com.iemr.tm.repo.quickConsultation.LabTestOrderDetailRepo labTestOrderDetailRepo;
+ @Mock
+ private com.iemr.tm.repo.quickConsultation.PrescribedDrugDetailRepo prescribedDrugDetailRepo;
+ @Mock
+ private com.iemr.tm.repo.registrar.ReistrarRepoBenSearch reistrarRepoBenSearch;
+ @Mock
+ private BenAdherenceRepo benAdherenceRepo;
+ @Mock
+ private BenChildDevelopmentHistoryRepo benChildDevelopmentHistoryRepo;
+ @Mock
+ private ChildFeedingDetailsRepo childFeedingDetailsRepo;
+ @Mock
+ private PerinatalHistoryRepo perinatalHistoryRepo;
+ @Mock
+ private com.iemr.tm.repo.benFlowStatus.BeneficiaryFlowStatusRepo beneficiaryFlowStatusRepo;
+ @Mock
+ private com.iemr.tm.repo.nurse.ncdscreening.PhysicalActivityTypeRepo physicalActivityTypeRepo;
+ @Mock
+ private com.iemr.tm.repo.nurse.ncdscreening.PhysicalActivityTypeRepo physicalActivityaRepo;
+ @Mock
+ private com.iemr.tm.repo.nurse.ncdscreening.IDRSDataRepo iDRSDataRepo;
+ @Mock
+ private com.iemr.tm.repo.nurse.ncdscreening.IDRSDataRepo iDrsDataRepo;
+ @Mock
+ private com.iemr.tm.repo.nurse.BenCancerVitalDetailRepo benCancerVitalDetailRepo;
+ @Mock
+ private CommonDoctorServiceImpl commonDoctorServiceImpl;
+ @Mock
+ private com.iemr.tm.repo.doctor.BenReferDetailsRepo benReferDetailsRepo;
+ @Mock
+ private BMICalculationRepo bmiCalculationRepo;
+
+ @InjectMocks
+ private CommonNurseServiceImpl service;
+
+ /** Echoes the entities handed to a {@code saveAll} call back to the caller. */
+ private static org.mockito.stubbing.Answer echoList() {
+ return invocation -> invocation.getArgument(0);
+ }
+
+ private BeneficiaryVisitDetail visitDetail() {
+ BeneficiaryVisitDetail detail = new BeneficiaryVisitDetail();
+ detail.setBeneficiaryRegID(BEN_REG_ID);
+ detail.setVisitCode(VISIT_CODE);
+ detail.setCreatedBy("nurse1");
+ return detail;
+ }
+
+ @Nested
+ @DisplayName("beneficiary visit details")
+ class VisitDetailTests {
+
+ @Test
+ @DisplayName("updateBeneficiaryStatus should delegate the flow status change to the registrar repository")
+ void updateBeneficiaryStatus_shouldDelegateToRegistrarRepo() {
+ when(registrarRepoBenData.updateBenFlowStatus('N', BEN_REG_ID)).thenReturn(1);
+
+ assertEquals(1, service.updateBeneficiaryStatus('N', BEN_REG_ID));
+ }
+
+ @Test
+ @DisplayName("saveBeneficiaryVisitDetails should increment the visit number and return the new visit id")
+ void saveBeneficiaryVisitDetails_shouldIncrementVisitNumber() {
+ BeneficiaryVisitDetail detail = visitDetail();
+ detail.setFileIDs(new Integer[] { 7, 8 });
+ when(benVisitDetailRepo.getVisitCountForBeneficiary(BEN_REG_ID)).thenReturn((short) 2);
+ BeneficiaryVisitDetail saved = visitDetail();
+ saved.setBenVisitID(99L);
+ when(benVisitDetailRepo.save(any(BeneficiaryVisitDetail.class))).thenReturn(saved);
+ Users user = new Users();
+ user.setUserID(42L);
+ when(userLoginRepo.getUserByUsername("nurse1")).thenReturn(user);
+
+ assertEquals(99L, service.saveBeneficiaryVisitDetails(detail));
+
+ ArgumentCaptor captor = ArgumentCaptor.forClass(BeneficiaryVisitDetail.class);
+ verify(benVisitDetailRepo).save(captor.capture());
+ assertEquals((short) 3, captor.getValue().getVisitNo());
+ assertEquals("7,8,", captor.getValue().getReportFilePath());
+ assertEquals(42L, captor.getValue().getNurseID());
+ }
+
+ @Test
+ @DisplayName("saveBeneficiaryVisitDetails should start the visit numbering at one for a first visit")
+ void saveBeneficiaryVisitDetails_shouldStartVisitNumberingAtOne() {
+ when(benVisitDetailRepo.getVisitCountForBeneficiary(BEN_REG_ID)).thenReturn(null);
+ BeneficiaryVisitDetail saved = visitDetail();
+ saved.setBenVisitID(99L);
+ when(benVisitDetailRepo.save(any(BeneficiaryVisitDetail.class))).thenReturn(saved);
+
+ assertEquals(99L, service.saveBeneficiaryVisitDetails(visitDetail()));
+
+ ArgumentCaptor captor = ArgumentCaptor.forClass(BeneficiaryVisitDetail.class);
+ verify(benVisitDetailRepo).save(captor.capture());
+ assertEquals((short) 1, captor.getValue().getVisitNo());
+ assertEquals("", captor.getValue().getReportFilePath());
+ assertNull(captor.getValue().getNurseID());
+ }
+
+ @Test
+ @DisplayName("saveBeneficiaryVisitDetails should return null when the save does not come back")
+ void saveBeneficiaryVisitDetails_shouldReturnNullWhenSaveFails() {
+ when(benVisitDetailRepo.getVisitCountForBeneficiary(BEN_REG_ID)).thenReturn((short) 0);
+ when(benVisitDetailRepo.save(any(BeneficiaryVisitDetail.class))).thenReturn(null);
+
+ assertNull(service.saveBeneficiaryVisitDetails(visitDetail()));
+ }
+
+ @Test
+ @DisplayName("saveBeneficiaryVisitDetails should leave the nurse unresolved for a blank createdBy")
+ void saveBeneficiaryVisitDetails_shouldLeaveNurseUnresolvedForBlankCreatedBy() {
+ BeneficiaryVisitDetail detail = visitDetail();
+ detail.setCreatedBy(" ");
+ BeneficiaryVisitDetail saved = visitDetail();
+ saved.setBenVisitID(99L);
+ when(benVisitDetailRepo.save(any(BeneficiaryVisitDetail.class))).thenReturn(saved);
+
+ service.saveBeneficiaryVisitDetails(detail);
+
+ verify(userLoginRepo, never()).getUserByUsername(anyString());
+ }
+
+ @Test
+ @DisplayName("saveBeneficiaryVisitDetails should leave the nurse unresolved for an unknown user")
+ void saveBeneficiaryVisitDetails_shouldLeaveNurseUnresolvedForUnknownUser() {
+ when(userLoginRepo.getUserByUsername("nurse1")).thenReturn(null);
+ BeneficiaryVisitDetail saved = visitDetail();
+ saved.setBenVisitID(99L);
+ when(benVisitDetailRepo.save(any(BeneficiaryVisitDetail.class))).thenReturn(saved);
+
+ service.saveBeneficiaryVisitDetails(visitDetail());
+
+ ArgumentCaptor captor = ArgumentCaptor.forClass(BeneficiaryVisitDetail.class);
+ verify(benVisitDetailRepo).save(captor.capture());
+ assertNull(captor.getValue().getNurseID());
+ }
+
+ @Test
+ @DisplayName("getMaxCurrentdate should report a recent visit as still within the ten minute window")
+ void getMaxCurrentdate_shouldReportRecentVisitWithinWindow() throws Exception {
+ String now = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
+ .format(new java.util.Date(System.currentTimeMillis()));
+ when(benVisitDetailRepo.getMaxCreatedDate(BEN_REG_ID, "New", "ANC")).thenReturn(now + ".0");
+
+ assertEquals(1, service.getMaxCurrentdate(BEN_REG_ID, "New", "ANC"));
+ }
+
+ @Test
+ @DisplayName("getMaxCurrentdate should report an old visit as outside the ten minute window")
+ void getMaxCurrentdate_shouldReportOldVisitOutsideWindow() throws Exception {
+ when(benVisitDetailRepo.getMaxCreatedDate(BEN_REG_ID, "New", "ANC"))
+ .thenReturn("2020-01-01 10:00:00.0");
+
+ assertEquals(-1, service.getMaxCurrentdate(BEN_REG_ID, "New", "ANC"));
+ }
+
+ @Test
+ @DisplayName("getMaxCurrentdate should report zero when the beneficiary has no earlier visit")
+ void getMaxCurrentdate_shouldReportZeroWithoutEarlierVisit() throws Exception {
+ when(benVisitDetailRepo.getMaxCreatedDate(BEN_REG_ID, "New", "ANC")).thenReturn(null);
+
+ assertEquals(0, service.getMaxCurrentdate(BEN_REG_ID, "New", "ANC"));
+ }
+
+ @Test
+ @DisplayName("getMaxCurrentdate should fail for an unparseable created date")
+ void getMaxCurrentdate_shouldFailForUnparseableDate() {
+ when(benVisitDetailRepo.getMaxCreatedDate(BEN_REG_ID, "New", "ANC")).thenReturn("not-a-date.0");
+
+ IEMRException thrown = assertThrows(IEMRException.class,
+ () -> service.getMaxCurrentdate(BEN_REG_ID, "New", "ANC"));
+
+ assertTrue(thrown.getMessage().contains("Error while parseing created date"));
+ }
+
+ @Test
+ @DisplayName("generateVisitCode should build a zero padded visit code and return it once stored")
+ void generateVisitCode_shouldBuildZeroPaddedVisitCode() {
+ when(benVisitDetailRepo.updateVisitCode(10000100123456L, 123456L)).thenReturn(1);
+
+ assertEquals(10000100123456L, service.generateVisitCode(123456L, 1, 1));
+ }
+
+ @Test
+ @DisplayName("generateVisitCode should return zero when the visit code could not be stored")
+ void generateVisitCode_shouldReturnZeroWhenNotStored() {
+ when(benVisitDetailRepo.updateVisitCode(anyLong(), anyLong())).thenReturn(0);
+
+ assertEquals(0L, service.generateVisitCode(123456L, 1, 1));
+ }
+
+ @Test
+ @DisplayName("updateVisitCodeInVisitDetailsTable should delegate to the visit detail repository")
+ void updateVisitCodeInVisitDetailsTable_shouldDelegateToRepo() {
+ when(benVisitDetailRepo.updateVisitCode(55L, 66L)).thenReturn(1);
+
+ assertEquals(1, service.updateVisitCodeInVisitDetailsTable(55L, 66L));
+ }
+
+ @Test
+ @DisplayName("getBenVisitCount should return the next visit number for a returning beneficiary")
+ void getBenVisitCount_shouldReturnNextVisitNumber() {
+ when(benVisitDetailRepo.getVisitCountForBeneficiary(BEN_REG_ID)).thenReturn((short) 4);
+
+ assertEquals((short) 5, service.getBenVisitCount(BEN_REG_ID));
+ }
+
+ @Test
+ @DisplayName("getBenVisitCount should return one for a first time beneficiary")
+ void getBenVisitCount_shouldReturnOneForFirstVisit() {
+ when(benVisitDetailRepo.getVisitCountForBeneficiary(BEN_REG_ID)).thenReturn(null);
+
+ assertEquals((short) 1, service.getBenVisitCount(BEN_REG_ID));
+ }
+
+ @Test
+ @DisplayName("updateBeneficiaryVisitDetails should return the number of rows changed")
+ void updateBeneficiaryVisitDetails_shouldReturnRowsChanged() {
+ when(benVisitDetailRepo.updateBeneficiaryVisitDetail(any(), any(), any(), any(), any(), any(), any(), any(),
+ any(), any())).thenReturn(1);
+
+ assertEquals(1, service.updateBeneficiaryVisitDetails(visitDetail()));
+ }
+
+ @Test
+ @DisplayName("updateBeneficiaryVisitDetails should swallow a repository failure and report no change")
+ void updateBeneficiaryVisitDetails_shouldSwallowRepositoryFailure() {
+ when(benVisitDetailRepo.updateBeneficiaryVisitDetail(any(), any(), any(), any(), any(), any(), any(), any(),
+ any(), any())).thenThrow(new IllegalStateException("db down"));
+
+ assertEquals(0, service.updateBeneficiaryVisitDetails(visitDetail()));
+ }
+
+ @Test
+ @DisplayName("getCSVisitDetails should copy the stored visit and expand the report file ids")
+ void getCSVisitDetails_shouldCopyVisitAndExpandFileIds() {
+ BeneficiaryVisitDetail stored = visitDetail();
+ stored.setBenVisitID(99L);
+ stored.setReportFilePath("7, 8,");
+ when(benVisitDetailRepo.getVisitDetails(BEN_REG_ID, VISIT_CODE)).thenReturn(stored);
+
+ BeneficiaryVisitDetail result = service.getCSVisitDetails(BEN_REG_ID, VISIT_CODE);
+
+ assertNotNull(result);
+ assertEquals(99L, result.getBenVisitID());
+ assertEquals(2, result.getFileIDs().length);
+ assertEquals(7, result.getFileIDs()[0]);
+ assertEquals(8, result.getFileIDs()[1]);
+ }
+
+ @Test
+ @DisplayName("getCSVisitDetails should leave the file ids empty when no report path is stored")
+ void getCSVisitDetails_shouldLeaveFileIdsEmptyWithoutReportPath() {
+ BeneficiaryVisitDetail stored = visitDetail();
+ stored.setBenVisitID(99L);
+ when(benVisitDetailRepo.getVisitDetails(BEN_REG_ID, VISIT_CODE)).thenReturn(stored);
+
+ BeneficiaryVisitDetail result = service.getCSVisitDetails(BEN_REG_ID, VISIT_CODE);
+
+ assertEquals(0, result.getFileIDs().length);
+ }
+
+ @Test
+ @DisplayName("getCSVisitDetails should return null when the visit is unknown")
+ void getCSVisitDetails_shouldReturnNullForUnknownVisit() {
+ when(benVisitDetailRepo.getVisitDetails(BEN_REG_ID, VISIT_CODE)).thenReturn(null);
+
+ assertNull(service.getCSVisitDetails(BEN_REG_ID, VISIT_CODE));
+ }
+ }
+
+ @Nested
+ @DisplayName("history saves")
+ class HistorySaveTests {
+
+ @Test
+ @DisplayName("saveBenChiefComplaints should store only the complaints that carry an id")
+ void saveBenChiefComplaints_shouldStoreOnlyIdentifiedComplaints() {
+ BenChiefComplaint identified = new BenChiefComplaint();
+ identified.setChiefComplaintID(3);
+ BenChiefComplaint unidentified = new BenChiefComplaint();
+ when(benChiefComplaintRepo.saveAll(any())).thenReturn(Collections.singletonList(identified));
+
+ assertEquals(1, service.saveBenChiefComplaints(Arrays.asList(identified, unidentified)));
+ }
+
+ @Test
+ @DisplayName("saveBenChiefComplaints should succeed without touching the repository when nothing is identified")
+ void saveBenChiefComplaints_shouldSucceedWithoutIdentifiedComplaints() {
+ assertEquals(1, service.saveBenChiefComplaints(Collections.singletonList(new BenChiefComplaint())));
+
+ verify(benChiefComplaintRepo, never()).saveAll(any());
+ }
+
+ @Test
+ @DisplayName("saveBenChiefComplaints should report a failure when not every complaint was stored")
+ void saveBenChiefComplaints_shouldReportPartialSaveAsFailure() {
+ BenChiefComplaint identified = new BenChiefComplaint();
+ identified.setChiefComplaintID(3);
+ when(benChiefComplaintRepo.saveAll(any())).thenReturn(Collections.emptyList());
+
+ assertEquals(0, service.saveBenChiefComplaints(Collections.singletonList(identified)));
+ }
+
+ @Test
+ @DisplayName("saveBenPastHistory should store the derived past illness and surgery entries")
+ void saveBenPastHistory_shouldStoreDerivedEntries() {
+ BenMedHistory history = new BenMedHistory();
+ ArrayList> illnesses = new ArrayList<>();
+ illnesses.add(illness());
+ history.setPastIllness(illnesses);
+ history.setPastSurgery(new ArrayList<>());
+ when(benMedHistoryRepo.saveAll(any())).thenAnswer(echoList());
+
+ assertEquals(1L, service.saveBenPastHistory(history));
+ }
+
+ @Test
+ @DisplayName("saveBenPastHistory should succeed for an empty past history")
+ void saveBenPastHistory_shouldSucceedForEmptyHistory() {
+ BenMedHistory history = new BenMedHistory();
+ history.setPastIllness(new ArrayList<>());
+ history.setPastSurgery(new ArrayList<>());
+
+ assertEquals(1L, service.saveBenPastHistory(history));
+ verify(benMedHistoryRepo, never()).saveAll(any());
+ }
+
+ @Test
+ @DisplayName("saveBenPastHistory should report a failure when not every entry was stored")
+ void saveBenPastHistory_shouldReportPartialSaveAsFailure() {
+ BenMedHistory history = new BenMedHistory();
+ ArrayList> illnesses = new ArrayList<>();
+ illnesses.add(illness());
+ history.setPastIllness(illnesses);
+ history.setPastSurgery(new ArrayList<>());
+ when(benMedHistoryRepo.saveAll(any())).thenReturn(new ArrayList());
+
+ assertNull(service.saveBenPastHistory(history));
+ }
+
+ @Test
+ @DisplayName("saveBenComorbidConditions should return the id of the first stored condition")
+ void saveBenComorbidConditions_shouldReturnFirstStoredId() {
+ WrapperComorbidCondDetails wrapper = new WrapperComorbidCondDetails();
+ BencomrbidityCondDetails condition = new BencomrbidityCondDetails();
+ condition.setComorbidCondition("Diabetes");
+ condition.setID(5L);
+ wrapper.setComorbidityConcurrentConditionsList(
+ new ArrayList<>(Collections.singletonList(condition)));
+ when(bencomrbidityCondRepo.saveAll(any())).thenAnswer(echoList());
+
+ assertEquals(5L, service.saveBenComorbidConditions(wrapper));
+ }
+
+ @Test
+ @DisplayName("saveBenComorbidConditions should succeed when no condition carries a name")
+ void saveBenComorbidConditions_shouldSucceedWithoutNamedConditions() {
+ WrapperComorbidCondDetails wrapper = new WrapperComorbidCondDetails();
+ wrapper.setComorbidityConcurrentConditionsList(
+ new ArrayList<>(Collections.singletonList(new BencomrbidityCondDetails())));
+
+ assertEquals(1L, service.saveBenComorbidConditions(wrapper));
+ verify(bencomrbidityCondRepo, never()).saveAll(any());
+ }
+
+ @Test
+ @DisplayName("saveBenComorbidConditions should report a failure when not every condition was stored")
+ void saveBenComorbidConditions_shouldReportPartialSaveAsFailure() {
+ WrapperComorbidCondDetails wrapper = new WrapperComorbidCondDetails();
+ BencomrbidityCondDetails condition = new BencomrbidityCondDetails();
+ condition.setComorbidCondition("Diabetes");
+ wrapper.setComorbidityConcurrentConditionsList(
+ new ArrayList<>(Collections.singletonList(condition)));
+ when(bencomrbidityCondRepo.saveAll(any())).thenReturn(new ArrayList());
+
+ assertNull(service.saveBenComorbidConditions(wrapper));
+ }
+
+ @Test
+ @DisplayName("saveBenMedicationHistory should return the id of the first stored entry")
+ void saveBenMedicationHistory_shouldReturnFirstStoredId() {
+ WrapperMedicationHistory wrapper = new WrapperMedicationHistory();
+ BenMedicationHistory entry = new BenMedicationHistory();
+ entry.setCurrentMedication("Metformin");
+ entry.setID(6L);
+ wrapper.setMedicationHistoryList(new ArrayList<>(Collections.singletonList(entry)));
+ when(benMedicationHistoryRepo.saveAll(any())).thenAnswer(echoList());
+
+ assertEquals(6L, service.saveBenMedicationHistory(wrapper));
+ }
+
+ @Test
+ @DisplayName("saveBenMedicationHistory should succeed when no entry names a medication")
+ void saveBenMedicationHistory_shouldSucceedWithoutNamedMedication() {
+ WrapperMedicationHistory wrapper = new WrapperMedicationHistory();
+ wrapper.setMedicationHistoryList(new ArrayList<>(Collections.singletonList(new BenMedicationHistory())));
+
+ assertEquals(1L, service.saveBenMedicationHistory(wrapper));
+ verify(benMedicationHistoryRepo, never()).saveAll(any());
+ }
+
+ @Test
+ @DisplayName("saveFemaleObstetricHistory should flatten the complication lists before storing")
+ void saveFemaleObstetricHistory_shouldFlattenComplicationLists() {
+ FemaleObstetricHistory history = new FemaleObstetricHistory();
+ history.setPregComplicationList(complications("pregComplicationID", "pregComplicationType"));
+ history.setDeliveryComplicationList(
+ complications("deliveryComplicationID", "deliveryComplicationType"));
+ history.setPostpartumComplicationList(
+ complications("postpartumComplicationID", "postpartumComplicationType"));
+ ArrayList> postAbortion = new ArrayList<>();
+ postAbortion.add(complication("complicationID", 1d, "complicationValue", "Sepsis"));
+ postAbortion.add(complication("complicationID", 2d, "complicationValue", "Bleeding"));
+ history.setPostAbortionComplication(postAbortion);
+ history.setAbortionType(complication("complicationID", 3d, "complicationValue", "Induced"));
+ history.setTypeofFacility(complication("serviceFacilityID", 4d, "facilityName", "PHC"));
+
+ WrapperFemaleObstetricHistory wrapper = new WrapperFemaleObstetricHistory();
+ wrapper.setFemaleObstetricHistoryList(new ArrayList<>(Collections.singletonList(history)));
+ when(femaleObstetricHistoryRepo.saveAll(any())).thenAnswer(echoList());
+
+ assertEquals(1L, service.saveFemaleObstetricHistory(wrapper));
+ assertEquals("1,2", history.getPregComplicationID());
+ assertEquals("A,B", history.getPregComplicationType());
+ assertEquals("1,2", history.getDeliveryComplicationID());
+ assertEquals("1,2", history.getPostpartumComplicationID());
+ assertEquals("1,2", history.getPostAbortionComplication_db());
+ assertEquals("Sepsis,Bleeding", history.getPostAbortionComplicationsValues());
+ assertEquals(3, history.getAbortionTypeID());
+ assertEquals("Induced", history.getTypeOfAbortionValue());
+ assertEquals(4, history.getTypeofFacilityID());
+ assertEquals("PHC", history.getServiceFacilityValue());
+ }
+
+ @Test
+ @DisplayName("saveFemaleObstetricHistory should succeed for an entry without any complications")
+ void saveFemaleObstetricHistory_shouldSucceedWithoutComplications() {
+ WrapperFemaleObstetricHistory wrapper = new WrapperFemaleObstetricHistory();
+ wrapper.setFemaleObstetricHistoryList(
+ new ArrayList<>(Collections.singletonList(new FemaleObstetricHistory())));
+ when(femaleObstetricHistoryRepo.saveAll(any())).thenAnswer(echoList());
+
+ assertEquals(1L, service.saveFemaleObstetricHistory(wrapper));
+ }
+
+ @Test
+ @DisplayName("saveFemaleObstetricHistory should succeed for an empty obstetric history")
+ void saveFemaleObstetricHistory_shouldSucceedForEmptyHistory() {
+ WrapperFemaleObstetricHistory wrapper = new WrapperFemaleObstetricHistory();
+ wrapper.setFemaleObstetricHistoryList(new ArrayList<>());
+
+ assertEquals(1L, service.saveFemaleObstetricHistory(wrapper));
+ verify(femaleObstetricHistoryRepo, never()).saveAll(any());
+ }
+
+ @Test
+ @DisplayName("saveBenMenstrualHistory should flatten the menstrual problem list before storing")
+ void saveBenMenstrualHistory_shouldFlattenProblemList() {
+ BenMenstrualDetails details = new BenMenstrualDetails();
+ ArrayList> problems = new ArrayList<>();
+ problems.add(complication("menstrualProblemID", 1, "problemName", "Cramps"));
+ problems.add(complication("menstrualProblemID", 2, "problemName", "Irregular"));
+ details.setMenstrualProblemList(problems);
+ BenMenstrualDetails saved = new BenMenstrualDetails();
+ saved.setBenMenstrualID(9);
+ when(benMenstrualDetailsRepo.save(details)).thenReturn(saved);
+
+ assertEquals(9, service.saveBenMenstrualHistory(details));
+ assertEquals("1,2", details.getMenstrualProblemID());
+ assertEquals("Cramps,Irregular", details.getProblemName());
+ }
+
+ @Test
+ @DisplayName("saveBenMenstrualHistory should return null when the stored row carries no id")
+ void saveBenMenstrualHistory_shouldReturnNullWithoutStoredId() {
+ BenMenstrualDetails details = new BenMenstrualDetails();
+ BenMenstrualDetails saved = new BenMenstrualDetails();
+ saved.setBenMenstrualID(0);
+ when(benMenstrualDetailsRepo.save(details)).thenReturn(saved);
+
+ assertNull(service.saveBenMenstrualHistory(details));
+ }
+
+ @Test
+ @DisplayName("saveBenFamilyHistory should store the derived family history entries")
+ void saveBenFamilyHistory_shouldStoreDerivedEntries() {
+ BenFamilyHistory history = new BenFamilyHistory();
+ history.setFamilyDiseaseList(familyDiseaseList());
+ when(benFamilyHistoryRepo.saveAll(any())).thenAnswer(echoList());
+
+ assertEquals(1L, service.saveBenFamilyHistory(history));
+ }
+
+ @Test
+ @DisplayName("saveBenFamilyHistory should succeed for an empty family history")
+ void saveBenFamilyHistory_shouldSucceedForEmptyHistory() {
+ BenFamilyHistory history = new BenFamilyHistory();
+ history.setFamilyDiseaseList(new ArrayList<>());
+
+ assertEquals(1L, service.saveBenFamilyHistory(history));
+ verify(benFamilyHistoryRepo, never()).saveAll(any());
+ }
+
+ @Test
+ @DisplayName("savePersonalHistory should store the derived personal habit entries")
+ void savePersonalHistory_shouldStoreDerivedEntries() {
+ BenPersonalHabit habit = new BenPersonalHabit();
+ List> tobacco = new ArrayList<>();
+ Map entry = new HashMap<>();
+ entry.put("habit", "Smoking");
+ tobacco.add(entry);
+ habit.setTobaccoList(tobacco);
+ habit.setAlcoholList(new ArrayList<>());
+ habit.setAllergicList(new ArrayList<>());
+ when(benPersonalHabitRepo.saveAll(any())).thenAnswer(echoList());
+
+ assertEquals(1, service.savePersonalHistory(habit));
+ }
+
+ @Test
+ @DisplayName("savePersonalHistory should succeed for an empty personal history")
+ void savePersonalHistory_shouldSucceedForEmptyHistory() {
+ BenPersonalHabit habit = new BenPersonalHabit();
+ habit.setTobaccoList(new ArrayList<>());
+ habit.setAlcoholList(new ArrayList<>());
+ habit.setAllergicList(new ArrayList<>());
+
+ assertEquals(1, service.savePersonalHistory(habit));
+ }
+
+ @Test
+ @DisplayName("saveAllergyHistory should store the derived allergy entries")
+ void saveAllergyHistory_shouldStoreDerivedEntries() {
+ BenAllergyHistory allergy = new BenAllergyHistory();
+ List> allergies = new ArrayList<>();
+ Map entry = new HashMap<>();
+ entry.put("allergyType", "Food");
+ allergies.add(entry);
+ allergy.setAllergicList(allergies);
+ when(benAllergyHistoryRepo.saveAll(any())).thenAnswer(echoList());
+
+ assertEquals(1L, service.saveAllergyHistory(allergy));
+ }
+
+ @Test
+ @DisplayName("saveAllergyHistory should succeed for an empty allergy history")
+ void saveAllergyHistory_shouldSucceedForEmptyHistory() {
+ BenAllergyHistory allergy = new BenAllergyHistory();
+ allergy.setAllergicList(new ArrayList<>());
+
+ assertEquals(1L, service.saveAllergyHistory(allergy));
+ verify(benAllergyHistoryRepo, never()).saveAll(any());
+ }
+
+ @Test
+ @DisplayName("saveChildOptionalVaccineDetail should store the optional vaccine entries")
+ void saveChildOptionalVaccineDetail_shouldStoreEntries() {
+ WrapperChildOptionalVaccineDetail wrapper = new WrapperChildOptionalVaccineDetail();
+ wrapper.setChildOptionalVaccineList(
+ new ArrayList<>(Collections.singletonList(new ChildOptionalVaccineDetail())));
+ when(childOptionalVaccineDetailRepo.saveAll(any())).thenAnswer(echoList());
+
+ assertEquals(1L, service.saveChildOptionalVaccineDetail(wrapper));
+ }
+
+ @Test
+ @DisplayName("saveChildOptionalVaccineDetail should succeed for an empty vaccine list")
+ void saveChildOptionalVaccineDetail_shouldSucceedForEmptyList() {
+ WrapperChildOptionalVaccineDetail wrapper = new WrapperChildOptionalVaccineDetail();
+ wrapper.setChildOptionalVaccineList(new ArrayList<>());
+
+ assertEquals(1L, service.saveChildOptionalVaccineDetail(wrapper));
+ }
+
+ @Test
+ @DisplayName("saveImmunizationHistory should expand each dose of the immunization list")
+ void saveImmunizationHistory_shouldExpandEachDose() {
+ WrapperImmunizationHistory wrapper = new WrapperImmunizationHistory();
+ ChildVaccineDetail1 vaccine = new ChildVaccineDetail1();
+ List> vaccines = new ArrayList<>();
+ Map dose = new HashMap<>();
+ dose.put("vaccine", "BCG");
+ dose.put("status", Boolean.TRUE);
+ vaccines.add(dose);
+ vaccine.setVaccines(vaccines);
+ wrapper.setImmunizationList(new ArrayList<>(Collections.singletonList(vaccine)));
+ when(childVaccineDetail1Repo.saveAll(any())).thenAnswer(echoList());
+
+ assertNull(service.saveImmunizationHistory(wrapper));
+ }
+
+ @Test
+ @DisplayName("saveImmunizationHistory should store a placeholder row for an empty immunization list")
+ void saveImmunizationHistory_shouldStorePlaceholderForEmptyList() {
+ WrapperImmunizationHistory wrapper = new WrapperImmunizationHistory();
+ wrapper.setImmunizationList(new ArrayList<>());
+ when(childVaccineDetail1Repo.saveAll(any())).thenAnswer(echoList());
+
+ assertNull(service.saveImmunizationHistory(wrapper));
+ }
+
+ @Test
+ @DisplayName("saveBenFamilyHistoryNCDScreening should store the derived screening family history")
+ void saveBenFamilyHistoryNCDScreening_shouldStoreDerivedEntries() {
+ BenFamilyHistory history = new BenFamilyHistory();
+ history.setFamilyDiseaseList(familyDiseaseList());
+ when(benFamilyHistoryRepo.saveAll(any())).thenAnswer(echoList());
+
+ assertEquals(1L, service.saveBenFamilyHistoryNCDScreening(history));
+ }
+
+ @Test
+ @DisplayName("saveBenFamilyHistoryNCDScreening should succeed for an empty screening history")
+ void saveBenFamilyHistoryNCDScreening_shouldSucceedForEmptyHistory() {
+ BenFamilyHistory history = new BenFamilyHistory();
+ history.setFamilyDiseaseList(new ArrayList<>());
+
+ assertEquals(1L, service.saveBenFamilyHistoryNCDScreening(history));
+ verify(benFamilyHistoryRepo, never()).saveAll(any());
+ }
+
+ private Map illness() {
+ Map map = new HashMap<>();
+ map.put("illnessType", "Asthma");
+ map.put("illnessTypeID", 1);
+ return map;
+ }
+
+ private List> familyDiseaseList() {
+ List> list = new ArrayList<>();
+ Map disease = new HashMap<>();
+ disease.put("diseaseType", "Diabetes");
+ disease.put("diseaseTypeID", 1);
+ disease.put("deleted", "false");
+ disease.put("familyMembers", Arrays.asList("Mother", "Father"));
+ list.add(disease);
+ return list;
+ }
+
+ private ArrayList> complications(String idKey, String nameKey) {
+ ArrayList> list = new ArrayList<>();
+ list.add(complication(idKey, 1, nameKey, "A"));
+ list.add(complication(idKey, 2, nameKey, "B"));
+ return list;
+ }
+
+ private Map complication(String idKey, Object id, String nameKey, Object name) {
+ Map map = new HashMap<>();
+ map.put(idKey, id);
+ map.put(nameKey, name);
+ return map;
+ }
+ }
+
+ @Nested
+ @DisplayName("vitals and examinations")
+ class VitalsAndExaminationTests {
+
+ @Test
+ @DisplayName("saveBeneficiaryPhysicalAnthropometryDetails should return the stored row id")
+ void saveAnthropometry_shouldReturnStoredId() {
+ BenAnthropometryDetail detail = new BenAnthropometryDetail();
+ BenAnthropometryDetail saved = new BenAnthropometryDetail();
+ saved.setID(4L);
+ when(benAnthropometryRepo.save(detail)).thenReturn(saved);
+
+ assertEquals(4L, service.saveBeneficiaryPhysicalAnthropometryDetails(detail));
+ }
+
+ @Test
+ @DisplayName("saveBeneficiaryPhysicalAnthropometryDetails should return null when nothing was stored")
+ void saveAnthropometry_shouldReturnNullWhenNothingStored() {
+ BenAnthropometryDetail detail = new BenAnthropometryDetail();
+ when(benAnthropometryRepo.save(detail)).thenReturn(null);
+
+ assertNull(service.saveBeneficiaryPhysicalAnthropometryDetails(detail));
+ }
+
+ @Test
+ @DisplayName("saveIDRS should return the stored row id")
+ void saveIDRS_shouldReturnStoredId() {
+ IDRSData detail = new IDRSData();
+ IDRSData saved = new IDRSData();
+ saved.setId(4L);
+ when(iDrsDataRepo.save(detail)).thenReturn(saved);
+
+ assertEquals(4L, service.saveIDRS(detail));
+ }
+
+ @Test
+ @DisplayName("saveIDRS should return null when nothing was stored")
+ void saveIDRS_shouldReturnNullWhenNothingStored() {
+ IDRSData detail = new IDRSData();
+ when(iDrsDataRepo.save(detail)).thenReturn(null);
+
+ assertNull(service.saveIDRS(detail));
+ }
+
+ @Test
+ @DisplayName("savePhysicalActivity should return the stored row id")
+ void savePhysicalActivity_shouldReturnStoredId() {
+ PhysicalActivityType detail = new PhysicalActivityType();
+ PhysicalActivityType saved = new PhysicalActivityType();
+ saved.setpAID(4L);
+ when(physicalActivityaRepo.save(detail)).thenReturn(saved);
+
+ assertEquals(4L, service.savePhysicalActivity(detail));
+ }
+
+ @Test
+ @DisplayName("savePhysicalActivity should return null when nothing was stored")
+ void savePhysicalActivity_shouldReturnNullWhenNothingStored() {
+ PhysicalActivityType detail = new PhysicalActivityType();
+ when(physicalActivityaRepo.save(detail)).thenReturn(null);
+
+ assertNull(service.savePhysicalActivity(detail));
+ }
+
+ @Test
+ @DisplayName("saveBeneficiaryPhysicalVitalDetails should average the three blood pressure readings")
+ void savePhysicalVitals_shouldAverageThreeReadings() {
+ BenPhysicalVitalDetail detail = new BenPhysicalVitalDetail();
+ detail.setSystolicBP_1stReading((short) 120);
+ detail.setDiastolicBP_1stReading((short) 80);
+ detail.setSystolicBP_2ndReading((short) 130);
+ detail.setDiastolicBP_2ndReading((short) 90);
+ detail.setSystolicBP_3rdReading((short) 110);
+ detail.setDiastolicBP_3rdReading((short) 70);
+ BenPhysicalVitalDetail saved = new BenPhysicalVitalDetail();
+ saved.setID(4L);
+ when(benPhysicalVitalRepo.save(detail)).thenReturn(saved);
+
+ assertEquals(4L, service.saveBeneficiaryPhysicalVitalDetails(detail));
+ assertEquals((short) 120, detail.getAverageSystolicBP());
+ assertEquals((short) 80, detail.getAverageDiastolicBP());
+ }
+
+ @Test
+ @DisplayName("saveBeneficiaryPhysicalVitalDetails should leave the average unset without any reading")
+ void savePhysicalVitals_shouldLeaveAverageUnsetWithoutReadings() {
+ BenPhysicalVitalDetail detail = new BenPhysicalVitalDetail();
+ BenPhysicalVitalDetail saved = new BenPhysicalVitalDetail();
+ saved.setID(4L);
+ when(benPhysicalVitalRepo.save(detail)).thenReturn(saved);
+
+ assertEquals(4L, service.saveBeneficiaryPhysicalVitalDetails(detail));
+ assertNull(detail.getAverageSystolicBP());
+ }
+
+ @Test
+ @DisplayName("saveBeneficiaryPhysicalVitalDetails should return null when nothing was stored")
+ void savePhysicalVitals_shouldReturnNullWhenNothingStored() {
+ BenPhysicalVitalDetail detail = new BenPhysicalVitalDetail();
+ when(benPhysicalVitalRepo.save(detail)).thenReturn(null);
+
+ assertNull(service.saveBeneficiaryPhysicalVitalDetails(detail));
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryPhysicalAnthropometryDetails should return the stored row as JSON")
+ void getAnthropometry_shouldReturnJson() {
+ BenAnthropometryDetail detail = new BenAnthropometryDetail();
+ detail.setID(4L);
+ when(benAnthropometryRepo.getBenAnthropometryDetail(BEN_REG_ID, VISIT_CODE)).thenReturn(detail);
+
+ assertTrue(service.getBeneficiaryPhysicalAnthropometryDetails(BEN_REG_ID, VISIT_CODE).contains("\"ID\""));
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryPhysicalVitalDetails should return the stored row as JSON")
+ void getPhysicalVitals_shouldReturnJson() {
+ BenPhysicalVitalDetail detail = new BenPhysicalVitalDetail();
+ detail.setID(4L);
+ when(benPhysicalVitalRepo.getBenPhysicalVitalDetail(BEN_REG_ID, VISIT_CODE)).thenReturn(detail);
+
+ assertTrue(service.getBeneficiaryPhysicalVitalDetails(BEN_REG_ID, VISIT_CODE).contains("\"ID\""));
+ }
+
+ @Test
+ @DisplayName("updateANCAnthropometryDetails should mark an already processed row as updated")
+ void updateAnthropometry_shouldMarkProcessedRowAsUpdated() {
+ BenAnthropometryDetail detail = new BenAnthropometryDetail();
+ detail.setBeneficiaryRegID(BEN_REG_ID);
+ detail.setVisitCode(VISIT_CODE);
+ when(benAnthropometryRepo.getBenAnthropometryStatus(BEN_REG_ID, VISIT_CODE)).thenReturn("P");
+ when(benAnthropometryRepo.updateANCCareDetails(any(), any(), any(), any(), any(), any(), any(), any(),
+ any(), eq("U"), eq(BEN_REG_ID), eq(VISIT_CODE))).thenReturn(1);
+
+ assertEquals(1, service.updateANCAnthropometryDetails(detail));
+ }
+
+ @Test
+ @DisplayName("updateANCAnthropometryDetails should keep a fresh row marked as new")
+ void updateAnthropometry_shouldKeepFreshRowAsNew() {
+ BenAnthropometryDetail detail = new BenAnthropometryDetail();
+ detail.setBeneficiaryRegID(BEN_REG_ID);
+ detail.setVisitCode(VISIT_CODE);
+ when(benAnthropometryRepo.getBenAnthropometryStatus(BEN_REG_ID, VISIT_CODE)).thenReturn("N");
+ when(benAnthropometryRepo.updateANCCareDetails(any(), any(), any(), any(), any(), any(), any(), any(),
+ any(), eq("N"), eq(BEN_REG_ID), eq(VISIT_CODE))).thenReturn(1);
+
+ assertEquals(1, service.updateANCAnthropometryDetails(detail));
+ }
+
+ @Test
+ @DisplayName("updateANCAnthropometryDetails should report no change for a null payload")
+ void updateAnthropometry_shouldReportNoChangeForNullPayload() {
+ assertEquals(0, service.updateANCAnthropometryDetails(null));
+ }
+
+ @Test
+ @DisplayName("updateANCPhysicalVitalDetails should copy the first reading into the averages")
+ void updatePhysicalVitals_shouldCopyFirstReadingIntoAverages() {
+ BenPhysicalVitalDetail detail = new BenPhysicalVitalDetail();
+ detail.setBeneficiaryRegID(BEN_REG_ID);
+ detail.setVisitCode(VISIT_CODE);
+ detail.setSystolicBP_1stReading((short) 118);
+ detail.setDiastolicBP_1stReading((short) 78);
+ when(benPhysicalVitalRepo.getBenPhysicalVitalStatus(BEN_REG_ID, VISIT_CODE)).thenReturn("P");
+ when(benPhysicalVitalRepo.updatePhysicalVitalDetails(any(), any(), any(), any(), any(), any(), any(), any(),
+ any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(),
+ eq("U"), any(), any(), any(), eq(BEN_REG_ID), eq(VISIT_CODE))).thenReturn(1);
+
+ assertEquals(1, service.updateANCPhysicalVitalDetails(detail));
+ assertEquals((short) 118, detail.getAverageSystolicBP());
+ assertEquals((short) 78, detail.getAverageDiastolicBP());
+ }
+
+ @Test
+ @DisplayName("updateANCPhysicalVitalDetails should report no change for a null payload")
+ void updatePhysicalVitals_shouldReportNoChangeForNullPayload() {
+ assertEquals(0, service.updateANCPhysicalVitalDetails(null));
+ }
+
+ @Test
+ @DisplayName("savePhyGeneralExamination should flatten the danger sign list before storing")
+ void saveGeneralExamination_shouldFlattenDangerSigns() {
+ PhyGeneralExamination examination = new PhyGeneralExamination();
+ examination.setTypeOfDangerSigns(new ArrayList<>(Arrays.asList("Fever", "Bleeding")));
+ PhyGeneralExamination saved = new PhyGeneralExamination();
+ saved.setID(4L);
+ when(phyGeneralExaminationRepo.save(examination)).thenReturn(saved);
+
+ assertEquals(4L, service.savePhyGeneralExamination(examination));
+ assertEquals("Fever,Bleeding,", examination.getTypeOfDangerSign());
+ }
+
+ @Test
+ @DisplayName("savePhyGeneralExamination should return null when nothing was stored")
+ void saveGeneralExamination_shouldReturnNullWhenNothingStored() {
+ PhyGeneralExamination examination = new PhyGeneralExamination();
+ when(phyGeneralExaminationRepo.save(examination)).thenReturn(null);
+
+ assertNull(service.savePhyGeneralExamination(examination));
+ }
+
+ @Test
+ @DisplayName("savePhyHeadToToeExamination should return the stored row id")
+ void saveHeadToToeExamination_shouldReturnStoredId() {
+ PhyHeadToToeExamination examination = new PhyHeadToToeExamination();
+ PhyHeadToToeExamination saved = new PhyHeadToToeExamination();
+ saved.setID(4L);
+ when(phyHeadToToeExaminationRepo.save(examination)).thenReturn(saved);
+
+ assertEquals(4L, service.savePhyHeadToToeExamination(examination));
+ }
+
+ @Test
+ @DisplayName("savePhyHeadToToeExamination should return null when nothing was stored")
+ void saveHeadToToeExamination_shouldReturnNullWhenNothingStored() {
+ PhyHeadToToeExamination examination = new PhyHeadToToeExamination();
+ when(phyHeadToToeExaminationRepo.save(examination)).thenReturn(null);
+
+ assertNull(service.savePhyHeadToToeExamination(examination));
+ }
+
+ @Test
+ @DisplayName("saveSysGastrointestinalExamination should return the stored row id")
+ void saveGastrointestinalExamination_shouldReturnStoredId() {
+ SysGastrointestinalExamination examination = new SysGastrointestinalExamination();
+ SysGastrointestinalExamination saved = new SysGastrointestinalExamination();
+ saved.setID(4L);
+ when(sysGastrointestinalExaminationRepo.save(examination)).thenReturn(saved);
+
+ assertEquals(4L, service.saveSysGastrointestinalExamination(examination));
+ }
+
+ @Test
+ @DisplayName("saveSysGastrointestinalExamination should return null when nothing was stored")
+ void saveGastrointestinalExamination_shouldReturnNullWhenNothingStored() {
+ SysGastrointestinalExamination examination = new SysGastrointestinalExamination();
+ when(sysGastrointestinalExaminationRepo.save(examination)).thenReturn(null);
+
+ assertNull(service.saveSysGastrointestinalExamination(examination));
+ }
+
+ @Test
+ @DisplayName("saveSysCardiovascularExamination should return the stored row id")
+ void saveCardiovascularExamination_shouldReturnStoredId() {
+ SysCardiovascularExamination examination = new SysCardiovascularExamination();
+ SysCardiovascularExamination saved = new SysCardiovascularExamination();
+ saved.setID(4L);
+ when(sysCardiovascularExaminationRepo.save(examination)).thenReturn(saved);
+
+ assertEquals(4L, service.saveSysCardiovascularExamination(examination));
+ }
+
+ @Test
+ @DisplayName("saveSysCardiovascularExamination should return null when nothing was stored")
+ void saveCardiovascularExamination_shouldReturnNullWhenNothingStored() {
+ SysCardiovascularExamination examination = new SysCardiovascularExamination();
+ when(sysCardiovascularExaminationRepo.save(examination)).thenReturn(null);
+
+ assertNull(service.saveSysCardiovascularExamination(examination));
+ }
+
+ @Test
+ @DisplayName("saveSysRespiratoryExamination should return the stored row id")
+ void saveRespiratoryExamination_shouldReturnStoredId() {
+ SysRespiratoryExamination examination = new SysRespiratoryExamination();
+ SysRespiratoryExamination saved = new SysRespiratoryExamination();
+ saved.setID(4L);
+ when(sysRespiratoryExaminationRepo.save(examination)).thenReturn(saved);
+
+ assertEquals(4L, service.saveSysRespiratoryExamination(examination));
+ }
+
+ @Test
+ @DisplayName("saveSysRespiratoryExamination should return null when nothing was stored")
+ void saveRespiratoryExamination_shouldReturnNullWhenNothingStored() {
+ SysRespiratoryExamination examination = new SysRespiratoryExamination();
+ when(sysRespiratoryExaminationRepo.save(examination)).thenReturn(null);
+
+ assertNull(service.saveSysRespiratoryExamination(examination));
+ }
+
+ @Test
+ @DisplayName("saveSysCentralNervousExamination should return the stored row id")
+ void saveCentralNervousExamination_shouldReturnStoredId() {
+ SysCentralNervousExamination examination = new SysCentralNervousExamination();
+ SysCentralNervousExamination saved = new SysCentralNervousExamination();
+ saved.setID(4L);
+ when(sysCentralNervousExaminationRepo.save(examination)).thenReturn(saved);
+
+ assertEquals(4L, service.saveSysCentralNervousExamination(examination));
+ }
+
+ @Test
+ @DisplayName("saveSysCentralNervousExamination should return null when nothing was stored")
+ void saveCentralNervousExamination_shouldReturnNullWhenNothingStored() {
+ SysCentralNervousExamination examination = new SysCentralNervousExamination();
+ when(sysCentralNervousExaminationRepo.save(examination)).thenReturn(null);
+
+ assertNull(service.saveSysCentralNervousExamination(examination));
+ }
+
+ @Test
+ @DisplayName("saveSysMusculoskeletalSystemExamination should return the stored row id")
+ void saveMusculoskeletalExamination_shouldReturnStoredId() {
+ SysMusculoskeletalSystemExamination examination = new SysMusculoskeletalSystemExamination();
+ SysMusculoskeletalSystemExamination saved = new SysMusculoskeletalSystemExamination();
+ saved.setID(4L);
+ when(sysMusculoskeletalSystemExaminationRepo.save(examination)).thenReturn(saved);
+
+ assertEquals(4L, service.saveSysMusculoskeletalSystemExamination(examination));
+ }
+
+ @Test
+ @DisplayName("saveSysMusculoskeletalSystemExamination should return null when nothing was stored")
+ void saveMusculoskeletalExamination_shouldReturnNullWhenNothingStored() {
+ SysMusculoskeletalSystemExamination examination = new SysMusculoskeletalSystemExamination();
+ when(sysMusculoskeletalSystemExaminationRepo.save(examination)).thenReturn(null);
+
+ assertNull(service.saveSysMusculoskeletalSystemExamination(examination));
+ }
+
+ @Test
+ @DisplayName("saveSysGenitourinarySystemExamination should return the stored row id")
+ void saveGenitourinaryExamination_shouldReturnStoredId() {
+ SysGenitourinarySystemExamination examination = new SysGenitourinarySystemExamination();
+ SysGenitourinarySystemExamination saved = new SysGenitourinarySystemExamination();
+ saved.setID(4L);
+ when(sysGenitourinarySystemExaminationRepo.save(examination)).thenReturn(saved);
+
+ assertEquals(4L, service.saveSysGenitourinarySystemExamination(examination));
+ }
+
+ @Test
+ @DisplayName("saveSysGenitourinarySystemExamination should return null when nothing was stored")
+ void saveGenitourinaryExamination_shouldReturnNullWhenNothingStored() {
+ SysGenitourinarySystemExamination examination = new SysGenitourinarySystemExamination();
+ when(sysGenitourinarySystemExaminationRepo.save(examination)).thenReturn(null);
+
+ assertNull(service.saveSysGenitourinarySystemExamination(examination));
+ }
+ }
+
+ @Nested
+ @DisplayName("history report fetches")
+ class HistoryFetchTests {
+
+ /** A single result row whose every column is empty, as an unfilled visit returns. */
+ private ArrayList oneEmptyRow() {
+ ArrayList rows = new ArrayList<>();
+ rows.add(new Object[40]);
+ return rows;
+ }
+
+ @Test
+ @DisplayName("fetchBenPastMedicalHistory should render the stored rows with the report columns")
+ void fetchBenPastMedicalHistory_shouldRenderRowsWithColumns() {
+ when(benMedHistoryRepo.getBenPastHistory(BEN_REG_ID)).thenReturn(oneEmptyRow());
+
+ String result = service.fetchBenPastMedicalHistory(BEN_REG_ID);
+
+ assertTrue(result.contains("Illness Type"));
+ assertTrue(result.contains("\"data\""));
+ }
+
+ @Test
+ @DisplayName("fetchBenPastMedicalHistory should render only the columns when nothing is stored")
+ void fetchBenPastMedicalHistory_shouldRenderColumnsOnlyWhenEmpty() {
+ when(benMedHistoryRepo.getBenPastHistory(BEN_REG_ID)).thenReturn(new ArrayList<>());
+
+ assertTrue(service.fetchBenPastMedicalHistory(BEN_REG_ID).contains("Year of Surgery"));
+ }
+
+ @Test
+ @DisplayName("fetchBenPersonalTobaccoHistory should render the stored rows with the report columns")
+ void fetchBenPersonalTobaccoHistory_shouldRenderRowsWithColumns() {
+ when(benPersonalHabitRepo.getBenPersonalTobaccoHabitDetail(BEN_REG_ID)).thenReturn(oneEmptyRow());
+
+ assertTrue(service.fetchBenPersonalTobaccoHistory(BEN_REG_ID).contains("Tobacco Use Type"));
+ }
+
+ @Test
+ @DisplayName("fetchBenPersonalTobaccoHistory should render only the columns when nothing is stored")
+ void fetchBenPersonalTobaccoHistory_shouldRenderColumnsOnlyWhenEmpty() {
+ when(benPersonalHabitRepo.getBenPersonalTobaccoHabitDetail(BEN_REG_ID)).thenReturn(null);
+
+ assertTrue(service.fetchBenPersonalTobaccoHistory(BEN_REG_ID).contains("Tobacco Use Status"));
+ }
+
+ @Test
+ @DisplayName("fetchBenPersonalAlcoholHistory should render the stored rows with the report columns")
+ void fetchBenPersonalAlcoholHistory_shouldRenderRowsWithColumns() {
+ when(benPersonalHabitRepo.getBenPersonalAlcoholHabitDetail(BEN_REG_ID)).thenReturn(oneEmptyRow());
+
+ assertTrue(service.fetchBenPersonalAlcoholHistory(BEN_REG_ID).contains("Alcohol Type"));
+ }
+
+ @Test
+ @DisplayName("fetchBenPersonalAlcoholHistory should render only the columns when nothing is stored")
+ void fetchBenPersonalAlcoholHistory_shouldRenderColumnsOnlyWhenEmpty() {
+ when(benPersonalHabitRepo.getBenPersonalAlcoholHabitDetail(BEN_REG_ID)).thenReturn(null);
+
+ assertTrue(service.fetchBenPersonalAlcoholHistory(BEN_REG_ID).contains("Alcohol Intake Status"));
+ }
+
+ @Test
+ @DisplayName("fetchBenPersonalAllergyHistory should render the stored rows with the report columns")
+ void fetchBenPersonalAllergyHistory_shouldRenderRowsWithColumns() {
+ when(benAllergyHistoryRepo.getBenPersonalAllergyDetail(BEN_REG_ID)).thenReturn(oneEmptyRow());
+
+ assertTrue(service.fetchBenPersonalAllergyHistory(BEN_REG_ID).contains("Allergy Name"));
+ }
+
+ @Test
+ @DisplayName("fetchBenPersonalAllergyHistory should render only the columns when nothing is stored")
+ void fetchBenPersonalAllergyHistory_shouldRenderColumnsOnlyWhenEmpty() {
+ when(benAllergyHistoryRepo.getBenPersonalAllergyDetail(BEN_REG_ID)).thenReturn(null);
+
+ assertTrue(service.fetchBenPersonalAllergyHistory(BEN_REG_ID).contains("Allergy Status"));
+ }
+
+ @Test
+ @DisplayName("fetchBenPersonalMedicationHistory should render the stored rows with the report columns")
+ void fetchBenPersonalMedicationHistory_shouldRenderRowsWithColumns() {
+ when(benMedicationHistoryRepo.getBenMedicationHistoryDetail(BEN_REG_ID)).thenReturn(oneEmptyRow());
+
+ assertTrue(service.fetchBenPersonalMedicationHistory(BEN_REG_ID).contains("Current Medication"));
+ }
+
+ @Test
+ @DisplayName("fetchBenPersonalMedicationHistory should render only the columns when nothing is stored")
+ void fetchBenPersonalMedicationHistory_shouldRenderColumnsOnlyWhenEmpty() {
+ when(benMedicationHistoryRepo.getBenMedicationHistoryDetail(BEN_REG_ID)).thenReturn(null);
+
+ assertTrue(service.fetchBenPersonalMedicationHistory(BEN_REG_ID).contains("Date of Capture"));
+ }
+
+ @Test
+ @DisplayName("fetchBenPersonalFamilyHistory should render the stored rows with the report columns")
+ void fetchBenPersonalFamilyHistory_shouldRenderRowsWithColumns() {
+ when(benFamilyHistoryRepo.getBenFamilyHistoryDetail(BEN_REG_ID)).thenReturn(oneEmptyRow());
+
+ assertTrue(service.fetchBenPersonalFamilyHistory(BEN_REG_ID).contains("\"columns\""));
+ }
+
+ @Test
+ @DisplayName("fetchBenPersonalFamilyHistory should render only the columns when nothing is stored")
+ void fetchBenPersonalFamilyHistory_shouldRenderColumnsOnlyWhenEmpty() {
+ when(benFamilyHistoryRepo.getBenFamilyHistoryDetail(BEN_REG_ID)).thenReturn(null);
+
+ assertTrue(service.fetchBenPersonalFamilyHistory(BEN_REG_ID).contains("Date of Capture"));
+ }
+
+ @Test
+ @DisplayName("fetchBenPhysicalHistory should render the stored rows with the report columns")
+ void fetchBenPhysicalHistory_shouldRenderRowsWithColumns() {
+ when(physicalActivityTypeRepo.getBenPhysicalHistoryDetail(BEN_REG_ID)).thenReturn(oneEmptyRow());
+
+ assertTrue(service.fetchBenPhysicalHistory(BEN_REG_ID).contains("\"columns\""));
+ }
+
+ @Test
+ @DisplayName("fetchBenPhysicalHistory should render only the columns when nothing is stored")
+ void fetchBenPhysicalHistory_shouldRenderColumnsOnlyWhenEmpty() {
+ when(physicalActivityTypeRepo.getBenPhysicalHistoryDetail(BEN_REG_ID)).thenReturn(null);
+
+ assertTrue(service.fetchBenPhysicalHistory(BEN_REG_ID).contains("Date of Capture"));
+ }
+
+ @Test
+ @DisplayName("fetchBenMenstrualHistory should render the stored rows with the report columns")
+ void fetchBenMenstrualHistory_shouldRenderRowsWithColumns() {
+ when(benMenstrualDetailsRepo.getBenMenstrualDetail(BEN_REG_ID)).thenReturn(oneEmptyRow());
+
+ assertTrue(service.fetchBenMenstrualHistory(BEN_REG_ID).contains("\"columns\""));
+ }
+
+ @Test
+ @DisplayName("fetchBenMenstrualHistory should render only the columns when nothing is stored")
+ void fetchBenMenstrualHistory_shouldRenderColumnsOnlyWhenEmpty() {
+ when(benMenstrualDetailsRepo.getBenMenstrualDetail(BEN_REG_ID)).thenReturn(null);
+
+ assertTrue(service.fetchBenMenstrualHistory(BEN_REG_ID).contains("Date of Capture"));
+ }
+
+ @Test
+ @DisplayName("fetchBenPastObstetricHistory should render the stored rows with the report columns")
+ void fetchBenPastObstetricHistory_shouldRenderRowsWithColumns() {
+ when(femaleObstetricHistoryRepo.getBenFemaleObstetricHistoryDetail(BEN_REG_ID)).thenReturn(oneEmptyRow());
+
+ assertTrue(service.fetchBenPastObstetricHistory(BEN_REG_ID).contains("\"columns\""));
+ }
+
+ @Test
+ @DisplayName("fetchBenPastObstetricHistory should render only the columns when nothing is stored")
+ void fetchBenPastObstetricHistory_shouldRenderColumnsOnlyWhenEmpty() {
+ when(femaleObstetricHistoryRepo.getBenFemaleObstetricHistoryDetail(BEN_REG_ID)).thenReturn(null);
+
+ assertTrue(service.fetchBenPastObstetricHistory(BEN_REG_ID).contains("Date of Capture"));
+ }
+
+ @Test
+ @DisplayName("fetchBenComorbidityHistory should render the stored rows with the report columns")
+ void fetchBenComorbidityHistory_shouldRenderRowsWithColumns() {
+ when(bencomrbidityCondRepo.getBencomrbidityCondDetails(BEN_REG_ID)).thenReturn(oneEmptyRow());
+
+ assertTrue(service.fetchBenComorbidityHistory(BEN_REG_ID).contains("\"columns\""));
+ }
+
+ @Test
+ @DisplayName("fetchBenComorbidityHistory should render only the columns when nothing is stored")
+ void fetchBenComorbidityHistory_shouldRenderColumnsOnlyWhenEmpty() {
+ when(bencomrbidityCondRepo.getBencomrbidityCondDetails(BEN_REG_ID)).thenReturn(null);
+
+ assertTrue(service.fetchBenComorbidityHistory(BEN_REG_ID).contains("Date of Capture"));
+ }
+
+ @Test
+ @DisplayName("fetchBenImmunizationHistory should render the stored rows with the report columns")
+ void fetchBenImmunizationHistory_shouldRenderRowsWithColumns() {
+ when(childVaccineDetail1Repo.getBenChildVaccineDetails(BEN_REG_ID)).thenReturn(oneEmptyRow());
+
+ assertTrue(service.fetchBenImmunizationHistory(BEN_REG_ID).contains("\"columns\""));
+ }
+
+ @Test
+ @DisplayName("fetchBenImmunizationHistory should render only the columns when nothing is stored")
+ void fetchBenImmunizationHistory_shouldRenderColumnsOnlyWhenEmpty() {
+ when(childVaccineDetail1Repo.getBenChildVaccineDetails(BEN_REG_ID)).thenReturn(null);
+
+ assertTrue(service.fetchBenImmunizationHistory(BEN_REG_ID).contains("Date of Capture"));
+ }
+
+ @Test
+ @DisplayName("fetchBenOptionalVaccineHistory should render the stored rows with the report columns")
+ void fetchBenOptionalVaccineHistory_shouldRenderRowsWithColumns() {
+ when(childOptionalVaccineDetailRepo.getBenOptionalVaccineDetail(BEN_REG_ID)).thenReturn(oneEmptyRow());
+
+ assertTrue(service.fetchBenOptionalVaccineHistory(BEN_REG_ID).contains("\"columns\""));
+ }
+
+ @Test
+ @DisplayName("fetchBenOptionalVaccineHistory should render only the columns when nothing is stored")
+ void fetchBenOptionalVaccineHistory_shouldRenderColumnsOnlyWhenEmpty() {
+ when(childOptionalVaccineDetailRepo.getBenOptionalVaccineDetail(BEN_REG_ID)).thenReturn(null);
+
+ assertTrue(service.fetchBenOptionalVaccineHistory(BEN_REG_ID).contains("Date of Capture"));
+ }
+ }
+
+ @Nested
+ @DisplayName("per visit history lookups")
+ class PerVisitLookupTests {
+
+ private ArrayList oneEmptyRow() {
+ ArrayList rows = new ArrayList<>();
+ rows.add(new Object[60]);
+ return rows;
+ }
+
+ @Test
+ @DisplayName("getBenChiefComplaints should render the stored complaints as JSON")
+ void getBenChiefComplaints_shouldRenderJson() {
+ when(benChiefComplaintRepo.getBenChiefComplaints(BEN_REG_ID, VISIT_CODE)).thenReturn(oneEmptyRow());
+
+ assertNotNull(service.getBenChiefComplaints(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getFamilyHistoryDetail should return the stored family history for the visit")
+ void getFamilyHistoryDetail_shouldReturnStoredHistory() {
+ when(benFamilyHistoryRepo.getBenFamilyHisDetail(BEN_REG_ID, VISIT_CODE)).thenReturn(oneEmptyRow());
+
+ assertNotNull(service.getFamilyHistoryDetail(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getPhysicalActivityType should delegate to the physical activity repository")
+ void getPhysicalActivityType_shouldDelegateToRepo() {
+ PhysicalActivityType stored = new PhysicalActivityType();
+ when(physicalActivityTypeRepo.getBenPhysicalHistoryDetails(BEN_REG_ID, VISIT_CODE)).thenReturn(stored);
+
+ assertEquals(stored, service.getPhysicalActivityType(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryIdrsDetails should return the stored IDRS row for the visit")
+ void getBeneficiaryIdrsDetails_shouldReturnStoredRow() {
+ when(iDRSDataRepo.getBenIdrsDetail(BEN_REG_ID, VISIT_CODE)).thenReturn(oneEmptyRow());
+
+ assertNotNull(service.getBeneficiaryIdrsDetails(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getPastHistoryData should return the stored past history for the visit")
+ void getPastHistoryData_shouldReturnStoredHistory() {
+ when(benMedHistoryRepo.getBenPastHistory(BEN_REG_ID, VISIT_CODE)).thenReturn(oneEmptyRow());
+
+ assertNotNull(service.getPastHistoryData(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getComorbidityConditionsHistory should return the stored comorbid conditions for the visit")
+ void getComorbidityConditionsHistory_shouldReturnStoredConditions() {
+ when(bencomrbidityCondRepo.getBencomrbidityCondDetails(BEN_REG_ID, VISIT_CODE)).thenReturn(oneEmptyRow());
+
+ assertNotNull(service.getComorbidityConditionsHistory(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getMedicationHistory should return the stored medication history for the visit")
+ void getMedicationHistory_shouldReturnStoredHistory() {
+ when(benMedicationHistoryRepo.getBenMedicationHistoryDetail(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(oneEmptyRow());
+
+ assertNotNull(service.getMedicationHistory(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getPersonalHistory should merge the stored habits with the allergy history")
+ void getPersonalHistory_shouldMergeHabitsAndAllergies() {
+ when(benPersonalHabitRepo.getBenPersonalHabitDetail(BEN_REG_ID, VISIT_CODE)).thenReturn(oneEmptyRow());
+ when(benAllergyHistoryRepo.getBenPersonalAllergyDetail(BEN_REG_ID, VISIT_CODE)).thenReturn(oneEmptyRow());
+
+ assertNotNull(service.getPersonalHistory(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getPersonalHistory should build an empty habit record when nothing is stored")
+ void getPersonalHistory_shouldBuildEmptyRecordWhenNothingStored() {
+ when(benPersonalHabitRepo.getBenPersonalHabitDetail(BEN_REG_ID, VISIT_CODE)).thenReturn(new ArrayList<>());
+ when(benAllergyHistoryRepo.getBenPersonalAllergyDetail(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(new ArrayList<>());
+
+ assertNotNull(service.getPersonalHistory(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getFamilyHistory should return the stored family history for the visit")
+ void getFamilyHistory_shouldReturnStoredHistory() {
+ when(benFamilyHistoryRepo.getBenFamilyHistoryDetail(BEN_REG_ID, VISIT_CODE)).thenReturn(oneEmptyRow());
+
+ assertNotNull(service.getFamilyHistory(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getMenstrualHistory should return the stored menstrual history for the visit")
+ void getMenstrualHistory_shouldReturnStoredHistory() {
+ when(benMenstrualDetailsRepo.getBenMenstrualDetail(BEN_REG_ID, VISIT_CODE)).thenReturn(oneEmptyRow());
+
+ assertNotNull(service.getMenstrualHistory(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getFemaleObstetricHistory should return the stored obstetric history for the visit")
+ void getFemaleObstetricHistory_shouldReturnStoredHistory() {
+ when(femaleObstetricHistoryRepo.getBenFemaleObstetricHistoryDetail(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(oneEmptyRow());
+
+ assertNotNull(service.getFemaleObstetricHistory(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getChildOptionalVaccineHistory should return the stored optional vaccines for the visit")
+ void getChildOptionalVaccineHistory_shouldReturnStoredVaccines() {
+ when(childOptionalVaccineDetailRepo.getBenOptionalVaccineDetail(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(oneEmptyRow());
+
+ assertNotNull(service.getChildOptionalVaccineHistory(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getImmunizationHistory should return the stored immunisations for the visit")
+ void getImmunizationHistory_shouldReturnStoredImmunisations() {
+ when(childVaccineDetail1Repo.getBenChildVaccineDetails(BEN_REG_ID, VISIT_CODE)).thenReturn(oneEmptyRow());
+
+ assertNotNull(service.getImmunizationHistory(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getGeneralExaminationData should expand the comma separated danger signs")
+ void getGeneralExaminationData_shouldExpandDangerSigns() {
+ PhyGeneralExamination stored = new PhyGeneralExamination();
+ stored.setTypeOfDangerSign("Fever,Bleeding");
+ when(phyGeneralExaminationRepo.getPhyGeneralExaminationData(BEN_REG_ID, VISIT_CODE)).thenReturn(stored);
+
+ PhyGeneralExamination result = service.getGeneralExaminationData(BEN_REG_ID, VISIT_CODE);
+
+ assertNotNull(result.getTypeOfDangerSigns());
+ assertEquals(2, result.getTypeOfDangerSigns().size());
+ }
+
+ @Test
+ @DisplayName("getGeneralExaminationData should leave the danger signs alone when none are stored")
+ void getGeneralExaminationData_shouldLeaveDangerSignsAloneWhenNoneStored() {
+ PhyGeneralExamination stored = new PhyGeneralExamination();
+ when(phyGeneralExaminationRepo.getPhyGeneralExaminationData(BEN_REG_ID, VISIT_CODE)).thenReturn(stored);
+
+ assertNotNull(service.getGeneralExaminationData(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getGeneralExaminationData should return null when the visit has no general examination")
+ void getGeneralExaminationData_shouldReturnNullWithoutExamination() {
+ when(phyGeneralExaminationRepo.getPhyGeneralExaminationData(BEN_REG_ID, VISIT_CODE)).thenReturn(null);
+
+ assertNull(service.getGeneralExaminationData(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getHeadToToeExaminationData should delegate to the head to toe repository")
+ void getHeadToToeExaminationData_shouldDelegateToRepo() {
+ PhyHeadToToeExamination stored = new PhyHeadToToeExamination();
+ when(phyHeadToToeExaminationRepo.getPhyHeadToToeExaminationData(BEN_REG_ID, VISIT_CODE)).thenReturn(stored);
+
+ assertEquals(stored, service.getHeadToToeExaminationData(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getSysGastrointestinalExamination should delegate to the gastrointestinal repository")
+ void getSysGastrointestinalExamination_shouldDelegateToRepo() {
+ SysGastrointestinalExamination stored = new SysGastrointestinalExamination();
+ when(sysGastrointestinalExaminationRepo.getSSysGastrointestinalExamination(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(stored);
+
+ assertEquals(stored, service.getSysGastrointestinalExamination(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getCardiovascularExamination should delegate to the cardiovascular repository")
+ void getCardiovascularExamination_shouldDelegateToRepo() {
+ SysCardiovascularExamination stored = new SysCardiovascularExamination();
+ when(sysCardiovascularExaminationRepo.getSysCardiovascularExaminationData(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(stored);
+
+ assertEquals(stored, service.getCardiovascularExamination(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getRespiratoryExamination should delegate to the respiratory repository")
+ void getRespiratoryExamination_shouldDelegateToRepo() {
+ SysRespiratoryExamination stored = new SysRespiratoryExamination();
+ when(sysRespiratoryExaminationRepo.getSysRespiratoryExaminationData(BEN_REG_ID, VISIT_CODE)).thenReturn(stored);
+
+ assertEquals(stored, service.getRespiratoryExamination(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getSysCentralNervousExamination should delegate to the central nervous repository")
+ void getSysCentralNervousExamination_shouldDelegateToRepo() {
+ SysCentralNervousExamination stored = new SysCentralNervousExamination();
+ when(sysCentralNervousExaminationRepo.getSysCentralNervousExaminationData(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(stored);
+
+ assertEquals(stored, service.getSysCentralNervousExamination(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getMusculoskeletalExamination should delegate to the musculoskeletal repository")
+ void getMusculoskeletalExamination_shouldDelegateToRepo() {
+ SysMusculoskeletalSystemExamination stored = new SysMusculoskeletalSystemExamination();
+ when(sysMusculoskeletalSystemExaminationRepo.getSysMusculoskeletalSystemExamination(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(stored);
+
+ assertEquals(stored, service.getMusculoskeletalExamination(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getGenitourinaryExamination should delegate to the genitourinary repository")
+ void getGenitourinaryExamination_shouldDelegateToRepo() {
+ SysGenitourinarySystemExamination stored = new SysGenitourinarySystemExamination();
+ when(sysGenitourinarySystemExaminationRepo.getSysGenitourinarySystemExaminationData(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(stored);
+
+ assertEquals(stored, service.getGenitourinaryExamination(BEN_REG_ID, VISIT_CODE));
+ }
+ }
+
+ @Nested
+ @DisplayName("history updates")
+ class HistoryUpdateTests {
+
+ /** One already-processed row and one fresh row, as a re-edited visit returns. */
+ private ArrayList statuses() {
+ ArrayList rows = new ArrayList<>();
+ rows.add(new Object[] { 1L, "P" });
+ rows.add(new Object[] { 2L, "N" });
+ return rows;
+ }
+
+ private ArrayList integerKeyedStatuses() {
+ ArrayList rows = new ArrayList<>();
+ rows.add(new Object[] { 1, "P" });
+ rows.add(new Object[] { 2, "N" });
+ return rows;
+ }
+
+ @Test
+ @DisplayName("updateBenChiefComplaints should replace the stored complaints and report the row count")
+ void updateBenChiefComplaints_shouldReplaceStoredComplaints() {
+ BenChiefComplaint complaint = new BenChiefComplaint();
+ complaint.setBeneficiaryRegID(BEN_REG_ID);
+ complaint.setVisitCode(VISIT_CODE);
+ List complaints = Collections.singletonList(complaint);
+ when(benChiefComplaintRepo.saveAll(complaints)).thenReturn(complaints);
+
+ assertEquals(1, service.updateBenChiefComplaints(complaints));
+ verify(benChiefComplaintRepo).deleteExistingBenChiefComplaints(BEN_REG_ID, VISIT_CODE);
+ }
+
+ @Test
+ @DisplayName("updateBenChiefComplaints should report no change for an empty complaint list")
+ void updateBenChiefComplaints_shouldReportNoChangeForEmptyList() {
+ assertEquals(0, service.updateBenChiefComplaints(Collections.emptyList()));
+ }
+
+ @Test
+ @DisplayName("updateBenChiefComplaints should report no change for a null complaint list")
+ void updateBenChiefComplaints_shouldReportNoChangeForNullList() {
+ assertEquals(0, service.updateBenChiefComplaints(null));
+ }
+
+ @Test
+ @DisplayName("updateBenPastHistoryDetails should soft delete the stored rows before writing the new ones")
+ void updateBenPastHistoryDetails_shouldSoftDeleteBeforeWriting() throws Exception {
+ BenMedHistory history = new BenMedHistory();
+ history.setBeneficiaryRegID(BEN_REG_ID);
+ history.setVisitCode(VISIT_CODE);
+ ArrayList> illnesses = new ArrayList<>();
+ Map illness = new HashMap<>();
+ illness.put("illnessType", "Asthma");
+ illnesses.add(illness);
+ history.setPastIllness(illnesses);
+ history.setPastSurgery(new ArrayList<>());
+ when(benMedHistoryRepo.getBenMedHistoryStatus(BEN_REG_ID, VISIT_CODE)).thenReturn(statuses());
+ when(benMedHistoryRepo.saveAll(any())).thenAnswer(echoList());
+
+ assertEquals(1, service.updateBenPastHistoryDetails(history));
+ verify(benMedHistoryRepo).deleteExistingBenMedHistory(1L, "U");
+ verify(benMedHistoryRepo).deleteExistingBenMedHistory(2L, "N");
+ }
+
+ @Test
+ @DisplayName("updateBenPastHistoryDetails should report no change for a null payload")
+ void updateBenPastHistoryDetails_shouldReportNoChangeForNullPayload() throws Exception {
+ assertEquals(0, service.updateBenPastHistoryDetails(null));
+ }
+
+ @Test
+ @DisplayName("updateBenComorbidConditions should soft delete the stored rows before writing the new ones")
+ void updateBenComorbidConditions_shouldSoftDeleteBeforeWriting() {
+ WrapperComorbidCondDetails wrapper = new WrapperComorbidCondDetails();
+ wrapper.setBeneficiaryRegID(BEN_REG_ID);
+ wrapper.setVisitCode(VISIT_CODE);
+ BencomrbidityCondDetails condition = new BencomrbidityCondDetails();
+ condition.setComorbidCondition("Diabetes");
+ wrapper.setComorbidityConcurrentConditionsList(
+ new ArrayList<>(Collections.singletonList(condition)));
+ when(bencomrbidityCondRepo.getBenComrbidityCondHistoryStatus(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(statuses());
+ when(bencomrbidityCondRepo.saveAll(any())).thenAnswer(echoList());
+
+ assertEquals(1, service.updateBenComorbidConditions(wrapper));
+ verify(bencomrbidityCondRepo).deleteExistingBenComrbidityCondDetails(1L, "U");
+ verify(bencomrbidityCondRepo).deleteExistingBenComrbidityCondDetails(2L, "N");
+ }
+
+ @Test
+ @DisplayName("updateBenComorbidConditions should report no change for a null payload")
+ void updateBenComorbidConditions_shouldReportNoChangeForNullPayload() {
+ assertEquals(0, service.updateBenComorbidConditions(null));
+ }
+
+ @Test
+ @DisplayName("updateBenMedicationHistory should soft delete the stored rows before writing the new ones")
+ void updateBenMedicationHistory_shouldSoftDeleteBeforeWriting() {
+ WrapperMedicationHistory wrapper = new WrapperMedicationHistory();
+ wrapper.setBeneficiaryRegID(BEN_REG_ID);
+ wrapper.setVisitCode(VISIT_CODE);
+ BenMedicationHistory entry = new BenMedicationHistory();
+ entry.setCurrentMedication("Metformin");
+ wrapper.setMedicationHistoryList(new ArrayList<>(Collections.singletonList(entry)));
+ when(benMedicationHistoryRepo.getBenMedicationHistoryStatus(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(statuses());
+ when(benMedicationHistoryRepo.saveAll(any())).thenAnswer(echoList());
+
+ assertEquals(1, service.updateBenMedicationHistory(wrapper));
+ }
+
+ @Test
+ @DisplayName("updateBenMedicationHistory should report no change for a null payload")
+ void updateBenMedicationHistory_shouldReportNoChangeForNullPayload() {
+ assertEquals(0, service.updateBenMedicationHistory(null));
+ }
+
+ @Test
+ @DisplayName("updateBenPersonalHistory should soft delete the stored rows before writing the new ones")
+ void updateBenPersonalHistory_shouldSoftDeleteBeforeWriting() {
+ BenPersonalHabit habit = new BenPersonalHabit();
+ habit.setBeneficiaryRegID(BEN_REG_ID);
+ habit.setVisitCode(VISIT_CODE);
+ habit.setTobaccoList(new ArrayList<>());
+ habit.setAlcoholList(new ArrayList<>());
+ habit.setAllergicList(new ArrayList<>());
+ when(benPersonalHabitRepo.getBenPersonalHistoryStatus(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(integerKeyedStatuses());
+
+ assertEquals(1, service.updateBenPersonalHistory(habit));
+ verify(benPersonalHabitRepo).deleteExistingBenPersonalHistory(1, "U");
+ verify(benPersonalHabitRepo).deleteExistingBenPersonalHistory(2, "N");
+ }
+
+ @Test
+ @DisplayName("updateBenPersonalHistory should report no change for a null payload")
+ void updateBenPersonalHistory_shouldReportNoChangeForNullPayload() {
+ assertEquals(0, service.updateBenPersonalHistory(null));
+ }
+
+ @Test
+ @DisplayName("updateBenAllergicHistory should soft delete the stored rows before writing the new ones")
+ void updateBenAllergicHistory_shouldSoftDeleteBeforeWriting() {
+ BenAllergyHistory allergy = new BenAllergyHistory();
+ allergy.setBeneficiaryRegID(BEN_REG_ID);
+ allergy.setVisitCode(VISIT_CODE);
+ allergy.setAllergicList(new ArrayList<>());
+ when(benAllergyHistoryRepo.getBenAllergyHistoryStatus(BEN_REG_ID, VISIT_CODE)).thenReturn(statuses());
+
+ assertEquals(1, service.updateBenAllergicHistory(allergy));
+ verify(benAllergyHistoryRepo).deleteExistingBenAllergyHistory(1L, "U");
+ }
+
+ @Test
+ @DisplayName("updateBenAllergicHistory should report no change for a null payload")
+ void updateBenAllergicHistory_shouldReportNoChangeForNullPayload() {
+ assertEquals(0, service.updateBenAllergicHistory(null));
+ }
+
+ @Test
+ @DisplayName("updateBenFamilyHistory should soft delete the stored rows before writing the new ones")
+ void updateBenFamilyHistory_shouldSoftDeleteBeforeWriting() {
+ BenFamilyHistory history = new BenFamilyHistory();
+ history.setBeneficiaryRegID(BEN_REG_ID);
+ history.setVisitCode(VISIT_CODE);
+ history.setFamilyDiseaseList(new ArrayList<>());
+ when(benFamilyHistoryRepo.getBenFamilyHistoryStatus(BEN_REG_ID, VISIT_CODE)).thenReturn(statuses());
+
+ assertEquals(1, service.updateBenFamilyHistory(history));
+ verify(benFamilyHistoryRepo).deleteExistingBenFamilyHistory(1L, "U");
+ }
+
+ @Test
+ @DisplayName("updateBenFamilyHistory should report no change for a null payload")
+ void updateBenFamilyHistory_shouldReportNoChangeForNullPayload() {
+ assertEquals(0, service.updateBenFamilyHistory(null));
+ }
+
+ @Test
+ @DisplayName("updateMenstrualHistory should update the stored row when one already exists")
+ void updateMenstrualHistory_shouldUpdateExistingRow() {
+ BenMenstrualDetails details = new BenMenstrualDetails();
+ details.setBeneficiaryRegID(BEN_REG_ID);
+ details.setVisitCode(VISIT_CODE);
+ ArrayList> problems = new ArrayList<>();
+ Map problem = new HashMap<>();
+ problem.put("menstrualProblemID", 1);
+ problem.put("problemName", "Cramps");
+ problems.add(problem);
+ details.setMenstrualProblemList(problems);
+ when(benMenstrualDetailsRepo.getBenMenstrualDetailStatus(BEN_REG_ID, VISIT_CODE)).thenReturn("P");
+
+ assertEquals(0, service.updateMenstrualHistory(details));
+ assertEquals("1", details.getMenstrualProblemID());
+ }
+
+ @Test
+ @DisplayName("updateMenstrualHistory should insert a new row when the visit has none")
+ void updateMenstrualHistory_shouldInsertNewRow() {
+ BenMenstrualDetails details = new BenMenstrualDetails();
+ details.setBeneficiaryRegID(BEN_REG_ID);
+ details.setVisitCode(VISIT_CODE);
+ details.setModifiedBy("nurse1");
+ when(benMenstrualDetailsRepo.getBenMenstrualDetailStatus(BEN_REG_ID, VISIT_CODE)).thenReturn(null);
+ BenMenstrualDetails saved = new BenMenstrualDetails();
+ saved.setBenMenstrualID(9);
+ when(benMenstrualDetailsRepo.save(details)).thenReturn(saved);
+
+ assertEquals(1, service.updateMenstrualHistory(details));
+ assertEquals("nurse1", details.getCreatedBy());
+ }
+
+ @Test
+ @DisplayName("updateMenstrualHistory should report no change for a null payload")
+ void updateMenstrualHistory_shouldReportNoChangeForNullPayload() {
+ assertEquals(0, service.updateMenstrualHistory(null));
+ }
+
+ @Test
+ @DisplayName("updatePastObstetricHistory should soft delete the stored rows before writing the new ones")
+ void updatePastObstetricHistory_shouldSoftDeleteBeforeWriting() {
+ WrapperFemaleObstetricHistory wrapper = new WrapperFemaleObstetricHistory();
+ wrapper.setBeneficiaryRegID(BEN_REG_ID);
+ wrapper.setVisitCode(VISIT_CODE);
+ wrapper.setFemaleObstetricHistoryList(new ArrayList<>());
+ when(femaleObstetricHistoryRepo.getBenObstetricHistoryStatus(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(statuses());
+
+ assertEquals(1, service.updatePastObstetricHistory(wrapper));
+ verify(femaleObstetricHistoryRepo).deleteExistingObstetricHistory(1L, "U");
+ }
+
+ @Test
+ @DisplayName("updatePastObstetricHistory should report no change for a null payload")
+ void updatePastObstetricHistory_shouldReportNoChangeForNullPayload() {
+ assertEquals(0, service.updatePastObstetricHistory(null));
+ }
+
+ @Test
+ @DisplayName("updateChildOptionalVaccineDetail should soft delete the stored rows before writing the new ones")
+ void updateChildOptionalVaccineDetail_shouldSoftDeleteBeforeWriting() {
+ WrapperChildOptionalVaccineDetail wrapper = new WrapperChildOptionalVaccineDetail();
+ wrapper.setBeneficiaryRegID(BEN_REG_ID);
+ wrapper.setVisitCode(VISIT_CODE);
+ wrapper.setChildOptionalVaccineList(new ArrayList<>());
+ when(childOptionalVaccineDetailRepo.getBenChildOptionalVaccineHistoryStatus(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(statuses());
+
+ assertEquals(1, service.updateChildOptionalVaccineDetail(wrapper));
+ }
+
+ @Test
+ @DisplayName("updateChildOptionalVaccineDetail should report no change for a null payload")
+ void updateChildOptionalVaccineDetail_shouldReportNoChangeForNullPayload() {
+ assertEquals(0, service.updateChildOptionalVaccineDetail(null));
+ }
+
+ @Test
+ @DisplayName("updateChildImmunizationDetail should report no change for an empty immunisation list")
+ void updateChildImmunizationDetail_shouldReportNoChangeForEmptyList() {
+ WrapperImmunizationHistory wrapper = new WrapperImmunizationHistory();
+ wrapper.setImmunizationList(new ArrayList<>());
+
+ assertEquals(0, service.updateChildImmunizationDetail(wrapper));
+ }
+
+ @Test
+ @DisplayName("updatePhyGeneralExamination should mark an already processed row as updated")
+ void updatePhyGeneralExamination_shouldMarkProcessedRowAsUpdated() {
+ PhyGeneralExamination examination = new PhyGeneralExamination();
+ examination.setBeneficiaryRegID(BEN_REG_ID);
+ examination.setVisitCode(VISIT_CODE);
+ examination.setTypeOfDangerSigns(new ArrayList<>(Arrays.asList("Fever")));
+ when(phyGeneralExaminationRepo.getBenGeneralExaminationStatus(BEN_REG_ID, VISIT_CODE)).thenReturn("P");
+
+ assertEquals(0, service.updatePhyGeneralExamination(examination));
+ assertEquals("Fever,", examination.getTypeOfDangerSign());
+ }
+
+ @Test
+ @DisplayName("updatePhyGeneralExamination should report no change for a null payload")
+ void updatePhyGeneralExamination_shouldReportNoChangeForNullPayload() {
+ assertEquals(0, service.updatePhyGeneralExamination(null));
+ }
+
+ @Test
+ @DisplayName("updatePhyHeadToToeExamination should read the processed flag before updating")
+ void updatePhyHeadToToeExamination_shouldReadProcessedFlag() {
+ PhyHeadToToeExamination examination = new PhyHeadToToeExamination();
+ examination.setBeneficiaryRegID(BEN_REG_ID);
+ examination.setVisitCode(VISIT_CODE);
+ when(phyHeadToToeExaminationRepo.getBenHeadToToeExaminationStatus(BEN_REG_ID, VISIT_CODE)).thenReturn("N");
+
+ assertEquals(0, service.updatePhyHeadToToeExamination(examination));
+ }
+
+ @Test
+ @DisplayName("updatePhyHeadToToeExamination should report no change for a null payload")
+ void updatePhyHeadToToeExamination_shouldReportNoChangeForNullPayload() {
+ assertEquals(0, service.updatePhyHeadToToeExamination(null));
+ }
+
+ @Test
+ @DisplayName("updateSysCardiovascularExamination should read the processed flag before updating")
+ void updateSysCardiovascularExamination_shouldReadProcessedFlag() {
+ SysCardiovascularExamination examination = new SysCardiovascularExamination();
+ examination.setBeneficiaryRegID(BEN_REG_ID);
+ examination.setVisitCode(VISIT_CODE);
+ when(sysCardiovascularExaminationRepo.getBenCardiovascularExaminationStatus(BEN_REG_ID, VISIT_CODE))
+ .thenReturn("P");
+
+ assertEquals(0, service.updateSysCardiovascularExamination(examination));
+ }
+
+ @Test
+ @DisplayName("updateSysCardiovascularExamination should report no change for a null payload")
+ void updateSysCardiovascularExamination_shouldReportNoChangeForNullPayload() {
+ assertEquals(0, service.updateSysCardiovascularExamination(null));
+ }
+
+ @Test
+ @DisplayName("updateSysRespiratoryExamination should report no change for a null payload")
+ void updateSysRespiratoryExamination_shouldReportNoChangeForNullPayload() {
+ assertEquals(0, service.updateSysRespiratoryExamination(null));
+ }
+
+ @Test
+ @DisplayName("updateSysCentralNervousExamination should read the processed flag before updating")
+ void updateSysCentralNervousExamination_shouldReadProcessedFlag() {
+ SysCentralNervousExamination examination = new SysCentralNervousExamination();
+ examination.setBeneficiaryRegID(BEN_REG_ID);
+ examination.setVisitCode(VISIT_CODE);
+ when(sysCentralNervousExaminationRepo.getBenCentralNervousExaminationStatus(BEN_REG_ID, VISIT_CODE))
+ .thenReturn("P");
+
+ assertEquals(0, service.updateSysCentralNervousExamination(examination));
+ }
+
+ @Test
+ @DisplayName("updateSysCentralNervousExamination should report no change for a null payload")
+ void updateSysCentralNervousExamination_shouldReportNoChangeForNullPayload() {
+ assertEquals(0, service.updateSysCentralNervousExamination(null));
+ }
+
+ @Test
+ @DisplayName("updateSysMusculoskeletalSystemExamination should read the processed flag before updating")
+ void updateSysMusculoskeletalSystemExamination_shouldReadProcessedFlag() {
+ SysMusculoskeletalSystemExamination examination = new SysMusculoskeletalSystemExamination();
+ examination.setBeneficiaryRegID(BEN_REG_ID);
+ examination.setVisitCode(VISIT_CODE);
+ when(sysMusculoskeletalSystemExaminationRepo
+ .getBenMusculoskeletalSystemExaminationStatus(BEN_REG_ID, VISIT_CODE)).thenReturn("P");
+
+ assertEquals(0, service.updateSysMusculoskeletalSystemExamination(examination));
+ }
+
+ @Test
+ @DisplayName("updateSysMusculoskeletalSystemExamination should report no change for a null payload")
+ void updateSysMusculoskeletalSystemExamination_shouldReportNoChangeForNullPayload() {
+ assertEquals(0, service.updateSysMusculoskeletalSystemExamination(null));
+ }
+
+ @Test
+ @DisplayName("updateSysGenitourinarySystemExamination should read the processed flag before updating")
+ void updateSysGenitourinarySystemExamination_shouldReadProcessedFlag() {
+ SysGenitourinarySystemExamination examination = new SysGenitourinarySystemExamination();
+ examination.setBeneficiaryRegID(BEN_REG_ID);
+ examination.setVisitCode(VISIT_CODE);
+ when(sysGenitourinarySystemExaminationRepo
+ .getBenGenitourinarySystemExaminationStatus(BEN_REG_ID, VISIT_CODE)).thenReturn("P");
+
+ assertEquals(0, service.updateSysGenitourinarySystemExamination(examination));
+ }
+
+ @Test
+ @DisplayName("updateSysGenitourinarySystemExamination should report no change for a null payload")
+ void updateSysGenitourinarySystemExamination_shouldReportNoChangeForNullPayload() {
+ assertEquals(0, service.updateSysGenitourinarySystemExamination(null));
+ }
+
+ @Test
+ @DisplayName("updateSysGastrointestinalExamination should report no change for a null payload")
+ void updateSysGastrointestinalExamination_shouldReportNoChangeForNullPayload() {
+ assertEquals(0, service.updateSysGastrointestinalExamination(null));
+ }
+ }
+
+ @Nested
+ @DisplayName("prescriptions and prescribed drugs")
+ class PrescriptionTests {
+
+ private SCTDescription diagnosis(String term, String conceptId) {
+ SCTDescription description = new SCTDescription();
+ description.setTerm(term);
+ description.setConceptID(conceptId);
+ return description;
+ }
+
+ private PrescriptionDetail stored(Long prescriptionId) {
+ PrescriptionDetail stored = new PrescriptionDetail();
+ stored.setPrescriptionID(prescriptionId);
+ return stored;
+ }
+
+ @Test
+ @DisplayName("savePrescriptionDetailsAndGetPrescriptionID should build the prescription and return its id")
+ void savePrescriptionDetailsAndGetPrescriptionID_shouldBuildAndReturnId() {
+ when(prescriptionDetailRepo.save(any(PrescriptionDetail.class))).thenReturn(stored(5L));
+
+ Long result = service.savePrescriptionDetailsAndGetPrescriptionID(BEN_REG_ID, 3L, 9, "nurse1",
+ "X-Ray", VISIT_CODE, 7, 8, "after food",
+ new ArrayList<>(Collections.singletonList(diagnosis("Fever", "386661006"))));
+
+ assertEquals(5L, result);
+
+ ArgumentCaptor captor = ArgumentCaptor.forClass(PrescriptionDetail.class);
+ verify(prescriptionDetailRepo).save(captor.capture());
+ assertEquals(BEN_REG_ID, captor.getValue().getBeneficiaryRegID());
+ assertEquals("after food", captor.getValue().getInstruction());
+ assertEquals("Fever", captor.getValue().getDiagnosisProvided());
+ assertEquals("386661006", captor.getValue().getDiagnosisProvided_SCTCode());
+ }
+
+ @Test
+ @DisplayName("savePrescriptionDetailsAndGetPrescriptionID should omit an absent instruction and diagnosis list")
+ void savePrescriptionDetailsAndGetPrescriptionID_shouldOmitAbsentOptionalFields() {
+ when(prescriptionDetailRepo.save(any(PrescriptionDetail.class))).thenReturn(stored(5L));
+
+ assertEquals(5L, service.savePrescriptionDetailsAndGetPrescriptionID(BEN_REG_ID, 3L, 9, "nurse1",
+ "X-Ray", VISIT_CODE, 7, 8, null, null));
+ }
+
+ @Test
+ @DisplayName("savePrescriptionCovid should carry the doctor diagnosis onto the prescription")
+ void savePrescriptionCovid_shouldCarryDoctorDiagnosis() {
+ when(prescriptionDetailRepo.save(any(PrescriptionDetail.class))).thenReturn(stored(5L));
+
+ assertEquals(5L, service.savePrescriptionCovid(BEN_REG_ID, 3L, 9, "nurse1", "X-Ray", VISIT_CODE, 7, 8,
+ "after food", "Covid positive"));
+
+ ArgumentCaptor captor = ArgumentCaptor.forClass(PrescriptionDetail.class);
+ verify(prescriptionDetailRepo).save(captor.capture());
+ assertEquals("Covid positive", captor.getValue().getDiagnosisProvided());
+ }
+
+ @Test
+ @DisplayName("savePrescriptionCovid should omit an absent instruction and diagnosis")
+ void savePrescriptionCovid_shouldOmitAbsentOptionalFields() {
+ when(prescriptionDetailRepo.save(any(PrescriptionDetail.class))).thenReturn(stored(5L));
+
+ assertEquals(5L, service.savePrescriptionCovid(BEN_REG_ID, 3L, 9, "nurse1", "X-Ray", VISIT_CODE, 7, 8,
+ null, null));
+ }
+
+ @Test
+ @DisplayName("saveBeneficiaryPrescription should map the case sheet onto a prescription and store it")
+ void saveBeneficiaryPrescription_shouldMapCaseSheetAndStore() throws Exception {
+ when(prescriptionDetailRepo.save(any(PrescriptionDetail.class))).thenReturn(stored(5L));
+
+ com.google.gson.JsonObject caseSheet = new com.google.gson.JsonObject();
+ caseSheet.addProperty("beneficiaryRegID", BEN_REG_ID);
+
+ assertEquals(5L, service.saveBeneficiaryPrescription(caseSheet));
+ }
+
+ @Test
+ @DisplayName("saveBenPrescription should join several provisional diagnoses into one field")
+ void saveBenPrescription_shouldJoinSeveralDiagnoses() {
+ PrescriptionDetail prescription = new PrescriptionDetail();
+ prescription.setProvisionalDiagnosisList(new ArrayList<>(
+ Arrays.asList(diagnosis("Fever", "1"), diagnosis("Cough", null), diagnosis(null, "3"))));
+ when(prescriptionDetailRepo.save(prescription)).thenReturn(stored(5L));
+
+ assertEquals(5L, service.saveBenPrescription(prescription));
+ assertEquals("Fever || Cough", prescription.getDiagnosisProvided());
+ assertEquals("1 || N/A", prescription.getDiagnosisProvided_SCTCode());
+ }
+
+ @Test
+ @DisplayName("saveBenPrescription should record N/A when the first diagnosis carries no concept id")
+ void saveBenPrescription_shouldRecordNotAvailableForMissingConceptId() {
+ PrescriptionDetail prescription = new PrescriptionDetail();
+ prescription.setProvisionalDiagnosisList(
+ new ArrayList<>(Collections.singletonList(diagnosis("Fever", null))));
+ when(prescriptionDetailRepo.save(prescription)).thenReturn(stored(5L));
+
+ assertEquals(5L, service.saveBenPrescription(prescription));
+ assertEquals("N/A", prescription.getDiagnosisProvided_SCTCode());
+ }
+
+ @Test
+ @DisplayName("saveBenPrescription should return null when the stored prescription carries no id")
+ void saveBenPrescription_shouldReturnNullWithoutStoredId() {
+ PrescriptionDetail prescription = new PrescriptionDetail();
+ when(prescriptionDetailRepo.save(prescription)).thenReturn(stored(0L));
+
+ assertNull(service.saveBenPrescription(prescription));
+ }
+
+ @Test
+ @DisplayName("updatePrescription should mark an already processed prescription as updated")
+ void updatePrescription_shouldMarkProcessedPrescriptionAsUpdated() {
+ PrescriptionDetail prescription = new PrescriptionDetail();
+ prescription.setBeneficiaryRegID(BEN_REG_ID);
+ prescription.setVisitCode(VISIT_CODE);
+ prescription.setPrescriptionID(5L);
+ prescription.setProvisionalDiagnosisList(new ArrayList<>(
+ Arrays.asList(diagnosis("Fever", "1"), diagnosis("Cough", null))));
+ PrescriptionDetail existing = stored(5L);
+ existing.setProcessed("P");
+ existing.setInstruction("after food");
+ when(prescriptionDetailRepo.getGeneralOPDDiagnosisStatus(BEN_REG_ID, VISIT_CODE, 5L)).thenReturn(existing);
+ when(prescriptionDetailRepo.save(prescription)).thenReturn(stored(5L));
+
+ assertEquals(1, service.updatePrescription(prescription));
+ assertEquals("U", prescription.getProcessed());
+ assertEquals("after food", prescription.getInstruction());
+ assertEquals("Fever || Cough", prescription.getDiagnosisProvided());
+ }
+
+ @Test
+ @DisplayName("updatePrescription should keep a fresh prescription marked as new")
+ void updatePrescription_shouldKeepFreshPrescriptionAsNew() {
+ PrescriptionDetail prescription = new PrescriptionDetail();
+ prescription.setBeneficiaryRegID(BEN_REG_ID);
+ prescription.setVisitCode(VISIT_CODE);
+ prescription.setPrescriptionID(5L);
+ PrescriptionDetail existing = stored(5L);
+ existing.setProcessed("N");
+ existing.setDiagnosisProvided("Fever");
+ when(prescriptionDetailRepo.getGeneralOPDDiagnosisStatus(BEN_REG_ID, VISIT_CODE, 5L)).thenReturn(existing);
+ when(prescriptionDetailRepo.save(prescription)).thenReturn(stored(5L));
+
+ assertEquals(1, service.updatePrescription(prescription));
+ assertEquals("N", prescription.getProcessed());
+ assertEquals("Fever", prescription.getDiagnosisProvided());
+ }
+
+ @Test
+ @DisplayName("updatePrescription should treat an unknown prescription as new")
+ void updatePrescription_shouldTreatUnknownPrescriptionAsNew() {
+ PrescriptionDetail prescription = new PrescriptionDetail();
+ prescription.setBeneficiaryRegID(BEN_REG_ID);
+ prescription.setVisitCode(VISIT_CODE);
+ prescription.setPrescriptionID(5L);
+ when(prescriptionDetailRepo.getGeneralOPDDiagnosisStatus(BEN_REG_ID, VISIT_CODE, 5L)).thenReturn(null);
+ when(prescriptionDetailRepo.save(prescription)).thenReturn(stored(0L));
+
+ assertEquals(0, service.updatePrescription(prescription));
+ assertEquals("N", prescription.getProcessed());
+ }
+
+ @Test
+ @DisplayName("saveBeneficiaryLabTestOrderDetails should succeed when the case sheet orders no test")
+ void saveBeneficiaryLabTestOrderDetails_shouldSucceedWithoutOrders() {
+ assertEquals(1L, service.saveBeneficiaryLabTestOrderDetails(new com.google.gson.JsonObject(), 5L));
+ }
+
+ @Test
+ @DisplayName("saveBenPrescribedDrugsList should succeed for an empty drug list")
+ void saveBenPrescribedDrugsList_shouldSucceedForEmptyList() {
+ assertEquals(1, service.saveBenPrescribedDrugsList(new ArrayList<>()));
+ }
+
+ @Test
+ @DisplayName("saveBenPrescribedDrugsList should store a drug that needs no quantity calculation")
+ void saveBenPrescribedDrugsList_shouldStoreDrugWithoutQuantityCalculation() {
+ PrescribedDrugDetail drug = new PrescribedDrugDetail();
+ drug.setFormName("Syrup");
+ List drugs = new ArrayList<>(Collections.singletonList(drug));
+ when(prescribedDrugDetailRepo.saveAll(drugs)).thenReturn(drugs);
+
+ assertEquals(1, service.saveBenPrescribedDrugsList(drugs));
+ assertNull(drug.getQtyPrescribed());
+ }
+
+ @Test
+ @DisplayName("saveBenPrescribedDrugsList should report a failure when not every drug was stored")
+ void saveBenPrescribedDrugsList_shouldReportPartialSaveAsFailure() {
+ PrescribedDrugDetail drug = new PrescribedDrugDetail();
+ drug.setFormName("Syrup");
+ List drugs = new ArrayList<>(Collections.singletonList(drug));
+ when(prescribedDrugDetailRepo.saveAll(drugs)).thenReturn(new ArrayList<>());
+
+ assertEquals(0, service.saveBenPrescribedDrugsList(drugs));
+ }
+
+ @org.junit.jupiter.params.ParameterizedTest(name = "{0} {1} {2} for {3} {4} should be {5} units")
+ @org.junit.jupiter.params.provider.CsvSource({
+ "Tablet, Half Tab, Once Daily(OD), 10, Day(s), 5",
+ "Tablet, One Tab, Once Daily(OD) Before Food, 10, Day(s), 10",
+ "Tablet, One & Half Tab, Once Daily(OD) After Food, 2, Week(s), 21",
+ "Tablet, Two Tabs, Once Daily(OD) At Bedtime, 1, Month(s), 60",
+ "Capsule, One Tab, Once Daily(OD), 10, Day(s), 10",
+ "Tablet, Half Tab, Twice Daily(BD), 10, Day(s), 10",
+ "Tablet, One Tab, Twice Daily(BD) Before Food, 10, Day(s), 20",
+ "Tablet, One & Half Tab, Twice Daily(BD) After Food, 10, Day(s), 30",
+ "Tablet, Two Tabs, Twice Daily(BD), 10, Day(s), 40",
+ "Capsule, One Tab, Twice Daily(BD), 10, Day(s), 20",
+ "Tablet, Half Tab, Thrice Daily (TID), 10, Day(s), 15",
+ "Tablet, One Tab, Thrice Daily (TID) After Food, 10, Day(s), 30",
+ "Tablet, One & Half Tab, Thrice Daily (TID) Before Food, 10, Day(s), 45",
+ "Tablet, Two Tabs, Thrice Daily (TID), 10, Day(s), 60",
+ "Tablet, Half Tab, Four Times in a Day (QID), 10, Day(s), 20",
+ "Tablet, One Tab, Four Times in a Day AF, 10, Day(s), 40",
+ "Tablet, One & Half Tab, Four Times in a Day BF, 10, Day(s), 60",
+ "Tablet, Two Tabs, Four Times in a Day (QID), 10, Day(s), 80",
+ "Tablet, Half Tab, Single Dose, 10, Day(s), 1",
+ "Tablet, One Tab, Stat Dose, 10, Day(s), 1",
+ "Tablet, Two Tabs, Single Dose After Food, 10, Day(s), 2",
+ "Tablet, One Tab, Once in a Week, 4, Week(s), 4",
+ "Tablet, Half Tab, SOS, 10, Day(s), 5",
+ "Tablet, One Tab, SOS, 10, Day(s), 10" })
+ @DisplayName("saveBenPrescribedDrugsList should derive the dispensed quantity from the dosage")
+ void saveBenPrescribedDrugsList_shouldDeriveDispensedQuantity(String form, String dose, String frequency,
+ String duration, String unit, int expectedQuantity) {
+ PrescribedDrugDetail drug = new PrescribedDrugDetail();
+ drug.setFormName(form);
+ drug.setDose(dose);
+ drug.setFrequency(frequency);
+ drug.setDuration(duration);
+ drug.setUnit(unit);
+ List drugs = new ArrayList<>(Collections.singletonList(drug));
+ when(prescribedDrugDetailRepo.saveAll(drugs)).thenReturn(drugs);
+
+ service.saveBenPrescribedDrugsList(drugs);
+
+ assertEquals(expectedQuantity, drug.getQtyPrescribed());
+ }
+
+ @Test
+ @DisplayName("saveBenPrescribedDrugsList should leave the quantity at zero when the dosage is incomplete")
+ void saveBenPrescribedDrugsList_shouldLeaveQuantityAtZeroForIncompleteDosage() {
+ PrescribedDrugDetail drug = new PrescribedDrugDetail();
+ drug.setFormName("Tablet");
+ List drugs = new ArrayList<>(Collections.singletonList(drug));
+ when(prescribedDrugDetailRepo.saveAll(drugs)).thenReturn(drugs);
+
+ service.saveBenPrescribedDrugsList(drugs);
+
+ assertEquals(0, drug.getQtyPrescribed());
+ }
+ }
+
+ @Nested
+ @DisplayName("investigations, worklists and child histories")
+ class WorklistAndChildHistoryTests {
+
+ private ArrayList oneEmptyRow() {
+ ArrayList rows = new ArrayList<>();
+ rows.add(new Object[60]);
+ return rows;
+ }
+
+ @Test
+ @DisplayName("saveBenInvestigationDetails should create the prescription then store the ordered tests")
+ void saveBenInvestigationDetails_shouldCreatePrescriptionThenStoreTests() {
+ WrapperBenInvestigationANC wrapper = new WrapperBenInvestigationANC();
+ wrapper.setBeneficiaryRegID(BEN_REG_ID);
+ wrapper.setVisitCode(VISIT_CODE);
+ PrescriptionDetail stored = new PrescriptionDetail();
+ stored.setPrescriptionID(5L);
+ when(prescriptionDetailRepo.save(any(PrescriptionDetail.class))).thenReturn(stored);
+
+ assertEquals(1, service.saveBenInvestigationDetails(wrapper));
+ assertEquals(5L, wrapper.getPrescriptionID());
+ }
+
+ @Test
+ @DisplayName("saveBenInvestigationDetails should report no change for a null payload")
+ void saveBenInvestigationDetails_shouldReportNoChangeForNullPayload() {
+ assertEquals(0, service.saveBenInvestigationDetails(null));
+ }
+
+ @Test
+ @DisplayName("saveBenInvestigation should stamp the visit details onto every ordered test")
+ void saveBenInvestigation_shouldStampVisitDetailsOntoTests() {
+ WrapperBenInvestigationANC wrapper = new WrapperBenInvestigationANC();
+ wrapper.setBeneficiaryRegID(BEN_REG_ID);
+ wrapper.setVisitCode(VISIT_CODE);
+ wrapper.setPrescriptionID(5L);
+ com.iemr.tm.data.quickConsultation.LabTestOrderDetail test =
+ new com.iemr.tm.data.quickConsultation.LabTestOrderDetail();
+ wrapper.setLaboratoryList(new ArrayList<>(Collections.singletonList(test)));
+ when(labTestOrderDetailRepo.saveAll(any())).thenAnswer(echoList());
+
+ assertEquals(1L, service.saveBenInvestigation(wrapper));
+ assertEquals(5L, test.getPrescriptionID());
+ assertEquals(BEN_REG_ID, test.getBeneficiaryRegID());
+ }
+
+ @Test
+ @DisplayName("saveBenInvestigation should succeed when no test was ordered")
+ void saveBenInvestigation_shouldSucceedWithoutOrderedTests() {
+ WrapperBenInvestigationANC wrapper = new WrapperBenInvestigationANC();
+
+ assertEquals(1L, service.saveBenInvestigation(wrapper));
+ }
+
+ @Test
+ @DisplayName("updateBenVisitStatusFlag should confirm the flag change")
+ void updateBenVisitStatusFlag_shouldConfirmFlagChange() {
+ when(benVisitDetailRepo.updateBenFlowStatus("C", 3L)).thenReturn(1);
+
+ assertTrue(service.updateBenVisitStatusFlag(3L, "C").contains("Updated Successfully"));
+ }
+
+ @Test
+ @DisplayName("updateBenStatus should leave the response empty when no row was changed")
+ void updateBenStatus_shouldLeaveResponseEmptyWhenNothingChanged() {
+ when(benVisitDetailRepo.updateBenFlowStatus("C", 3L)).thenReturn(0);
+
+ assertEquals("{}", service.updateBenStatus(3L, "C"));
+ }
+
+ @Test
+ @DisplayName("getNurseWorkList should render the registrar worklist")
+ void getNurseWorkList_shouldRenderRegistrarWorklist() {
+ when(reistrarRepoBenSearch.getNurseWorkList()).thenReturn(new ArrayList<>());
+
+ assertNotNull(service.getNurseWorkList());
+ }
+
+ @Test
+ @DisplayName("getNurseWorkListNew should render the worklist for the configured lookback window")
+ void getNurseWorkListNew_shouldRenderWorklistForConfiguredWindow() {
+ org.springframework.test.util.ReflectionTestUtils.setField(service, "nurseWL", 10);
+ when(beneficiaryFlowStatusRepo.getNurseWorklistNew(eq(9), eq(7), any(java.sql.Timestamp.class)))
+ .thenReturn(new ArrayList<>());
+
+ assertEquals("[]", service.getNurseWorkListNew(9, 7));
+ }
+
+ @Test
+ @DisplayName("getNurseWorkListNew should fall back to a seven day window when the setting is out of range")
+ void getNurseWorkListNew_shouldFallBackToSevenDayWindow() {
+ org.springframework.test.util.ReflectionTestUtils.setField(service, "nurseWL", 90);
+ when(beneficiaryFlowStatusRepo.getNurseWorklistNew(eq(9), eq(7), any(java.sql.Timestamp.class)))
+ .thenReturn(new ArrayList<>());
+
+ assertEquals("[]", service.getNurseWorkListNew(9, 7));
+ }
+
+ @Test
+ @DisplayName("getNurseWorkListTcCurrentDate should render the same day teleconsultation worklist")
+ void getNurseWorkListTcCurrentDate_shouldRenderWorklist() {
+ org.springframework.test.util.ReflectionTestUtils.setField(service, "nurseTCWL", 5);
+ when(beneficiaryFlowStatusRepo.getNurseWorklistCurrentDate(eq(9), any(java.sql.Timestamp.class), eq(7)))
+ .thenReturn(new ArrayList<>());
+
+ assertEquals("[]", service.getNurseWorkListTcCurrentDate(9, 7));
+ }
+
+ @Test
+ @DisplayName("getNurseWorkListTcCurrentDate should fall back to a seven day window when unset")
+ void getNurseWorkListTcCurrentDate_shouldFallBackToSevenDayWindow() {
+ when(beneficiaryFlowStatusRepo.getNurseWorklistCurrentDate(eq(9), any(java.sql.Timestamp.class), eq(7)))
+ .thenReturn(new ArrayList<>());
+
+ assertEquals("[]", service.getNurseWorkListTcCurrentDate(9, 7));
+ }
+
+ @Test
+ @DisplayName("getNurseWorkListTcFutureDate should render the future teleconsultation worklist")
+ void getNurseWorkListTcFutureDate_shouldRenderWorklist() {
+ when(beneficiaryFlowStatusRepo.getNurseWorklistFutureDate(9, 7)).thenReturn(new ArrayList<>());
+
+ assertEquals("[]", service.getNurseWorkListTcFutureDate(9, 7));
+ }
+
+ @Test
+ @DisplayName("getLabWorkListNew should render the laboratory worklist")
+ void getLabWorkListNew_shouldRenderWorklist() {
+ org.springframework.test.util.ReflectionTestUtils.setField(service, "labWL", 5);
+ when(beneficiaryFlowStatusRepo.getLabWorklistNew(eq(9), any(java.sql.Timestamp.class), eq(7)))
+ .thenReturn(new ArrayList<>());
+
+ assertEquals("[]", service.getLabWorkListNew(9, 7));
+ }
+
+ @Test
+ @DisplayName("getLabWorkListNew should fall back to a seven day window when unset")
+ void getLabWorkListNew_shouldFallBackToSevenDayWindow() {
+ when(beneficiaryFlowStatusRepo.getLabWorklistNew(eq(9), any(java.sql.Timestamp.class), eq(7)))
+ .thenReturn(new ArrayList<>());
+
+ assertEquals("[]", service.getLabWorkListNew(9, 7));
+ }
+
+ @Test
+ @DisplayName("getRadiologistWorkListNew should render the radiology worklist")
+ void getRadiologistWorkListNew_shouldRenderWorklist() {
+ org.springframework.test.util.ReflectionTestUtils.setField(service, "radioWL", 5);
+ when(beneficiaryFlowStatusRepo.getRadiologistWorkListNew(eq(9), any(java.sql.Timestamp.class), eq(7)))
+ .thenReturn(new ArrayList<>());
+
+ assertEquals("[]", service.getRadiologistWorkListNew(9, 7));
+ }
+
+ @Test
+ @DisplayName("getRadiologistWorkListNew should fall back to a seven day window when unset")
+ void getRadiologistWorkListNew_shouldFallBackToSevenDayWindow() {
+ when(beneficiaryFlowStatusRepo.getRadiologistWorkListNew(eq(9), any(java.sql.Timestamp.class), eq(7)))
+ .thenReturn(new ArrayList<>());
+
+ assertEquals("[]", service.getRadiologistWorkListNew(9, 7));
+ }
+
+ @Test
+ @DisplayName("getOncologistWorkListNew should render the oncology worklist")
+ void getOncologistWorkListNew_shouldRenderWorklist() {
+ org.springframework.test.util.ReflectionTestUtils.setField(service, "oncoWL", 5);
+ when(beneficiaryFlowStatusRepo.getOncologistWorkListNew(eq(9), any(java.sql.Timestamp.class), eq(7)))
+ .thenReturn(new ArrayList<>());
+
+ assertEquals("[]", service.getOncologistWorkListNew(9, 7));
+ }
+
+ @Test
+ @DisplayName("getOncologistWorkListNew should fall back to a seven day window when unset")
+ void getOncologistWorkListNew_shouldFallBackToSevenDayWindow() {
+ when(beneficiaryFlowStatusRepo.getOncologistWorkListNew(eq(9), any(java.sql.Timestamp.class), eq(7)))
+ .thenReturn(new ArrayList<>());
+
+ assertEquals("[]", service.getOncologistWorkListNew(9, 7));
+ }
+
+ @Test
+ @DisplayName("getPharmaWorkListNew should render the pharmacy worklist")
+ void getPharmaWorkListNew_shouldRenderWorklist() {
+ org.springframework.test.util.ReflectionTestUtils.setField(service, "pharmaWL", 5);
+ when(beneficiaryFlowStatusRepo.getPharmaWorkListNew(eq(9), any(java.sql.Timestamp.class), eq(7)))
+ .thenReturn(new ArrayList<>());
+
+ assertEquals("[]", service.getPharmaWorkListNew(9, 7));
+ }
+
+ @Test
+ @DisplayName("getPharmaWorkListNew should fall back to a seven day window when unset")
+ void getPharmaWorkListNew_shouldFallBackToSevenDayWindow() {
+ when(beneficiaryFlowStatusRepo.getPharmaWorkListNew(eq(9), any(java.sql.Timestamp.class), eq(7)))
+ .thenReturn(new ArrayList<>());
+
+ assertEquals("[]", service.getPharmaWorkListNew(9, 7));
+ }
+
+ @Test
+ @DisplayName("saveBenAdherenceDetails should confirm the stored adherence row")
+ void saveBenAdherenceDetails_shouldConfirmStoredRow() {
+ BenAdherence adherence = new BenAdherence();
+ when(benAdherenceRepo.save(adherence)).thenReturn(adherence);
+
+ assertEquals(1, service.saveBenAdherenceDetails(adherence));
+ }
+
+ @Test
+ @DisplayName("saveBenAdherenceDetails should report no change when nothing was stored")
+ void saveBenAdherenceDetails_shouldReportNoChangeWhenNothingStored() {
+ BenAdherence adherence = new BenAdherence();
+ when(benAdherenceRepo.save(adherence)).thenReturn(null);
+
+ assertEquals(0, service.saveBenAdherenceDetails(adherence));
+ }
+
+ @Test
+ @DisplayName("saveChildFeedingHistory should return the stored row id")
+ void saveChildFeedingHistory_shouldReturnStoredId() {
+ ChildFeedingDetails details = new ChildFeedingDetails();
+ ChildFeedingDetails saved = new ChildFeedingDetails();
+ saved.setID(4L);
+ when(childFeedingDetailsRepo.save(details)).thenReturn(saved);
+
+ assertEquals(4L, service.saveChildFeedingHistory(details));
+ }
+
+ @Test
+ @DisplayName("saveChildFeedingHistory should return null when nothing was stored")
+ void saveChildFeedingHistory_shouldReturnNullWhenNothingStored() {
+ ChildFeedingDetails details = new ChildFeedingDetails();
+ when(childFeedingDetailsRepo.save(details)).thenReturn(null);
+
+ assertNull(service.saveChildFeedingHistory(details));
+ }
+
+ @Test
+ @DisplayName("savePerinatalHistory should return the stored row id")
+ void savePerinatalHistory_shouldReturnStoredId() {
+ PerinatalHistory history = new PerinatalHistory();
+ PerinatalHistory saved = new PerinatalHistory();
+ saved.setID(4L);
+ when(perinatalHistoryRepo.save(history)).thenReturn(saved);
+
+ assertEquals(4L, service.savePerinatalHistory(history));
+ }
+
+ @Test
+ @DisplayName("savePerinatalHistory should return null when nothing was stored")
+ void savePerinatalHistory_shouldReturnNullWhenNothingStored() {
+ PerinatalHistory history = new PerinatalHistory();
+ when(perinatalHistoryRepo.save(history)).thenReturn(null);
+
+ assertNull(service.savePerinatalHistory(history));
+ }
+
+ @Test
+ @DisplayName("getBenAdherence should render the stored adherence for the visit")
+ void getBenAdherence_shouldRenderStoredAdherence() {
+ when(benAdherenceRepo.getBenAdherence(BEN_REG_ID, VISIT_CODE)).thenReturn(oneEmptyRow());
+
+ assertNotNull(service.getBenAdherence(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getLabTestOrders should render the stored lab test orders for the visit")
+ void getLabTestOrders_shouldRenderStoredOrders() {
+ when(labTestOrderDetailRepo.getLabTestOrderDetails(BEN_REG_ID, VISIT_CODE)).thenReturn(new ArrayList<>());
+
+ assertNotNull(service.getLabTestOrders(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getPerinatalHistory should return the stored perinatal history for the visit")
+ void getPerinatalHistory_shouldReturnStoredHistory() {
+ when(perinatalHistoryRepo.getBenPerinatalDetails(BEN_REG_ID, VISIT_CODE)).thenReturn(new ArrayList<>());
+
+ assertNull(service.getPerinatalHistory(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getFeedingHistory should return the stored feeding history for the visit")
+ void getFeedingHistory_shouldReturnStoredHistory() {
+ when(childFeedingDetailsRepo.getBenFeedingDetails(BEN_REG_ID, VISIT_CODE)).thenReturn(new ArrayList<>());
+
+ assertNull(service.getFeedingHistory(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("fetchBenPerinatalHistory should render the stored rows with the report columns")
+ void fetchBenPerinatalHistory_shouldRenderRowsWithColumns() {
+ when(perinatalHistoryRepo.getBenPerinatalDetail(BEN_REG_ID)).thenReturn(oneEmptyRow());
+
+ assertTrue(service.fetchBenPerinatalHistory(BEN_REG_ID).contains("\"columns\""));
+ }
+
+ @Test
+ @DisplayName("fetchBenPerinatalHistory should render only the columns when nothing is stored")
+ void fetchBenPerinatalHistory_shouldRenderColumnsOnlyWhenEmpty() {
+ when(perinatalHistoryRepo.getBenPerinatalDetail(BEN_REG_ID)).thenReturn(null);
+
+ assertTrue(service.fetchBenPerinatalHistory(BEN_REG_ID).contains("\"columns\""));
+ }
+
+ @Test
+ @DisplayName("fetchBenFeedingHistory should render the stored rows with the report columns")
+ void fetchBenFeedingHistory_shouldRenderRowsWithColumns() {
+ when(childFeedingDetailsRepo.getBenFeedingHistoryDetail(BEN_REG_ID)).thenReturn(oneEmptyRow());
+
+ assertTrue(service.fetchBenFeedingHistory(BEN_REG_ID).contains("\"columns\""));
+ }
+
+ @Test
+ @DisplayName("fetchBenFeedingHistory should render only the columns when nothing is stored")
+ void fetchBenFeedingHistory_shouldRenderColumnsOnlyWhenEmpty() {
+ when(childFeedingDetailsRepo.getBenFeedingHistoryDetail(BEN_REG_ID)).thenReturn(null);
+
+ assertTrue(service.fetchBenFeedingHistory(BEN_REG_ID).contains("\"columns\""));
+ }
+
+ @Test
+ @DisplayName("updateChildFeedingHistory should report no change for a null payload")
+ void updateChildFeedingHistory_shouldReportNoChangeForNullPayload() {
+ assertEquals(0, service.updateChildFeedingHistory(null));
+ }
+
+ @Test
+ @DisplayName("updatePerinatalHistory should report no change for a null payload")
+ void updatePerinatalHistory_shouldReportNoChangeForNullPayload() {
+ assertEquals(0, service.updatePerinatalHistory(null));
+ }
+
+ @Test
+ @DisplayName("updateChildDevelopmentHistory should report no change for a null payload")
+ void updateChildDevelopmentHistory_shouldReportNoChangeForNullPayload() {
+ assertEquals(0, service.updateChildDevelopmentHistory(null));
+ }
+ }
+
+ @Nested
+ @DisplayName("trends, screening summaries and BMI status")
+ class TrendAndSummaryTests {
+
+ private ArrayList visitRows(String visitCategory) {
+ ArrayList rows = new ArrayList<>();
+ rows.add(new Object[] { 1L, visitCategory, 22L });
+ return rows;
+ }
+
+ @Test
+ @DisplayName("getGraphicalTrendData should return the weight, blood pressure and blood glucose series")
+ void getGraphicalTrendData_shouldReturnAllSeries() {
+ when(benVisitDetailRepo.getLastSixVisitDetailsForBeneficiary(BEN_REG_ID))
+ .thenReturn(visitRows("General OPD"));
+ when(benAnthropometryRepo.getBenAnthropometryDetailForGraphtrends(any())).thenReturn(new ArrayList<>());
+ when(benPhysicalVitalRepo.getBenPhysicalVitalDetailForGraphTrends(any())).thenReturn(new ArrayList<>());
+
+ Map result = service.getGraphicalTrendData(BEN_REG_ID, "General OPD");
+
+ assertTrue(result.containsKey("weightList"));
+ assertTrue(result.containsKey("bpList"));
+ assertTrue(result.containsKey("bgList"));
+ }
+
+ @Test
+ @DisplayName("getGraphicalTrendData should read the cancer vitals for a cancer screening visit")
+ void getGraphicalTrendData_shouldReadCancerVitals() {
+ when(benVisitDetailRepo.getLastSixVisitDetailsForBeneficiary(BEN_REG_ID))
+ .thenReturn(visitRows("Cancer Screening"));
+ when(benCancerVitalDetailRepo.getBenCancerVitalDetailForGraph(any())).thenReturn(new ArrayList<>());
+
+ assertNotNull(service.getGraphicalTrendData(BEN_REG_ID, "Cancer Screening"));
+ verify(benCancerVitalDetailRepo).getBenCancerVitalDetailForGraph(any());
+ }
+
+ @Test
+ @DisplayName("getGraphicalTrendData should return empty series when the beneficiary has no earlier visit")
+ void getGraphicalTrendData_shouldReturnEmptySeriesWithoutVisits() {
+ when(benVisitDetailRepo.getLastSixVisitDetailsForBeneficiary(BEN_REG_ID)).thenReturn(new ArrayList<>());
+
+ assertNotNull(service.getGraphicalTrendData(BEN_REG_ID, "General OPD"));
+ }
+
+ @Test
+ @DisplayName("updateBenFamilyHistoryNCDScreening should confirm the update when entries were stored")
+ void updateBenFamilyHistoryNCDScreening_shouldConfirmUpdate() {
+ BenFamilyHistory history = new BenFamilyHistory();
+ List> diseases = new ArrayList<>();
+ Map disease = new HashMap<>();
+ disease.put("diseaseType", "Diabetes");
+ disease.put("deleted", "false");
+ diseases.add(disease);
+ history.setFamilyDiseaseList(diseases);
+ when(benFamilyHistoryRepo.saveAll(any())).thenAnswer(echoList());
+
+ assertEquals(1, service.updateBenFamilyHistoryNCDScreening(history));
+ }
+
+ @Test
+ @DisplayName("updateBenFamilyHistoryNCDScreening should report no change for an empty history")
+ void updateBenFamilyHistoryNCDScreening_shouldReportNoChangeForEmptyHistory() {
+ BenFamilyHistory history = new BenFamilyHistory();
+ history.setFamilyDiseaseList(new ArrayList<>());
+
+ assertEquals(0, service.updateBenFamilyHistoryNCDScreening(history));
+ }
+
+ @Test
+ @DisplayName("updateBenPhysicalActivityHistoryNCDScreening should mark an existing row as updated")
+ void updatePhysicalActivityNCDScreening_shouldMarkExistingRowAsUpdated() {
+ PhysicalActivityType activity = new PhysicalActivityType();
+ activity.setID(3L);
+ when(physicalActivityTypeRepo.save(activity)).thenReturn(activity);
+
+ assertEquals(1, service.updateBenPhysicalActivityHistoryNCDScreening(activity));
+ assertEquals("U", activity.getProcessed());
+ assertEquals(Boolean.FALSE, activity.getDeleted());
+ }
+
+ @Test
+ @DisplayName("updateBenPhysicalActivityHistoryNCDScreening should mark a new row as new")
+ void updatePhysicalActivityNCDScreening_shouldMarkNewRowAsNew() {
+ PhysicalActivityType activity = new PhysicalActivityType();
+ when(physicalActivityTypeRepo.save(activity)).thenReturn(null);
+
+ assertEquals(0, service.updateBenPhysicalActivityHistoryNCDScreening(activity));
+ assertEquals("N", activity.getProcessed());
+ }
+
+ @Test
+ @DisplayName("getBenSymptomaticData should summarise the confirmed and suspected diseases")
+ void getBenSymptomaticData_shouldSummariseDiseases() throws Exception {
+ when(iDRSDataRepo.getBenIdrsDetailsLast_3_Month(eq(BEN_REG_ID), any(java.sql.Timestamp.class)))
+ .thenReturn(new ArrayList<>());
+ when(iDRSDataRepo.isDiabeticCheck(BEN_REG_ID)).thenReturn(1);
+ when(iDRSDataRepo.isEpilepsyCheck(BEN_REG_ID)).thenReturn(1);
+ when(iDRSDataRepo.isDefectiveVisionCheck(BEN_REG_ID)).thenReturn(1);
+ when(iDRSDataRepo.isHypertensionCheck(BEN_REG_ID)).thenReturn(1);
+
+ assertNotNull(service.getBenSymptomaticData(BEN_REG_ID));
+ }
+
+ @Test
+ @DisplayName("getBenSymptomaticData should summarise nothing when no screening was recorded")
+ void getBenSymptomaticData_shouldSummariseNothingWithoutScreening() throws Exception {
+ when(iDRSDataRepo.getBenIdrsDetailsLast_3_Month(eq(BEN_REG_ID), any(java.sql.Timestamp.class)))
+ .thenReturn(new ArrayList<>());
+
+ assertNotNull(service.getBenSymptomaticData(BEN_REG_ID));
+ }
+
+ @Test
+ @DisplayName("getBenPreviousDiabetesData should render the earlier diabetes screening")
+ void getBenPreviousDiabetesData_shouldRenderEarlierScreening() throws Exception {
+ when(iDRSDataRepo.getBenPreviousDiabetesDetails(BEN_REG_ID)).thenReturn(new ArrayList<>());
+
+ assertNotNull(service.getBenPreviousDiabetesData(BEN_REG_ID));
+ }
+
+ @Test
+ @DisplayName("getBenPreviousReferralData should render the earlier referrals")
+ void getBenPreviousReferralData_shouldRenderEarlierReferrals() throws Exception {
+ assertNotNull(service.getBenPreviousReferralData(BEN_REG_ID));
+ }
+
+ @Test
+ @DisplayName("getMmuNurseWorkListNew should render the MMU referred worklist")
+ void getMmuNurseWorkListNew_shouldRenderWorklist() {
+ org.springframework.test.util.ReflectionTestUtils.setField(service, "TMReferredWL", 7);
+ when(beneficiaryFlowStatusRepo.getMmuNurseWorklistNew(eq(9), eq(7), any(java.sql.Timestamp.class)))
+ .thenReturn(new ArrayList<>());
+
+ assertEquals("[]", service.getMmuNurseWorkListNew(9, 7));
+ }
+
+ @Test
+ @DisplayName("fetchProviderSpecificdata should render the referral data for a referral request")
+ void fetchProviderSpecificdata_shouldRenderReferralData() throws Exception {
+ when(benReferDetailsRepo.getBenReferDetails(anyLong(), any())).thenReturn(new ArrayList<>());
+
+ String result = service.fetchProviderSpecificdata(
+ "{\"benRegID\":11,\"visitCode\":22,\"fetchMMUDataFor\":\"referral\"}");
+
+ assertNotNull(result);
+ }
+
+ @Test
+ @DisplayName("fetchProviderSpecificdata should render the prescription data for a prescription request")
+ void fetchProviderSpecificdata_shouldRenderPrescriptionData() throws Exception {
+ when(prescribedDrugDetailRepo.getBenPrescribedDrugDetails(anyLong(), any())).thenReturn(new ArrayList<>());
+
+ assertNotNull(service.fetchProviderSpecificdata(
+ "{\"benRegID\":11,\"visitCode\":22,\"fetchMMUDataFor\":\"prescription\"}"));
+ }
+
+ @Test
+ @DisplayName("fetchProviderSpecificdata should reject an unknown data category")
+ void fetchProviderSpecificdata_shouldRejectUnknownCategory() throws Exception {
+ assertEquals("Invalid master param to fetch data", service.fetchProviderSpecificdata(
+ "{\"benRegID\":11,\"visitCode\":22,\"fetchMMUDataFor\":\"unknown\"}"));
+ }
+
+ @Test
+ @DisplayName("fetchProviderSpecificdata should fail for a request without a data category")
+ void fetchProviderSpecificdata_shouldFailWithoutCategory() {
+ assertThrows(IEMRException.class,
+ () -> service.fetchProviderSpecificdata("{\"benRegID\":11,\"visitCode\":22}"));
+ }
+
+ @org.junit.jupiter.params.ParameterizedTest(name = "a BMI of {0} should read as {1}")
+ @org.junit.jupiter.params.provider.CsvSource({ "16.0, Normal", "14.5, Mild malnourished",
+ "12.5, Moderately Malnourished", "11.0, Severely Malnourished", "18.5, Overweight", "20.5, Obese",
+ "23.0, Severely Obese" })
+ @DisplayName("calculateBMIStatus should classify the BMI against the age and gender reference")
+ void calculateBMIStatus_shouldClassifyAgainstReference(double bmi, String expectedStatus) throws Exception {
+ com.iemr.tm.data.bmi.BmiCalculation reference = new com.iemr.tm.data.bmi.BmiCalculation();
+ reference.setN3SD(12d);
+ reference.setN2SD(13d);
+ reference.setN1SD(15d);
+ reference.setP1SD(18d);
+ reference.setP2SD(20d);
+ reference.setP3SD(22d);
+ when(bmiCalculationRepo.getBMIDetails(30, "Male")).thenReturn(reference);
+
+ String result = service.calculateBMIStatus(
+ "{\"yearMonth\":\"2 years and 6 months\",\"gender\":\"Male\",\"bmi\":" + bmi + "}");
+
+ assertTrue(result.contains(expectedStatus));
+ }
+
+ @Test
+ @DisplayName("calculateBMIStatus should fail when no reference exists for the age and gender")
+ void calculateBMIStatus_shouldFailWithoutReference() {
+ when(bmiCalculationRepo.getBMIDetails(30, "Male")).thenReturn(null);
+
+ IEMRException thrown = assertThrows(IEMRException.class, () -> service.calculateBMIStatus(
+ "{\"yearMonth\":\"2 years and 6 months\",\"gender\":\"Male\",\"bmi\":16.0}"));
+
+ assertTrue(thrown.getMessage().contains("No data found for this category"));
+ }
+
+ @Test
+ @DisplayName("calculateBMIStatus should report an empty status for a request without a BMI")
+ void calculateBMIStatus_shouldReportEmptyStatusWithoutBmi() throws Exception {
+ assertTrue(service.calculateBMIStatus("{\"yearMonth\":\"2 years and 6 months\",\"gender\":\"Male\"}")
+ .contains("\"bmiStatus\":\"\""));
+ }
+ }
+
+ @Nested
+ @DisplayName("child history reports and graph series")
+ class ChildHistoryAndGraphTests {
+
+ private ArrayList oneEmptyRow() {
+ ArrayList rows = new ArrayList<>();
+ rows.add(new Object[40]);
+ return rows;
+ }
+
+ @Test
+ @DisplayName("fetchBenDevelopmentHistory should render the stored rows with the report columns")
+ void fetchDevelopmentHistory_shouldRenderRowsWithColumns() {
+ when(benChildDevelopmentHistoryRepo.getBenDevelopmentHistoryDetail(BEN_REG_ID))
+ .thenReturn(oneEmptyRow());
+
+ assertTrue(service.fetchBenDevelopmentHistory(BEN_REG_ID).contains("\"columns\""));
+ }
+
+ @Test
+ @DisplayName("fetchBenDevelopmentHistory should render only the columns when nothing is stored")
+ void fetchDevelopmentHistory_shouldRenderColumnsOnlyWhenEmpty() {
+ when(benChildDevelopmentHistoryRepo.getBenDevelopmentHistoryDetail(BEN_REG_ID)).thenReturn(null);
+
+ assertTrue(service.fetchBenDevelopmentHistory(BEN_REG_ID).contains("\"columns\""));
+ }
+
+ @Test
+ @DisplayName("updateChildDevelopmentHistory should update the stored development history")
+ void updateDevelopmentHistory_shouldUpdateStoredHistory() {
+ BenChildDevelopmentHistory history = new BenChildDevelopmentHistory();
+ history.setBeneficiaryRegID(BEN_REG_ID);
+ history.setVisitCode(VISIT_CODE);
+ when(benChildDevelopmentHistoryRepo.getDevelopmentHistoryStatus(BEN_REG_ID, VISIT_CODE)).thenReturn("P");
+
+ assertEquals(0, service.updateChildDevelopmentHistory(history));
+ }
+
+ @Test
+ @DisplayName("updateChildDevelopmentHistory should insert a new row when the visit has none")
+ void updateDevelopmentHistory_shouldInsertNewRow() {
+ BenChildDevelopmentHistory history = new BenChildDevelopmentHistory();
+ history.setBeneficiaryRegID(BEN_REG_ID);
+ history.setVisitCode(VISIT_CODE);
+ history.setModifiedBy("nurse1");
+ when(benChildDevelopmentHistoryRepo.getDevelopmentHistoryStatus(BEN_REG_ID, VISIT_CODE)).thenReturn(null);
+ BenChildDevelopmentHistory saved = new BenChildDevelopmentHistory();
+ saved.setID(4L);
+ when(benChildDevelopmentHistoryRepo.save(any())).thenReturn(saved);
+
+ assertEquals(1, service.updateChildDevelopmentHistory(history));
+ }
+
+ @Test
+ @DisplayName("updateChildFeedingHistory should update the stored feeding history")
+ void updateFeedingHistory_shouldUpdateStoredHistory() {
+ ChildFeedingDetails details = new ChildFeedingDetails();
+ details.setBeneficiaryRegID(BEN_REG_ID);
+ details.setVisitCode(VISIT_CODE);
+ when(childFeedingDetailsRepo.getBenChildFeedingDetailStatus(BEN_REG_ID, VISIT_CODE)).thenReturn("P");
+
+ assertEquals(0, service.updateChildFeedingHistory(details));
+ }
+
+ @Test
+ @DisplayName("updateChildFeedingHistory should insert a new row when the visit has none")
+ void updateFeedingHistory_shouldInsertNewRow() {
+ ChildFeedingDetails details = new ChildFeedingDetails();
+ details.setBeneficiaryRegID(BEN_REG_ID);
+ details.setVisitCode(VISIT_CODE);
+ details.setModifiedBy("nurse1");
+ when(childFeedingDetailsRepo.getBenChildFeedingDetailStatus(BEN_REG_ID, VISIT_CODE)).thenReturn(null);
+ ChildFeedingDetails saved = new ChildFeedingDetails();
+ saved.setID(4L);
+ when(childFeedingDetailsRepo.save(any())).thenReturn(saved);
+
+ assertEquals(1, service.updateChildFeedingHistory(details));
+ }
+
+ @Test
+ @DisplayName("updatePerinatalHistory should update the stored perinatal history")
+ void updatePerinatalHistory_shouldUpdateStoredHistory() {
+ PerinatalHistory history = new PerinatalHistory();
+ history.setBeneficiaryRegID(BEN_REG_ID);
+ history.setVisitCode(VISIT_CODE);
+ when(perinatalHistoryRepo.getPerinatalHistoryStatus(BEN_REG_ID, VISIT_CODE)).thenReturn("P");
+
+ assertEquals(0, service.updatePerinatalHistory(history));
+ }
+
+ @Test
+ @DisplayName("updatePerinatalHistory should insert a new row when the visit has none")
+ void updatePerinatalHistory_shouldInsertNewRow() {
+ PerinatalHistory history = new PerinatalHistory();
+ history.setBeneficiaryRegID(BEN_REG_ID);
+ history.setVisitCode(VISIT_CODE);
+ history.setModifiedBy("nurse1");
+ when(perinatalHistoryRepo.getPerinatalHistoryStatus(BEN_REG_ID, VISIT_CODE)).thenReturn(null);
+ PerinatalHistory saved = new PerinatalHistory();
+ saved.setID(4L);
+ when(perinatalHistoryRepo.save(any())).thenReturn(saved);
+
+ assertEquals(1, service.updatePerinatalHistory(history));
+ }
+
+ @Test
+ @DisplayName("getGraphicalTrendData should build the weight, blood pressure and blood glucose series")
+ void getGraphicalTrendData_shouldBuildEverySeries() {
+ ArrayList visits = new ArrayList<>();
+ visits.add(new Object[] { 1L, "General OPD", 22L });
+ when(benVisitDetailRepo.getLastSixVisitDetailsForBeneficiary(BEN_REG_ID)).thenReturn(visits);
+
+ ArrayList anthro = new ArrayList<>();
+ anthro.add(new Object[] { 60d, new java.sql.Timestamp(1_700_000_000_000L) });
+ when(benAnthropometryRepo.getBenAnthropometryDetailForGraphtrends(any())).thenReturn(anthro);
+
+ ArrayList vitals = new ArrayList<>();
+ vitals.add(new Object[] { (short) 120, (short) 80, 90d, 140d, 120d, new java.sql.Timestamp(
+ 1_700_000_000_000L) });
+ when(benPhysicalVitalRepo.getBenPhysicalVitalDetailForGraphTrends(any())).thenReturn(vitals);
+
+ Map result = service.getGraphicalTrendData(BEN_REG_ID, "General OPD");
+
+ assertNotNull(result.get("weightList"));
+ assertNotNull(result.get("bpList"));
+ assertNotNull(result.get("bgList"));
+ }
+
+ @Test
+ @DisplayName("getGraphicalTrendData should build the series from the cancer screening vitals")
+ void getGraphicalTrendData_shouldBuildSeriesFromCancerVitals() {
+ ArrayList visits = new ArrayList<>();
+ visits.add(new Object[] { 1L, "Cancer Screening", 22L });
+ when(benVisitDetailRepo.getLastSixVisitDetailsForBeneficiary(BEN_REG_ID)).thenReturn(visits);
+ com.iemr.tm.data.nurse.BenCancerVitalDetail cancerVital =
+ new com.iemr.tm.data.nurse.BenCancerVitalDetail();
+ cancerVital.setSystolicBP_1stReading((short) 120);
+ cancerVital.setDiastolicBP_1stReading((short) 80);
+ cancerVital.setWeight_Kg(60d);
+ cancerVital.setCreatedDate(new java.sql.Timestamp(1_700_000_000_000L));
+ when(benCancerVitalDetailRepo.getBenCancerVitalDetailForGraph(any()))
+ .thenReturn(new ArrayList<>(Collections.singletonList(cancerVital)));
+
+ assertNotNull(service.getGraphicalTrendData(BEN_REG_ID, "Cancer Screening"));
+ }
+ }
+
+ @Nested
+ @DisplayName("obstetric, menstrual and trend assembly")
+ class HistoryAssemblyTests {
+
+ /**
+ * One obstetric history row as the native query returns it: identifiers,
+ * the pregnancy count and the comma separated complication columns.
+ */
+ private Object[] obstetricRow() {
+ Object[] values = new Object[38];
+ values[0] = 11L;
+ values[1] = 3L;
+ values[2] = 9;
+ values[3] = (short) 1;
+ values[4] = (short) 2;
+ for (int i = 5; i < 38; i++) {
+ values[i] = "1,2";
+ }
+ values[8] = (short) 1;
+ values[10] = (short) 1;
+ values[12] = (short) 1;
+ values[18] = (short) 1;
+ values[23] = (short) 1;
+ values[27] = (short) 1;
+ values[30] = 5L;
+ values[31] = 3;
+ values[33] = 3;
+ values[34] = 3;
+ return values;
+ }
+
+ @Test
+ @DisplayName("getFemaleObstetricHistory should expand the complications of every pregnancy")
+ void getFemaleObstetricHistory_shouldExpandComplications() {
+ java.util.ArrayList rows = new java.util.ArrayList<>();
+ rows.add(obstetricRow());
+ when(femaleObstetricHistoryRepo.getBenFemaleObstetricHistoryDetail(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(rows);
+
+ com.iemr.tm.data.anc.WrapperFemaleObstetricHistory history =
+ service.getFemaleObstetricHistory(BEN_REG_ID, VISIT_CODE);
+
+ assertEquals(1, history.getFemaleObstetricHistoryList().size());
+ com.iemr.tm.data.anc.FemaleObstetricHistory pregnancy = history.getFemaleObstetricHistoryList().get(0);
+ assertNotNull(pregnancy.getPregComplicationList());
+ assertNotNull(pregnancy.getDeliveryComplicationList());
+ assertNotNull(pregnancy.getPostpartumComplicationList());
+ assertNotNull(pregnancy.getAbortionType());
+ assertNotNull(pregnancy.getTypeofFacility());
+ assertNotNull(pregnancy.getPostAbortionComplication());
+ }
+
+ @Test
+ @DisplayName("getFemaleObstetricHistory should answer for a beneficiary with no recorded pregnancy")
+ void getFemaleObstetricHistory_shouldAnswerWithoutRecordedPregnancy() {
+ when(femaleObstetricHistoryRepo.getBenFemaleObstetricHistoryDetail(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(new java.util.ArrayList<>());
+
+ assertNotNull(service.getFemaleObstetricHistory(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getMenstrualHistory should expand the recorded menstrual problems")
+ void getMenstrualHistory_shouldExpandRecordedProblems() {
+ java.util.ArrayList rows = new java.util.ArrayList<>();
+ rows.add(new Object[] { 11L, 3L, 9, (short) 1, "1,2", "1,2", (short) 5, "1,2", (short) 28,
+ "1,2", "1,2", "1,2", new java.sql.Timestamp(System.currentTimeMillis()), 22L });
+ when(benMenstrualDetailsRepo.getBenMenstrualDetail(BEN_REG_ID, VISIT_CODE)).thenReturn(rows);
+
+ com.iemr.tm.data.anc.BenMenstrualDetails details =
+ service.getMenstrualHistory(BEN_REG_ID, VISIT_CODE);
+
+ assertNotNull(details);
+ }
+
+ @Test
+ @DisplayName("getMenstrualHistory should answer for a beneficiary with no recorded menstrual history")
+ void getMenstrualHistory_shouldAnswerWithoutRecordedHistory() {
+ when(benMenstrualDetailsRepo.getBenMenstrualDetail(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertDoesNotThrow(
+ () -> service.getMenstrualHistory(BEN_REG_ID, VISIT_CODE));
+ }
+
+ private com.iemr.tm.data.nurse.BenCancerVitalDetail cancerVitals() {
+ com.iemr.tm.data.nurse.BenCancerVitalDetail vitals =
+ new com.iemr.tm.data.nurse.BenCancerVitalDetail();
+ vitals.setWeight_Kg(62.0);
+ vitals.setSystolicBP_1stReading((short) 120);
+ vitals.setSystolicBP_2ndReading((short) 122);
+ vitals.setSystolicBP_3rdReading((short) 118);
+ vitals.setDiastolicBP_1stReading((short) 80);
+ vitals.setDiastolicBP_2ndReading((short) 82);
+ vitals.setDiastolicBP_3rdReading((short) 78);
+ vitals.setBloodGlucose_Fasting((short) 90);
+ vitals.setBloodGlucose_Random((short) 120);
+ vitals.setBloodGlucose_2HrPostPrandial((short) 140);
+ vitals.setCreatedDate(new java.sql.Timestamp(System.currentTimeMillis()));
+ return vitals;
+ }
+
+ @Test
+ @DisplayName("getGraphicalTrendData should chart the weight, blood pressure and blood glucose readings")
+ void getGraphicalTrendData_shouldChartWeightBpAndGlucose() {
+ java.util.ArrayList visits = new java.util.ArrayList<>();
+ visits.add(new Object[] { 3L, "Cancer Screening", "22" });
+ visits.add(new Object[] { 4L, "ANC", "23" });
+ when(benVisitDetailRepo.getLastSixVisitDetailsForBeneficiary(BEN_REG_ID)).thenReturn(visits);
+ when(benCancerVitalDetailRepo.getBenCancerVitalDetailForGraph(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(new java.util.ArrayList<>(
+ java.util.Collections.singletonList(cancerVitals())));
+ java.util.ArrayList anthro = new java.util.ArrayList<>();
+ anthro.add(new Object[] { "60", java.sql.Date.valueOf("2026-08-01") });
+ when(benAnthropometryRepo.getBenAnthropometryDetailForGraphtrends(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(anthro);
+ java.util.ArrayList vital = new java.util.ArrayList<>();
+ vital.add(new Object[] { (short) 120, (short) 80, "90", "120", "140",
+ java.sql.Date.valueOf("2026-08-01") });
+ when(benPhysicalVitalRepo.getBenPhysicalVitalDetailForGraphTrends(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(vital);
+
+ java.util.Map trend = service.getGraphicalTrendData(BEN_REG_ID, "ANC");
+
+ assertNotNull(trend);
+ assertTrue(trend.containsKey("bpList") || !trend.isEmpty());
+ }
+
+ @Test
+ @DisplayName("getGraphicalTrendData should answer for a beneficiary with no earlier visit")
+ void getGraphicalTrendData_shouldAnswerWithoutEarlierVisit() {
+ when(benVisitDetailRepo.getLastSixVisitDetailsForBeneficiary(BEN_REG_ID))
+ .thenReturn(new java.util.ArrayList<>());
+
+ assertNotNull(service.getGraphicalTrendData(BEN_REG_ID, "ANC"));
+ }
+
+ private com.iemr.tm.data.ncdScreening.IDRSData idrsAnswer(Long visitCode, Integer questionID) {
+ com.iemr.tm.data.ncdScreening.IDRSData answer = new com.iemr.tm.data.ncdScreening.IDRSData();
+ answer.setVisitCode(visitCode);
+ answer.setIdrsQuestionID(questionID);
+ answer.setAnswer("Yes");
+ answer.setSuspectedDisease("Diabetes");
+ answer.setConfirmedDisease("Diabetes");
+ return answer;
+ }
+
+ @Test
+ @DisplayName("getBenSymptomaticData should collect the answers of the most recent screening")
+ void getBenSymptomaticData_shouldCollectRecentAnswers() throws Exception {
+ when(iDRSDataRepo.getBenIdrsDetailsLast_3_Month(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.any()))
+ .thenReturn(new java.util.ArrayList<>(java.util.Arrays.asList(
+ idrsAnswer(22L, 1), idrsAnswer(22L, 2), idrsAnswer(23L, 3))));
+
+ String result = service.getBenSymptomaticData(BEN_REG_ID);
+
+ assertNotNull(result);
+ assertTrue(result.contains("Diabetes"));
+ }
+
+ @Test
+ @DisplayName("getBenSymptomaticData should answer for a beneficiary with no recent screening")
+ void getBenSymptomaticData_shouldAnswerWithoutRecentScreening() throws Exception {
+ when(iDRSDataRepo.getBenIdrsDetailsLast_3_Month(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.any())).thenReturn(new java.util.ArrayList<>());
+
+ assertNotNull(service.getBenSymptomaticData(BEN_REG_ID));
+ }
+
+ @Test
+ @DisplayName("getBenPreviousReferralData should render the earlier referrals with the report columns")
+ void getBenPreviousReferralData_shouldRenderEarlierReferrals() throws Exception {
+ java.util.ArrayList rows = new java.util.ArrayList<>();
+ rows.add(new Object[] { java.math.BigInteger.valueOf(22L),
+ new java.sql.Timestamp(System.currentTimeMillis()), "Diabetes" });
+ when(iDRSDataRepo.getBenPreviousReferredDetails(BEN_REG_ID)).thenReturn(rows);
+
+ String result = service.getBenPreviousReferralData(BEN_REG_ID);
+
+ assertTrue(result.contains("columns"));
+ assertTrue(result.contains("Diabetes"));
+ }
+
+ @Test
+ @DisplayName("getBenPreviousReferralData should render only the columns when there is no earlier referral")
+ void getBenPreviousReferralData_shouldRenderColumnsOnly() throws Exception {
+ when(iDRSDataRepo.getBenPreviousReferredDetails(BEN_REG_ID)).thenReturn(null);
+
+ assertTrue(service.getBenPreviousReferralData(BEN_REG_ID).contains("columns"));
+ }
+ }
+
+ @Nested
+ @DisplayName("provider specific data")
+ class ProviderSpecificDataTests {
+
+ private String request(String fetchFor) {
+ return "{\"benRegID\":11,\"visitCode\":22,\"fetchMMUDataFor\":\"" + fetchFor + "\"}";
+ }
+
+ @Test
+ @DisplayName("fetchProviderSpecificdata should render the prescribed drugs")
+ void fetchProviderSpecificdata_shouldRenderPrescribedDrugs() throws Exception {
+ when(prescribedDrugDetailRepo.getBenPrescribedDrugDetails(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(new java.util.ArrayList<>());
+
+ assertTrue(service.fetchProviderSpecificdata(request("prescription")).contains("columns"));
+ }
+
+ @Test
+ @DisplayName("fetchProviderSpecificdata should render the ordered tests and the RBS test from the vitals")
+ void fetchProviderSpecificdata_shouldRenderOrderedTestsAndRbsFromVitals() throws Exception {
+ java.util.ArrayList orders = new java.util.ArrayList<>();
+ orders.add(new Object[] { 11L, 3L, 9, 4, "CBC", "1,2", 22L });
+ when(labTestOrderDetailRepo.getLabTestOrderDetails(BEN_REG_ID, VISIT_CODE)).thenReturn(orders);
+ com.iemr.tm.data.nurse.BenPhysicalVitalDetail vitals =
+ new com.iemr.tm.data.nurse.BenPhysicalVitalDetail();
+ vitals.setRbsTestResult("110");
+ when(benPhysicalVitalRepo.getBenPhysicalVitalDetail(BEN_REG_ID, VISIT_CODE)).thenReturn(vitals);
+
+ String result = service.fetchProviderSpecificdata(request("investigation"));
+
+ assertTrue(result.contains("CBC"));
+ assertTrue(result.contains("RBS Test"));
+ }
+
+ @Test
+ @DisplayName("fetchProviderSpecificdata should render the RBS test alone when no test was ordered")
+ void fetchProviderSpecificdata_shouldRenderRbsTestAlone() throws Exception {
+ when(labTestOrderDetailRepo.getLabTestOrderDetails(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(new java.util.ArrayList<>());
+ com.iemr.tm.data.nurse.BenPhysicalVitalDetail vitals =
+ new com.iemr.tm.data.nurse.BenPhysicalVitalDetail();
+ vitals.setRbsTestResult("110");
+ when(benPhysicalVitalRepo.getBenPhysicalVitalDetail(BEN_REG_ID, VISIT_CODE)).thenReturn(vitals);
+
+ assertTrue(service.fetchProviderSpecificdata(request("investigation")).contains("RBS Test"));
+ }
+
+ @Test
+ @DisplayName("fetchProviderSpecificdata should skip the RBS test when it was already ordered")
+ void fetchProviderSpecificdata_shouldSkipAlreadyOrderedRbsTest() throws Exception {
+ java.util.ArrayList orders = new java.util.ArrayList<>();
+ orders.add(new Object[] { 11L, 3L, 9, 4, "RBS Test", "1,2", 22L });
+ when(labTestOrderDetailRepo.getLabTestOrderDetails(BEN_REG_ID, VISIT_CODE)).thenReturn(orders);
+
+ assertTrue(service.fetchProviderSpecificdata(request("investigation")).contains("RBS Test"));
+ verify(benPhysicalVitalRepo, never()).getBenPhysicalVitalDetail(BEN_REG_ID, VISIT_CODE);
+ }
+
+ @Test
+ @DisplayName("fetchProviderSpecificdata should render the referrals")
+ void fetchProviderSpecificdata_shouldRenderReferrals() throws Exception {
+ when(benReferDetailsRepo.getBenReferDetails(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(new java.util.ArrayList<>());
+
+ assertTrue(service.fetchProviderSpecificdata(request("referral")).contains("columns"));
+ }
+
+ @Test
+ @DisplayName("fetchProviderSpecificdata should reject a master it does not know")
+ void fetchProviderSpecificdata_shouldRejectUnknownMaster() throws Exception {
+ assertEquals("Invalid master param to fetch data", service.fetchProviderSpecificdata(request("unknown")));
+ }
+
+ @Test
+ @DisplayName("fetchProviderSpecificdata should report a request it cannot act on")
+ void fetchProviderSpecificdata_shouldReportRequestItCannotActOn() {
+ org.junit.jupiter.api.Assertions.assertThrows(
+ com.iemr.tm.utils.exception.IEMRException.class,
+ () -> service.fetchProviderSpecificdata("{\"benRegID\":11}"));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/common/transaction/CommonServiceImplTest.java b/src/test/java/com/iemr/tm/service/common/transaction/CommonServiceImplTest.java
new file mode 100644
index 00000000..b021eb25
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/common/transaction/CommonServiceImplTest.java
@@ -0,0 +1,349 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.common.transaction;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.benFlowStatus.BeneficiaryFlowStatusRepo;
+import com.iemr.tm.repo.nurse.BenVisitDetailRepo;
+import com.iemr.tm.repo.provider.ProviderServiceMappingRepo;
+import com.iemr.tm.service.anc.ANCServiceImpl;
+import com.iemr.tm.service.cancerScreening.CSNurseServiceImpl;
+import com.iemr.tm.service.cancerScreening.CSServiceImpl;
+import com.iemr.tm.service.covid19.Covid19ServiceImpl;
+import com.iemr.tm.service.generalOPD.GeneralOPDServiceImpl;
+import com.iemr.tm.service.ncdCare.NCDCareServiceImpl;
+import com.iemr.tm.service.ncdscreening.NCDScreeningServiceImpl;
+import com.iemr.tm.service.pnc.PNCServiceImpl;
+import com.iemr.tm.service.quickConsultation.QuickConsultationServiceImpl;
+import com.iemr.tm.service.tele_consultation.TeleConsultationServiceImpl;
+import com.iemr.tm.utils.CookieUtil;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("CommonServiceImpl Test Suite")
+class CommonServiceImplTest {
+
+ @Mock
+ private Covid19ServiceImpl covid19ServiceImpl;
+ @Mock
+ private BeneficiaryFlowStatusRepo beneficiaryFlowStatusRepo;
+ @Mock
+ private ANCServiceImpl ancServiceImpl;
+ @Mock
+ private PNCServiceImpl pncServiceImpl;
+ @Mock
+ private GeneralOPDServiceImpl generalOPDServiceImpl;
+ @Mock
+ private NCDCareServiceImpl ncdCareServiceImpl;
+ @Mock
+ private QuickConsultationServiceImpl quickConsultationServiceImpl;
+ @Mock
+ private CommonNurseServiceImpl commonNurseServiceImpl;
+ @Mock
+ private CSNurseServiceImpl cSNurseServiceImpl;
+ @Mock
+ private CSServiceImpl csServiceImpl;
+ @Mock
+ private NCDScreeningServiceImpl ncdScreeningServiceImpl;
+ @Mock
+ private CommonDoctorServiceImpl commonDoctorServiceImpl;
+ @Mock
+ private TeleConsultationServiceImpl teleConsultationServiceImpl;
+ @Mock
+ private ProviderServiceMappingRepo providerServiceMappingRepo;
+ @Mock
+ private BenVisitDetailRepo benVisitDetailRepo;
+ @Mock
+ private CookieUtil cookieUtil;
+
+ @InjectMocks
+ private CommonServiceImpl service;
+
+ @Test
+ @DisplayName("getCaseSheetPrintDataForBeneficiary should answer for a well formed request")
+ void getCaseSheetPrintDataForBeneficiary_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getCaseSheetPrintDataForBeneficiary(new com.iemr.tm.data.benFlowStatus.BeneficiaryFlowStatus(), "{}"));
+ }
+
+ @Test
+ @DisplayName("getBenPastHistoryData should answer for a well formed request")
+ void getBenPastHistoryData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenPastHistoryData(11L));
+ }
+
+ @Test
+ @DisplayName("getComorbidHistoryData should answer for a well formed request")
+ void getComorbidHistoryData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getComorbidHistoryData(11L));
+ }
+
+ @Test
+ @DisplayName("getMedicationHistoryData should answer for a well formed request")
+ void getMedicationHistoryData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getMedicationHistoryData(11L));
+ }
+
+ @Test
+ @DisplayName("getPersonalTobaccoHistoryData should answer for a well formed request")
+ void getPersonalTobaccoHistoryData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getPersonalTobaccoHistoryData(11L));
+ }
+
+ @Test
+ @DisplayName("getPersonalAlcoholHistoryData should answer for a well formed request")
+ void getPersonalAlcoholHistoryData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getPersonalAlcoholHistoryData(11L));
+ }
+
+ @Test
+ @DisplayName("getPersonalAllergyHistoryData should answer for a well formed request")
+ void getPersonalAllergyHistoryData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getPersonalAllergyHistoryData(11L));
+ }
+
+ @Test
+ @DisplayName("getFamilyHistoryData should answer for a well formed request")
+ void getFamilyHistoryData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getFamilyHistoryData(11L));
+ }
+
+ @Test
+ @DisplayName("getProviderSpecificData should answer for a well formed request")
+ void getProviderSpecificData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getProviderSpecificData("{}"));
+ }
+
+ @Test
+ @DisplayName("getBenPhysicalHistory should answer for a well formed request")
+ void getBenPhysicalHistory_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenPhysicalHistory(11L));
+ }
+
+ @Test
+ @DisplayName("getMenstrualHistoryData should answer for a well formed request")
+ void getMenstrualHistoryData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getMenstrualHistoryData(11L));
+ }
+
+ @Test
+ @DisplayName("getObstetricHistoryData should answer for a well formed request")
+ void getObstetricHistoryData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getObstetricHistoryData(11L));
+ }
+
+ @Test
+ @DisplayName("getImmunizationHistoryData should answer for a well formed request")
+ void getImmunizationHistoryData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getImmunizationHistoryData(11L));
+ }
+
+ @Test
+ @DisplayName("getChildVaccineHistoryData should answer for a well formed request")
+ void getChildVaccineHistoryData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getChildVaccineHistoryData(11L));
+ }
+
+ @Test
+ @DisplayName("getBenPerinatalHistoryData should answer for a well formed request")
+ void getBenPerinatalHistoryData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenPerinatalHistoryData(11L));
+ }
+
+ @Test
+ @DisplayName("getBenFeedingHistoryData should answer for a well formed request")
+ void getBenFeedingHistoryData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenFeedingHistoryData(11L));
+ }
+
+ @Test
+ @DisplayName("getBenDevelopmentHistoryData should answer for a well formed request")
+ void getBenDevelopmentHistoryData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenDevelopmentHistoryData(11L));
+ }
+
+ @Test
+ @DisplayName("getBenPreviousVisitDataForCaseRecord should answer for a well formed request")
+ void getBenPreviousVisitDataForCaseRecord_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenPreviousVisitDataForCaseRecord("{}"));
+ }
+
+ @Test
+ @DisplayName("createTcRequest should answer for a well formed request")
+ void createTcRequest_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.createTcRequest(new com.google.gson.JsonObject(), org.mockito.Mockito.mock(com.iemr.tm.data.nurse.CommonUtilityClass.class), "{}"));
+ }
+
+ @Test
+ @DisplayName("getOpenKMDocURL should reject a request it cannot act on")
+ void getOpenKMDocURL_shouldRejectRequestItCannotActOn() {
+ assertThrows(NullPointerException.class, () -> service.getOpenKMDocURL("{}", "{}"));
+ }
+
+ @Test
+ @DisplayName("getBenSymptomaticQuestionnaireDetailsData should answer for a well formed request")
+ void getBenSymptomaticQuestionnaireDetailsData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenSymptomaticQuestionnaireDetailsData(11L));
+ }
+
+ @Test
+ @DisplayName("getBenPreviousDiabetesData should answer for a well formed request")
+ void getBenPreviousDiabetesData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenPreviousDiabetesData(11L));
+ }
+
+ @Test
+ @DisplayName("getBenPreviousReferralData should answer for a well formed request")
+ void getBenPreviousReferralData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenPreviousReferralData(11L));
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("case sheet assembly")
+ class CaseSheetTests {
+
+ private com.iemr.tm.data.benFlowStatus.BeneficiaryFlowStatus flow(String visitCategory) {
+ com.iemr.tm.data.benFlowStatus.BeneficiaryFlowStatus flow =
+ new com.iemr.tm.data.benFlowStatus.BeneficiaryFlowStatus();
+ flow.setBeneficiaryRegID(11L);
+ flow.setBenVisitCode(22L);
+ flow.setBenFlowID(5L);
+ flow.setVisitCategory(visitCategory);
+ return flow;
+ }
+
+ @org.junit.jupiter.api.BeforeEach
+ void stubBeneficiaryPanel() {
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.getBenDetailsForLeftSidePanel(
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyLong()))
+ .thenReturn(new java.util.ArrayList<>());
+ }
+
+ @Test
+ @DisplayName("getCaseSheetPrintDataForBeneficiary should assemble the ANC case sheet")
+ void getCaseSheet_shouldAssembleAncCaseSheet() throws Exception {
+ org.mockito.Mockito.when(ancServiceImpl.getBenANCNurseData(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong())).thenReturn("{}");
+ org.mockito.Mockito.when(ancServiceImpl.getBenCaseRecordFromDoctorANC(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong())).thenReturn("{}");
+
+ org.junit.jupiter.api.Assertions.assertNotNull(
+ service.getCaseSheetPrintDataForBeneficiary(flow("ANC"), "Bearer session-token"));
+ }
+
+ @Test
+ @DisplayName("getCaseSheetPrintDataForBeneficiary should assemble the PNC case sheet")
+ void getCaseSheet_shouldAssemblePncCaseSheet() throws Exception {
+ org.mockito.Mockito.when(pncServiceImpl.getBenPNCNurseData(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong())).thenReturn("{}");
+ org.mockito.Mockito.when(pncServiceImpl.getBenCaseRecordFromDoctorPNC(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong())).thenReturn("{}");
+
+ org.junit.jupiter.api.Assertions.assertNotNull(
+ service.getCaseSheetPrintDataForBeneficiary(flow("PNC"), "Bearer session-token"));
+ }
+
+ @Test
+ @DisplayName("getCaseSheetPrintDataForBeneficiary should assemble the General OPD case sheet")
+ void getCaseSheet_shouldAssembleGeneralOpdCaseSheet() throws Exception {
+ org.mockito.Mockito.when(generalOPDServiceImpl.getBenGeneralOPDNurseData(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong())).thenReturn("{}");
+ org.mockito.Mockito.when(generalOPDServiceImpl.getBenCaseRecordFromDoctorGeneralOPD(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong())).thenReturn("{}");
+
+ org.junit.jupiter.api.Assertions.assertNotNull(
+ service.getCaseSheetPrintDataForBeneficiary(flow("General OPD"), "Bearer session-token"));
+ }
+
+ @Test
+ @DisplayName("getCaseSheetPrintDataForBeneficiary should assemble the NCD care case sheet")
+ void getCaseSheet_shouldAssembleNcdCareCaseSheet() throws Exception {
+ org.mockito.Mockito.when(ncdCareServiceImpl.getBenNCDCareNurseData(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong())).thenReturn("{}");
+ org.mockito.Mockito.when(ncdCareServiceImpl.getBenCaseRecordFromDoctorNCDCare(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong())).thenReturn("{}");
+
+ org.junit.jupiter.api.Assertions.assertNotNull(
+ service.getCaseSheetPrintDataForBeneficiary(flow("NCD care"), "Bearer session-token"));
+ }
+
+ @Test
+ @DisplayName("getCaseSheetPrintDataForBeneficiary should assemble the General OPD (QC) case sheet")
+ void getCaseSheet_shouldAssembleGeneralOpdQcCaseSheet() throws Exception {
+ org.mockito.Mockito.when(quickConsultationServiceImpl.getBenQuickConsultNurseData(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong())).thenReturn("{}");
+ org.mockito.Mockito.when(quickConsultationServiceImpl.getBenCaseRecordFromDoctorQuickConsult(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong())).thenReturn("{}");
+
+ org.junit.jupiter.api.Assertions.assertNotNull(
+ service.getCaseSheetPrintDataForBeneficiary(flow("General OPD (QC)"), "Bearer session-token"));
+ }
+
+ @Test
+ @DisplayName("getCaseSheetPrintDataForBeneficiary should assemble the COVID-19 Screening case sheet")
+ void getCaseSheet_shouldAssembleCovid19ScreeningCaseSheet() throws Exception {
+ org.mockito.Mockito.when(covid19ServiceImpl.getBenCovidNurseData(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong())).thenReturn("{}");
+ org.mockito.Mockito.when(covid19ServiceImpl.getBenCaseRecordFromDoctorCovid19(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong())).thenReturn("{}");
+
+ org.junit.jupiter.api.Assertions.assertNotNull(
+ service.getCaseSheetPrintDataForBeneficiary(flow("COVID-19 Screening"), "Bearer session-token"));
+ }
+
+ @Test
+ @DisplayName("getCaseSheetPrintDataForBeneficiary should assemble the NCD screening case sheet")
+ void getCaseSheet_shouldAssembleNcdScreeningCaseSheet() throws Exception {
+ org.mockito.Mockito.when(ncdScreeningServiceImpl.getBenNCDScreeningNurseData(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong())).thenReturn("{}");
+ org.mockito.Mockito.when(ncdScreeningServiceImpl.getBenCaseRecordFromDoctorNCDScreening(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong())).thenReturn("{}");
+
+ org.junit.jupiter.api.Assertions.assertNotNull(
+ service.getCaseSheetPrintDataForBeneficiary(flow("NCD screening"), "Bearer session-token"));
+ }
+
+ @Test
+ @DisplayName("getCaseSheetPrintDataForBeneficiary should answer for an unknown visit category")
+ void getCaseSheet_shouldAnswerForUnknownVisitCategory() throws Exception {
+ org.junit.jupiter.api.Assertions.assertNotNull(
+ service.getCaseSheetPrintDataForBeneficiary(flow("Unknown"), "Bearer session-token"));
+ }
+
+ @Test
+ @DisplayName("getCaseSheetPrintDataForBeneficiary should answer for a visit without a category")
+ void getCaseSheet_shouldAnswerWithoutVisitCategory() throws Exception {
+ org.junit.jupiter.api.Assertions.assertDoesNotThrow(
+ () -> service.getCaseSheetPrintDataForBeneficiary(flow(null), "Bearer session-token"));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/covid19/Covid19ServiceImplTest.java b/src/test/java/com/iemr/tm/service/covid19/Covid19ServiceImplTest.java
new file mode 100644
index 00000000..6479a995
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/covid19/Covid19ServiceImplTest.java
@@ -0,0 +1,534 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.covid19;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyShort;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.sql.Timestamp;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.iemr.tm.data.covid19.Covid19BenFeedback;
+import com.iemr.tm.data.nurse.CommonUtilityClass;
+import com.iemr.tm.data.tele_consultation.TeleconsultationRequestOBJ;
+import com.iemr.tm.repo.nurse.covid19.Covid19BenFeedbackRepo;
+import com.iemr.tm.repo.nurse.BenVisitDetailRepo;
+import com.iemr.tm.repo.quickConsultation.PrescriptionDetailRepo;
+import com.iemr.tm.service.benFlowStatus.CommonBenStatusFlowServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonDoctorServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonNurseServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonServiceImpl;
+import com.iemr.tm.service.labtechnician.LabTechnicianServiceImpl;
+import com.iemr.tm.service.tele_consultation.SMSGatewayServiceImpl;
+import com.iemr.tm.service.tele_consultation.TeleConsultationServiceImpl;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("Covid19ServiceImpl Test Suite")
+class Covid19ServiceImplTest {
+
+ private static final String AUTHORIZATION = "Bearer session-token";
+ private static final Long BEN_REG_ID = 11L;
+ private static final Long VISIT_ID = 3L;
+ private static final Long VISIT_CODE = 22L;
+
+ private static final String FULL_HISTORY = "{\"pastHistory\":{},\"comorbidConditions\":{},"
+ + "\"medicationHistory\":{\"medicationHistoryList\":[{\"currentMedication\":\"Iron\"}]},"
+ + "\"personalHistory\":{},\"familyHistory\":{},\"menstrualHistory\":{},"
+ + "\"femaleObstetricHistory\":{},\"immunizationHistory\":{},\"childVaccineDetails\":{},"
+ + "\"developmentHistory\":{},\"feedingHistory\":{},\"perinatalHistroy\":{}}";
+
+ @Mock
+ private CommonNurseServiceImpl commonNurseServiceImpl;
+ @Mock
+ private CommonDoctorServiceImpl commonDoctorServiceImpl;
+ @Mock
+ private CommonBenStatusFlowServiceImpl commonBenStatusFlowServiceImpl;
+ @Mock
+ private LabTechnicianServiceImpl labTechnicianServiceImpl;
+ @Mock
+ private CommonServiceImpl commonServiceImpl;
+ @Mock
+ private TeleConsultationServiceImpl teleConsultationServiceImpl;
+ @Mock
+ private SMSGatewayServiceImpl sMSGatewayServiceImpl;
+ @Mock
+ private Covid19BenFeedbackRepo covid19BenFeedbackRepo;
+ @Mock
+ private PrescriptionDetailRepo prescriptionDetailRepo;
+ @Mock
+ private BenVisitDetailRepo benVisitDetailRepo;
+
+ @InjectMocks
+ private Covid19ServiceImpl service;
+
+ private JsonObject json(String raw) {
+ return JsonParser.parseString(raw).getAsJsonObject();
+ }
+
+ private JsonObject nurseRequest() {
+ return json("{" + "\"beneficiaryRegID\":11,\"providerServiceMapID\":9,\"vanID\":7,\"sessionID\":1,"
+ + "\"benFlowID\":5,\"createdBy\":\"nurse1\","
+ + "\"visitDetails\":{"
+ + " \"visitDetails\":{\"beneficiaryRegID\":11,\"visitReason\":\"New Chief Complaint\","
+ + " \"visitCategory\":\"COVID-19 Screening\"},"
+ + " \"covidDetails\":{\"symptoms\":[\"Fever\",\"Cough\"],\"contactStatus\":[\"Yes\"],"
+ + " \"suspectedStatusUI\":\"Suspected\"}"
+ + "},"
+ + "\"historyDetails\":" + FULL_HISTORY + ",\"vitalDetails\":{\"height_cm\":170}}");
+ }
+
+ private CommonUtilityClass utility() {
+ CommonUtilityClass utility = new CommonUtilityClass();
+ utility.setBeneficiaryRegID(BEN_REG_ID);
+ utility.setVanID(7);
+ utility.setSessionID(1);
+ utility.setProviderServiceMapID(9);
+ utility.setCreatedBy("nurse1");
+ return utility;
+ }
+
+ private TeleconsultationRequestOBJ teleconsultationRequest(boolean walkIn) {
+ TeleconsultationRequestOBJ request = new TeleconsultationRequestOBJ();
+ request.setWalkIn(walkIn);
+ request.setUserID(42);
+ request.setSpecializationID(2);
+ request.setTmRequestID(8L);
+ request.setAllocationDate(new Timestamp(1_700_000_000_000L));
+ return request;
+ }
+
+ private Covid19BenFeedback storedFeedback() {
+ Covid19BenFeedback stored = new Covid19BenFeedback();
+ stored.setcOVID19ID(5L);
+ return stored;
+ }
+
+ @BeforeEach
+ @DisplayName("Wire the collaborators that every save path needs")
+ void setUp() throws Exception {
+ when(commonNurseServiceImpl.getMaxCurrentdate(anyLong(), anyString(), anyString())).thenReturn(0);
+ when(commonNurseServiceImpl.saveBeneficiaryVisitDetails(any())).thenReturn(VISIT_ID);
+ when(commonNurseServiceImpl.generateVisitCode(anyLong(), any(), any())).thenReturn(VISIT_CODE);
+ when(commonNurseServiceImpl.saveBeneficiaryPhysicalAnthropometryDetails(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBeneficiaryPhysicalVitalDetails(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenPastHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenComorbidConditions(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenMedicationHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.savePersonalHistory(any())).thenReturn(1);
+ when(commonNurseServiceImpl.saveAllergyHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenFamilyHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenMenstrualHistory(any())).thenReturn(1);
+ when(commonNurseServiceImpl.saveFemaleObstetricHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveImmunizationHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveChildOptionalVaccineDetail(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveChildDevelopmentHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveChildFeedingHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.savePerinatalHistory(any())).thenReturn(1L);
+ when(covid19BenFeedbackRepo.save(any())).thenReturn(storedFeedback());
+ when(commonBenStatusFlowServiceImpl.updateBenFlowNurseAfterNurseActivity(any(), anyLong(), anyLong(),
+ anyString(), anyString(), anyShort(), anyShort(), anyShort(), anyShort(), anyShort(), anyLong(), any(),
+ anyShort(), any(), any())).thenReturn(1);
+ }
+
+ @Nested
+ @DisplayName("saveCovid19NurseData")
+ class SaveNurseDataTests {
+
+ @Test
+ @DisplayName("saveCovid19NurseData should save the visit, screening feedback, history and vitals")
+ void saveNurseData_shouldSaveEverySection() throws Exception {
+ String result = service.saveCovid19NurseData(nurseRequest(), AUTHORIZATION);
+
+ assertTrue(result.contains("Data saved successfully"));
+ assertTrue(result.contains("\"visitCode\":\"22\""));
+ verify(covid19BenFeedbackRepo).save(any());
+ }
+
+ @Test
+ @DisplayName("saveCovid19NurseData should save the visit when no screening feedback was captured")
+ void saveNurseData_shouldSaveWithoutScreeningFeedback() throws Exception {
+ JsonObject request = nurseRequest();
+ request.getAsJsonObject("visitDetails").remove("covidDetails");
+
+ assertTrue(service.saveCovid19NurseData(request, AUTHORIZATION).contains("Data saved successfully"));
+ verify(covid19BenFeedbackRepo, never()).save(any());
+ }
+
+ @Test
+ @DisplayName("saveCovid19NurseData should report an already saved visit")
+ void saveNurseData_shouldReportAlreadySavedVisit() throws Exception {
+ when(commonNurseServiceImpl.getMaxCurrentdate(anyLong(), anyString(), anyString())).thenReturn(1);
+
+ assertTrue(service.saveCovid19NurseData(nurseRequest(), AUTHORIZATION).contains("Data already saved"));
+ }
+
+ @Test
+ @DisplayName("saveCovid19NurseData should reject a request without visit details")
+ void saveNurseData_shouldRejectRequestWithoutVisitDetails() {
+ assertThrows(Exception.class, () -> service.saveCovid19NurseData(json("{}"), AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveCovid19NurseData should fail when the visit could not be created")
+ void saveNurseData_shouldFailWhenVisitNotCreated() throws Exception {
+ when(commonNurseServiceImpl.saveBeneficiaryVisitDetails(any())).thenReturn(0L);
+
+ assertThrows(RuntimeException.class, () -> service.saveCovid19NurseData(nurseRequest(), AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveCovid19NurseData should fail when the screening feedback could not be stored")
+ void saveNurseData_shouldFailWhenFeedbackNotStored() throws Exception {
+ when(covid19BenFeedbackRepo.save(any())).thenReturn(null);
+
+ assertThrows(RuntimeException.class, () -> service.saveCovid19NurseData(nurseRequest(), AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveCovid19NurseData should notify a scheduled teleconsultation by SMS")
+ void saveNurseData_shouldNotifyScheduledTeleconsultation() throws Exception {
+ when(commonServiceImpl.createTcRequest(any(), any(), anyString()))
+ .thenReturn(teleconsultationRequest(false));
+
+ service.saveCovid19NurseData(nurseRequest(), AUTHORIZATION);
+
+ verify(sMSGatewayServiceImpl).smsSenderGateway(eq("schedule"), anyLong(), anyInt(), anyLong(), any(),
+ anyString(), anyString(), any(), eq(AUTHORIZATION));
+ }
+ }
+
+ @Nested
+ @DisplayName("deleteVisitDetails")
+ class DeleteVisitDetailsTests {
+
+ @Test
+ @DisplayName("deleteVisitDetails should remove the visit and the screening feedback")
+ void deleteVisitDetails_shouldRemoveVisitRows() throws Exception {
+ when(benVisitDetailRepo.getVisitCode(BEN_REG_ID, 9)).thenReturn(VISIT_CODE);
+
+ service.deleteVisitDetails(nurseRequest());
+
+ verify(covid19BenFeedbackRepo).deleteVisitDetails(VISIT_CODE);
+ verify(benVisitDetailRepo).deleteVisitDetails(VISIT_CODE);
+ }
+
+ @Test
+ @DisplayName("deleteVisitDetails should do nothing for a request without visit details")
+ void deleteVisitDetails_shouldDoNothingWithoutVisitDetails() throws Exception {
+ service.deleteVisitDetails(json("{}"));
+
+ verify(benVisitDetailRepo, never()).deleteVisitDetails(anyLong());
+ }
+ }
+
+ @Nested
+ @DisplayName("nurse section saves")
+ class SectionSaveTests {
+
+ @Test
+ @DisplayName("saveBenVisitDetails should return the new visit id and code")
+ void saveBenVisitDetails_shouldReturnVisitIdAndCode() throws Exception {
+ Map result = service.saveBenVisitDetails(nurseRequest().getAsJsonObject("visitDetails"),
+ utility());
+
+ assertEquals(VISIT_ID, result.get("visitID"));
+ assertEquals(VISIT_CODE, result.get("visitCode"));
+ }
+
+ @Test
+ @DisplayName("saveBenVisitDetails should return nothing when the visit was already recorded")
+ void saveBenVisitDetails_shouldReturnNothingForAlreadyRecordedVisit() throws Exception {
+ when(commonNurseServiceImpl.getMaxCurrentdate(anyLong(), anyString(), anyString())).thenReturn(1);
+
+ assertTrue(service.saveBenVisitDetails(nurseRequest().getAsJsonObject("visitDetails"), utility())
+ .isEmpty());
+ }
+
+ @Test
+ @DisplayName("saveBenCovid19HistoryDetails should store every captured history section")
+ void saveHistory_shouldStoreCapturedSections() throws Exception {
+ assertEquals(1L, service.saveBenCovid19HistoryDetails(json(FULL_HISTORY), VISIT_ID, VISIT_CODE));
+ verify(commonNurseServiceImpl).saveBenPastHistory(any());
+ }
+
+ @Test
+ @DisplayName("saveBenCovid19VitalDetails should store the anthropometry and the physical vitals")
+ void saveVitals_shouldStoreAnthropometryAndPhysicalVitals() throws Exception {
+ assertEquals(1L, service.saveBenCovid19VitalDetails(json("{\"height_cm\":170}"), VISIT_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("saveBenCovid19VitalDetails should report a failure when the physical vitals were not stored")
+ void saveVitals_shouldReportFailureWhenPhysicalVitalsNotStored() throws Exception {
+ when(commonNurseServiceImpl.saveBeneficiaryPhysicalVitalDetails(any())).thenReturn(null);
+
+ assertNull(service.saveBenCovid19VitalDetails(json("{}"), VISIT_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("saveCovidDetails should flatten the symptom, contact and travel lists before storing")
+ void saveCovidDetails_shouldFlattenLists() {
+ Covid19BenFeedback feedback = new Covid19BenFeedback();
+ feedback.setSuspectedStatusUI("Suspected");
+ feedback.setSymptoms(new String[] { "Fever", "Cough" });
+ feedback.setContactStatus(new String[] { "Yes", "No" });
+
+ assertEquals(1, service.saveCovidDetails(feedback));
+ assertEquals("Fever||Cough", feedback.getSymptoms_db());
+ assertEquals("Yes||No", feedback.getcOVID19_contact_history());
+ }
+
+ @Test
+ @DisplayName("saveCovidDetails should store a feedback without any list")
+ void saveCovidDetails_shouldStoreFeedbackWithoutLists() {
+ Covid19BenFeedback feedback = new Covid19BenFeedback();
+ feedback.setSuspectedStatusUI("Not Suspected");
+
+ assertEquals(1, service.saveCovidDetails(feedback));
+ }
+
+ @Test
+ @DisplayName("saveCovidDetails should report a failure when nothing was stored")
+ void saveCovidDetails_shouldReportFailureWhenNothingStored() {
+ when(covid19BenFeedbackRepo.save(any())).thenReturn(null);
+ Covid19BenFeedback feedback = new Covid19BenFeedback();
+ feedback.setSuspectedStatusUI("Not Suspected");
+
+ assertNull(service.saveCovidDetails(feedback));
+ }
+ }
+
+ @Nested
+ @DisplayName("read endpoints")
+ class ReadTests {
+
+ @Test
+ @DisplayName("getBenVisitDetailsFrmNurseCovid19 should assemble the visit and the screening feedback")
+ void getVisitDetails_shouldAssembleVisitSections() {
+ when(covid19BenFeedbackRepo.findByBeneficiaryRegIDAndVisitCode(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(storedFeedback());
+
+ String result = service.getBenVisitDetailsFrmNurseCovid19(BEN_REG_ID, VISIT_CODE);
+
+ assertTrue(result.contains("covid19NurseVisitDetail"));
+ assertTrue(result.contains("covidDetails"));
+ }
+
+ @Test
+ @DisplayName("getBenCovid19HistoryDetails should assemble every stored history section")
+ void getHistoryDetails_shouldAssembleStoredSections() {
+ when(commonNurseServiceImpl.getPastHistoryData(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(new com.iemr.tm.data.anc.BenMedHistory());
+
+ assertTrue(service.getBenCovid19HistoryDetails(BEN_REG_ID, VISIT_CODE).contains("PastHistory"));
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryVitalDetails should assemble the anthropometry and the physical vitals")
+ void getVitalDetails_shouldAssembleVitalSections() {
+ when(commonNurseServiceImpl.getBeneficiaryPhysicalAnthropometryDetails(BEN_REG_ID, VISIT_CODE))
+ .thenReturn("{}");
+ when(commonNurseServiceImpl.getBeneficiaryPhysicalVitalDetails(BEN_REG_ID, VISIT_CODE)).thenReturn("{}");
+
+ assertTrue(service.getBeneficiaryVitalDetails(BEN_REG_ID, VISIT_CODE).contains("benAnthropometryDetail"));
+ }
+
+ @Test
+ @DisplayName("getBenCovidNurseData should assemble the nurse captured sections")
+ void getNurseData_shouldAssembleNurseSections() {
+ assertTrue(service.getBenCovidNurseData(BEN_REG_ID, VISIT_CODE).contains("covidDetails"));
+ }
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorCovid19 should assemble the whole doctor case record")
+ void getCaseRecord_shouldAssembleDoctorCaseRecord() throws Exception {
+ when(commonNurseServiceImpl.getGraphicalTrendData(anyLong(), anyString())).thenReturn(new HashMap<>());
+
+ String result = service.getBenCaseRecordFromDoctorCovid19(BEN_REG_ID, VISIT_CODE);
+
+ assertTrue(result.contains("findings"));
+ assertTrue(result.contains("LabReport"));
+ }
+ }
+
+ @Nested
+ @DisplayName("saveDoctorData")
+ class SaveDoctorDataTests {
+
+ private JsonObject doctorRequest() {
+ return json("{" + "\"beneficiaryRegID\":11,\"benVisitID\":3,\"visitCode\":22,\"providerServiceMapID\":9,"
+ + "\"createdBy\":\"doctor1\",\"doctorSignatureFlag\":true,\"findings\":{},"
+ + "\"diagnosis\":{\"specialistDiagnosis\":\"Covid suspect\",\"doctorDiagnosis\":\"Covid\"},"
+ + "\"investigation\":{\"laboratoryList\":[{\"testID\":1}]},"
+ + "\"prescription\":[{\"drugID\":1,\"formName\":\"Tablet\"}],"
+ + "\"refer\":{\"referredToInstituteID\":1}" + "}");
+ }
+
+ @BeforeEach
+ void stubDoctorCollaborators() throws Exception {
+ when(commonDoctorServiceImpl.saveDocFindings(any())).thenReturn(1);
+ when(commonNurseServiceImpl.savePrescriptionCovid(any(), any(), any(), any(), any(), any(), any(), any(),
+ any(), any())).thenReturn(4L);
+ when(commonNurseServiceImpl.saveBenInvestigation(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenPrescribedDrugsList(any())).thenReturn(1);
+ when(commonDoctorServiceImpl.saveBenReferDetails(any())).thenReturn(1L);
+ when(commonDoctorServiceImpl.updateBenFlowtableAfterDocDataSave(any(), anyBoolean(), anyBoolean(), any(),
+ anyBoolean())).thenReturn(1);
+ }
+
+ @Test
+ @DisplayName("saveDoctorData should save the findings, prescription, tests, drugs and referral")
+ void saveDoctorData_shouldSaveWholeCaseRecord() throws Exception {
+ assertEquals(1L, service.saveDoctorData(doctorRequest(), AUTHORIZATION));
+
+ verify(commonDoctorServiceImpl).saveDocFindings(any());
+ verify(commonNurseServiceImpl).saveBenInvestigation(any());
+ }
+
+ @Test
+ @DisplayName("saveDoctorData should succeed for a case record with only an investigation section")
+ void saveDoctorData_shouldSucceedForMinimalCaseRecord() throws Exception {
+ assertEquals(1L,
+ service.saveDoctorData(json("{\"beneficiaryRegID\":11,\"investigation\":{}}"), AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveDoctorData should return nothing for a null request")
+ void saveDoctorData_shouldReturnNothingForNullRequest() throws Exception {
+ assertNull(service.saveDoctorData(null, AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveDoctorData should fail when the beneficiary flow could not be advanced")
+ void saveDoctorData_shouldFailWhenFlowNotAdvanced() throws Exception {
+ when(commonDoctorServiceImpl.updateBenFlowtableAfterDocDataSave(any(), anyBoolean(), anyBoolean(), any(),
+ anyBoolean())).thenReturn(0);
+
+ assertThrows(RuntimeException.class, () -> service.saveDoctorData(doctorRequest(), AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveDoctorData should notify a scheduled teleconsultation by SMS")
+ void saveDoctorData_shouldNotifyScheduledTeleconsultation() throws Exception {
+ when(commonServiceImpl.createTcRequest(any(), any(), anyString()))
+ .thenReturn(teleconsultationRequest(false));
+
+ service.saveDoctorData(doctorRequest(), AUTHORIZATION);
+
+ verify(sMSGatewayServiceImpl).smsSenderGateway(eq("schedule"), anyLong(), anyInt(), anyLong(), any(), any(),
+ anyString(), any(), eq(AUTHORIZATION));
+ }
+ }
+
+ @Nested
+ @DisplayName("update endpoints")
+ class UpdateTests {
+
+ @Test
+ @DisplayName("updateBenHistoryDetails should succeed when no history section was captured")
+ void updateHistory_shouldSucceedWithoutCapturedSections() throws Exception {
+ assertEquals(1, service.updateBenHistoryDetails(json("{}")));
+ }
+
+ @Test
+ @DisplayName("updateBenVitalDetails should confirm the update when both sections changed")
+ void updateVitals_shouldConfirmUpdate() throws Exception {
+ when(commonNurseServiceImpl.updateANCAnthropometryDetails(any())).thenReturn(1);
+ when(commonNurseServiceImpl.updateANCPhysicalVitalDetails(any())).thenReturn(1);
+
+ assertEquals(1, service.updateBenVitalDetails(json("{\"height_cm\":170}")));
+ }
+
+ @Test
+ @DisplayName("updateBenVitalDetails should report no change when a section did not change")
+ void updateVitals_shouldReportNoChangeWhenSectionUnchanged() throws Exception {
+ when(commonNurseServiceImpl.updateANCAnthropometryDetails(any())).thenReturn(0);
+
+ assertEquals(0, service.updateBenVitalDetails(json("{}")));
+ }
+
+ @Test
+ @DisplayName("updateCovid19DoctorData should return nothing for a null request")
+ void updateDoctorData_shouldReturnNothingForNullRequest() throws Exception {
+ assertNull(service.updateCovid19DoctorData(null, AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("updateCovid19DoctorData should update the whole case record")
+ void updateDoctorData_shouldUpdateWholeCaseRecord() throws Exception {
+ when(commonDoctorServiceImpl.updateDocFindings(any())).thenReturn(1);
+ when(commonNurseServiceImpl.updatePrescription(any())).thenReturn(1);
+ when(commonNurseServiceImpl.saveBenInvestigation(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenPrescribedDrugsList(any())).thenReturn(1);
+ when(commonDoctorServiceImpl.updateBenReferDetails(any())).thenReturn(1L);
+ when(commonDoctorServiceImpl.updateBenFlowtableAfterDocDataUpdate(any(), anyBoolean(), anyBoolean(), any(),
+ anyBoolean())).thenReturn(1);
+
+ JsonObject request = json("{" + "\"beneficiaryRegID\":11,\"benVisitID\":3,\"visitCode\":22,"
+ + "\"isSpecialist\":false,\"findings\":{},\"diagnosis\":{\"prescriptionID\":4},"
+ + "\"investigation\":{\"laboratoryList\":[{\"testID\":1}]},"
+ + "\"prescription\":[{\"drugID\":1,\"formName\":\"Tablet\"}],"
+ + "\"refer\":{\"referredToInstituteID\":1}" + "}");
+
+ assertEquals(1L, service.updateCovid19DoctorData(request, AUTHORIZATION));
+ }
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("COVID-19 captured-section updates")
+ class CapturedSectionUpdateTests {
+
+ @Test
+ @DisplayName("updateBenHistoryDetails should update every captured history section")
+ void updateBenHistoryDetails_shouldUpdateEveryCapturedSection() throws Exception {
+ org.junit.jupiter.api.Assertions.assertDoesNotThrow(() -> service.updateBenHistoryDetails(
+ com.google.gson.JsonParser.parseString("{\"pastHistory\":{},\"comorbidConditions\":{},\"medicationHistory\":{},\"personalHistory\":{},\"familyHistory\":{},\"menstrualHistory\":{},\"femaleObstetricHistory\":{},\"immunizationHistory\":{},\"childVaccineDetails\":{},\"developmentHistory\":{},\"feedingHistory\":{},\"perinatalHistroy\":{},\"allergyHistory\":{}}").getAsJsonObject()));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/dataSyncActivity/DownloadDataFromServerImplTest.java b/src/test/java/com/iemr/tm/service/dataSyncActivity/DownloadDataFromServerImplTest.java
new file mode 100644
index 00000000..ee516c1a
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/dataSyncActivity/DownloadDataFromServerImplTest.java
@@ -0,0 +1,71 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.dataSyncActivity;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.syncActivity_syncLayer.SyncDownloadMasterRepo;
+import com.iemr.tm.repo.syncActivity_syncLayer.TempVanRepo;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("DownloadDataFromServerImpl Test Suite")
+class DownloadDataFromServerImplTest {
+
+ @Mock
+ private SyncDownloadMasterRepo syncDownloadMasterRepo;
+ @Mock
+ private DataSyncRepository dataSyncRepository;
+ @Mock
+ private TempVanRepo tempVanRepo;
+
+ @InjectMocks
+ private DownloadDataFromServerImpl service;
+
+ @Test
+ @DisplayName("downloadMasterDataFromServer should answer for a well formed request")
+ void downloadMasterDataFromServer_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.downloadMasterDataFromServer("{}", 9, 9));
+ }
+
+ @Test
+ @DisplayName("getVanDetailsForMasterDownload should reject a request it cannot act on")
+ void getVanDetailsForMasterDownload_shouldRejectRequestItCannotActOn() {
+ assertThrows(Exception.class, () -> service.getVanDetailsForMasterDownload());
+ }
+
+ @Test
+ @DisplayName("getDownloadStatus should reject a request it cannot act on")
+ void getDownloadStatus_shouldRejectRequestItCannotActOn() {
+ assertThrows(ArithmeticException.class, () -> service.getDownloadStatus());
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/dataSyncActivity/UploadDataToServerImplTest.java b/src/test/java/com/iemr/tm/service/dataSyncActivity/UploadDataToServerImplTest.java
new file mode 100644
index 00000000..5397ea07
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/dataSyncActivity/UploadDataToServerImplTest.java
@@ -0,0 +1,80 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.dataSyncActivity;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.syncActivity_syncLayer.DataSyncGroupsRepo;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("UploadDataToServerImpl Test Suite")
+class UploadDataToServerImplTest {
+
+ @Mock
+ private DataSyncRepository dataSyncRepository;
+ @Mock
+ private DataSyncGroupsRepo dataSyncGroupsRepo;
+
+ @InjectMocks
+ private UploadDataToServerImpl service;
+
+ @Test
+ @DisplayName("getDataToSyncToServer should answer for a well formed request")
+ void getDataToSyncToServer_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getDataToSyncToServer(9, "{}", "{}"));
+ }
+
+ @Test
+ @DisplayName("syncIntercepter should answer for a well formed request")
+ void syncIntercepter_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.syncIntercepter(9, "{}", "{}"));
+ }
+
+ @Test
+ @DisplayName("syncDataToServer should reject a request it cannot act on")
+ void syncDataToServer_shouldRejectRequestItCannotActOn() {
+ assertThrows(IllegalArgumentException.class, () -> service.syncDataToServer("{}", "{}", "{}", "{}", new java.util.ArrayList<>(), "user", "{}"));
+ }
+
+ @Test
+ @DisplayName("getVanSerialNoListForSyncedData should answer for a well formed request")
+ void getVanSerialNoListForSyncedData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getVanSerialNoListForSyncedData("{}", new java.util.ArrayList<>()));
+ }
+
+ @Test
+ @DisplayName("getDataSyncGroupDetails should answer for a well formed request")
+ void getDataSyncGroupDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getDataSyncGroupDetails());
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/dataSyncLayerCentral/GetDataFromVanAndSyncToDBImplTest.java b/src/test/java/com/iemr/tm/service/dataSyncLayerCentral/GetDataFromVanAndSyncToDBImplTest.java
new file mode 100644
index 00000000..da9258b5
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/dataSyncLayerCentral/GetDataFromVanAndSyncToDBImplTest.java
@@ -0,0 +1,72 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.dataSyncLayerCentral;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("GetDataFromVanAndSyncToDBImpl Test Suite")
+class GetDataFromVanAndSyncToDBImplTest {
+
+ @Mock
+ private DataSyncRepositoryCentral dataSyncRepositoryCentral;
+
+ @InjectMocks
+ private GetDataFromVanAndSyncToDBImpl service;
+
+ @Test
+ @DisplayName("syncDataToServer should reject a request it cannot act on")
+ void syncDataToServer_shouldRejectRequestItCannotActOn() {
+ assertThrows(NullPointerException.class, () -> service.syncDataToServer("{}", "{}"));
+ }
+
+ @Test
+ @DisplayName("update_M_BeneficiaryRegIdMapping_for_provisioned_benID should answer for a well formed request")
+ void update_M_BeneficiaryRegIdMapping_for_provisioned_benID_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.update_M_BeneficiaryRegIdMapping_for_provisioned_benID(org.mockito.Mockito.mock(com.iemr.tm.data.syncActivity_syncLayer.SyncUploadDataDigester.class)));
+ }
+
+ @Test
+ @DisplayName("getQueryToInsertDataToServerDB should answer for a well formed request")
+ void getQueryToInsertDataToServerDB_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getQueryToInsertDataToServerDB("{}", "{}", "{}"));
+ }
+
+ @Test
+ @DisplayName("getQueryToUpdateDataToServerDB should answer for a well formed request")
+ void getQueryToUpdateDataToServerDB_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getQueryToUpdateDataToServerDB("{}", "{}", "{}"));
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/foetalmonitor/FoetalMonitorServiceImplTest.java b/src/test/java/com/iemr/tm/service/foetalmonitor/FoetalMonitorServiceImplTest.java
new file mode 100644
index 00000000..21071b6a
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/foetalmonitor/FoetalMonitorServiceImplTest.java
@@ -0,0 +1,156 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.foetalmonitor;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.benFlowStatus.BeneficiaryFlowStatusRepo;
+import com.iemr.tm.repo.foetalmonitor.FoetalMonitorDeviceIDRepo;
+import com.iemr.tm.repo.foetalmonitor.FoetalMonitorRepo;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("FoetalMonitorServiceImpl Test Suite")
+class FoetalMonitorServiceImplTest {
+
+ @Mock
+ private FoetalMonitorRepo foetalMonitorRepo;
+ @Mock
+ private BeneficiaryFlowStatusRepo beneficiaryFlowStatusRepo;
+ @Mock
+ private FoetalMonitorDeviceIDRepo foetalMonitorDeviceIDRepo;
+
+ @InjectMocks
+ private FoetalMonitorServiceImpl service;
+
+ @Test
+ @DisplayName("updateFoetalMonitorData should reject a request it cannot act on")
+ void updateFoetalMonitorData_shouldRejectRequestItCannotActOn() {
+ assertThrows(com.iemr.tm.utils.exception.IEMRException.class, () -> service.updateFoetalMonitorData(new com.iemr.tm.data.foetalmonitor.FoetalMonitor()));
+ }
+
+ @Test
+ @DisplayName("readPDFANDGetBase64 should reject a request it cannot act on")
+ void readPDFANDGetBase64_shouldRejectRequestItCannotActOn() {
+ assertThrows(IllegalArgumentException.class, () -> service.readPDFANDGetBase64("{}"));
+ }
+
+ @Test
+ @DisplayName("sendFoetalMonitorTestDetails should reject a request it cannot act on")
+ void sendFoetalMonitorTestDetails_shouldRejectRequestItCannotActOn() {
+ assertThrows(Exception.class, () -> service.sendFoetalMonitorTestDetails(new com.iemr.tm.data.foetalmonitor.FoetalMonitor(), "{}"));
+ }
+
+ @Test
+ @DisplayName("getFoetalMonitorDetails should answer for a well formed request")
+ void getFoetalMonitorDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getFoetalMonitorDetails(11L));
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("foetal monitor test results")
+ class TestResultTests {
+
+ private com.iemr.tm.data.foetalmonitor.FoetalMonitor deviceResult() {
+ com.iemr.tm.data.foetalmonitor.FoetalMonitor result = new com.iemr.tm.data.foetalmonitor.FoetalMonitor();
+ result.setFoetalMonitorID(4L);
+ result.setAccelerationsList(new java.util.ArrayList<>());
+ result.setDecelerationsList(new java.util.ArrayList<>());
+ result.setMovementEntries(new java.util.ArrayList<>());
+ result.setAutoFetalMovement(new java.util.ArrayList<>());
+ java.util.Map mother = new java.util.HashMap<>();
+ mother.put("cmMotherId", "M1");
+ mother.put("partnerId", "P1");
+ mother.put("partnerName", "Partner");
+ result.setMother(mother);
+ return result;
+ }
+
+ @Test
+ @DisplayName("updateFoetalMonitorData should reject a result for an unknown device test")
+ void updateResult_shouldRejectUnknownDeviceTest() {
+ org.mockito.Mockito.when(foetalMonitorRepo.getFoetalMonitorDetails(4L)).thenReturn(null);
+
+ org.junit.jupiter.api.Assertions.assertThrows(com.iemr.tm.utils.exception.IEMRException.class,
+ () -> service.updateFoetalMonitorData(deviceResult()));
+ }
+
+ @Test
+ @DisplayName("updateFoetalMonitorData should fail when the report file cannot be written")
+ void updateResult_shouldFailWhenReportCannotBeWritten() throws Exception {
+ com.iemr.tm.data.foetalmonitor.FoetalMonitor stored = new com.iemr.tm.data.foetalmonitor.FoetalMonitor();
+ stored.setFoetalMonitorID(4L);
+ stored.setBeneficiaryID(7L);
+ stored.setBeneficiaryRegID(11L);
+ stored.setVisitCode(22L);
+ stored.setBenFlowID(5L);
+ org.mockito.Mockito.when(foetalMonitorRepo.getFoetalMonitorDetails(4L)).thenReturn(stored);
+ org.mockito.Mockito.when(foetalMonitorRepo.save(org.mockito.ArgumentMatchers.any())).thenReturn(stored);
+
+ org.junit.jupiter.api.Assertions.assertThrows(com.iemr.tm.utils.exception.IEMRException.class,
+ () -> service.updateFoetalMonitorData(deviceResult()));
+ }
+
+ @Test
+ @DisplayName("getFoetalMonitorDetails should render the tests recorded against the flow")
+ void getDetails_shouldRenderTestsForFlow() throws Exception {
+ com.iemr.tm.data.foetalmonitor.FoetalMonitor stored = new com.iemr.tm.data.foetalmonitor.FoetalMonitor();
+ stored.setFoetalMonitorID(4L);
+ stored.setBeneficiaryRegID(11L);
+ stored.setBenFlowID(5L);
+ stored.setVisitCode(22L);
+ stored.setResultState(true);
+ org.mockito.Mockito.when(foetalMonitorRepo.getFoetalMonitorDetailsByFlowId(5L))
+ .thenReturn(new java.util.ArrayList<>(java.util.Collections.singletonList(stored)));
+
+ org.junit.jupiter.api.Assertions.assertTrue(
+ service.getFoetalMonitorDetails(5L).contains("benFetosenseData"));
+ }
+
+ @Test
+ @DisplayName("getFoetalMonitorDetails should render an empty list when the flow has no test")
+ void getDetails_shouldRenderEmptyListWithoutTests() throws Exception {
+ org.mockito.Mockito.when(foetalMonitorRepo.getFoetalMonitorDetailsByFlowId(5L))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertTrue(
+ service.getFoetalMonitorDetails(5L).contains("benFetosenseData"));
+ }
+
+ @Test
+ @DisplayName("readPDFANDGetBase64 should reject a path that does not exist")
+ void readReport_shouldRejectMissingPath() {
+ org.junit.jupiter.api.Assertions.assertThrows(Exception.class,
+ () -> service.readPDFANDGetBase64("/no/such/report.pdf"));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/generalOPD/GeneralOPDDoctorServiceImplTest.java b/src/test/java/com/iemr/tm/service/generalOPD/GeneralOPDDoctorServiceImplTest.java
new file mode 100644
index 00000000..73370ad5
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/generalOPD/GeneralOPDDoctorServiceImplTest.java
@@ -0,0 +1,53 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.generalOPD;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.quickConsultation.PrescriptionDetailRepo;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("GeneralOPDDoctorServiceImpl Test Suite")
+class GeneralOPDDoctorServiceImplTest {
+
+ @Mock
+ private PrescriptionDetailRepo prescriptionDetailRepo;
+
+ @InjectMocks
+ private GeneralOPDDoctorServiceImpl service;
+
+ @Test
+ @DisplayName("getGeneralOPDDiagnosisDetails should answer for a well formed request")
+ void getGeneralOPDDiagnosisDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getGeneralOPDDiagnosisDetails(11L, 11L));
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/generalOPD/GeneralOPDServiceImplTest.java b/src/test/java/com/iemr/tm/service/generalOPD/GeneralOPDServiceImplTest.java
new file mode 100644
index 00000000..1acf83d6
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/generalOPD/GeneralOPDServiceImplTest.java
@@ -0,0 +1,627 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.generalOPD;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyShort;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.sql.Timestamp;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.iemr.tm.data.nurse.CommonUtilityClass;
+import com.iemr.tm.data.tele_consultation.TeleconsultationRequestOBJ;
+import com.iemr.tm.repo.nurse.BenVisitDetailRepo;
+import com.iemr.tm.repo.nurse.anc.BenAdherenceRepo;
+import com.iemr.tm.repo.quickConsultation.BenChiefComplaintRepo;
+import com.iemr.tm.service.benFlowStatus.CommonBenStatusFlowServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonDoctorServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonNurseServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonServiceImpl;
+import com.iemr.tm.service.labtechnician.LabTechnicianServiceImpl;
+import com.iemr.tm.service.tele_consultation.SMSGatewayServiceImpl;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("GeneralOPDServiceImpl Test Suite")
+class GeneralOPDServiceImplTest {
+
+ private static final String AUTHORIZATION = "Bearer session-token";
+ private static final Long BEN_REG_ID = 11L;
+ private static final Long VISIT_ID = 3L;
+ private static final Long VISIT_CODE = 22L;
+
+ @Mock
+ private CommonNurseServiceImpl commonNurseServiceImpl;
+ @Mock
+ private CommonDoctorServiceImpl commonDoctorServiceImpl;
+ @Mock
+ private CommonBenStatusFlowServiceImpl commonBenStatusFlowServiceImpl;
+ @Mock
+ private GeneralOPDDoctorServiceImpl generalOPDDoctorServiceImpl;
+ @Mock
+ private LabTechnicianServiceImpl labTechnicianServiceImpl;
+ @Mock
+ private CommonServiceImpl commonServiceImpl;
+ @Mock
+ private SMSGatewayServiceImpl sMSGatewayServiceImpl;
+ @Mock
+ private BenVisitDetailRepo benVisitDetailRepo;
+ @Mock
+ private BenChiefComplaintRepo benChiefComplaintRepo;
+ @Mock
+ private BenAdherenceRepo benAdherenceRepo;
+
+ @InjectMocks
+ private GeneralOPDServiceImpl service;
+
+ private JsonObject json(String raw) {
+ return JsonParser.parseString(raw).getAsJsonObject();
+ }
+
+ private JsonObject nurseRequest() {
+ return json("{" + "\"beneficiaryRegID\":11,\"providerServiceMapID\":9,\"vanID\":7,\"sessionID\":1,"
+ + "\"benFlowID\":5,\"createdBy\":\"nurse1\","
+ + "\"visitDetails\":{"
+ + " \"visitDetails\":{\"beneficiaryRegID\":11,\"visitReason\":\"New Chief Complaint\","
+ + " \"visitCategory\":\"General OPD\"},"
+ + " \"chiefComplaints\":[{\"chiefComplaintID\":3}]"
+ + "},"
+ + "\"historyDetails\":{},\"vitalDetails\":{\"height_cm\":170},"
+ + "\"examinationDetails\":{\"generalExamination\":{}}" + "}");
+ }
+
+ private CommonUtilityClass utility() {
+ CommonUtilityClass utility = new CommonUtilityClass();
+ utility.setBeneficiaryRegID(BEN_REG_ID);
+ utility.setVanID(7);
+ utility.setSessionID(1);
+ utility.setProviderServiceMapID(9);
+ utility.setCreatedBy("nurse1");
+ return utility;
+ }
+
+ private TeleconsultationRequestOBJ teleconsultationRequest(boolean walkIn) {
+ TeleconsultationRequestOBJ request = new TeleconsultationRequestOBJ();
+ request.setWalkIn(walkIn);
+ request.setUserID(42);
+ request.setSpecializationID(2);
+ request.setTmRequestID(8L);
+ request.setAllocationDate(new Timestamp(1_700_000_000_000L));
+ return request;
+ }
+
+ @BeforeEach
+ @DisplayName("Wire the collaborators that every save path needs")
+ void setUp() throws Exception {
+ when(commonNurseServiceImpl.getMaxCurrentdate(anyLong(), anyString(), anyString())).thenReturn(0);
+ when(commonNurseServiceImpl.saveBeneficiaryVisitDetails(any())).thenReturn(VISIT_ID);
+ when(commonNurseServiceImpl.generateVisitCode(anyLong(), any(), any())).thenReturn(VISIT_CODE);
+ when(commonNurseServiceImpl.saveBenChiefComplaints(any())).thenReturn(1);
+ when(commonNurseServiceImpl.saveBeneficiaryPhysicalAnthropometryDetails(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBeneficiaryPhysicalVitalDetails(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.savePhyGeneralExamination(any())).thenReturn(1L);
+ when(commonBenStatusFlowServiceImpl.updateBenFlowNurseAfterNurseActivity(any(), anyLong(), anyLong(),
+ anyString(), anyString(), anyShort(), anyShort(), anyShort(), anyShort(), anyShort(), anyLong(), any(),
+ anyShort(), any(), any())).thenReturn(1);
+ }
+
+ @Nested
+ @DisplayName("saveNurseData")
+ class SaveNurseDataTests {
+
+ @Test
+ @DisplayName("saveNurseData should save the visit, history, vitals and examination")
+ void saveNurseData_shouldSaveEverySection() throws Exception {
+ String result = service.saveNurseData(nurseRequest(), AUTHORIZATION);
+
+ assertTrue(result.contains("Data saved successfully"));
+ assertTrue(result.contains("\"visitCode\":\"22\""));
+ verify(commonNurseServiceImpl).saveBenChiefComplaints(any());
+ }
+
+ @Test
+ @DisplayName("saveNurseData should report an already saved visit without touching the history")
+ void saveNurseData_shouldReportAlreadySavedVisit() throws Exception {
+ when(commonNurseServiceImpl.getMaxCurrentdate(anyLong(), anyString(), anyString())).thenReturn(1);
+
+ assertTrue(service.saveNurseData(nurseRequest(), AUTHORIZATION).contains("Data already saved"));
+ }
+
+ @Test
+ @DisplayName("saveNurseData should reject a request without visit details")
+ void saveNurseData_shouldRejectRequestWithoutVisitDetails() {
+ assertThrows(Exception.class, () -> service.saveNurseData(json("{}"), AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveNurseData should reject a null request")
+ void saveNurseData_shouldRejectNullRequest() {
+ assertThrows(Exception.class, () -> service.saveNurseData(null, AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveNurseData should fail when the visit could not be created")
+ void saveNurseData_shouldFailWhenVisitNotCreated() throws Exception {
+ when(commonNurseServiceImpl.saveBeneficiaryVisitDetails(any())).thenReturn(0L);
+
+ assertThrows(RuntimeException.class, () -> service.saveNurseData(nurseRequest(), AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveNurseData should fail when a section was not captured")
+ void saveNurseData_shouldFailWhenSectionNotCaptured() throws Exception {
+ JsonObject request = nurseRequest();
+ request.remove("examinationDetails");
+
+ assertThrows(RuntimeException.class, () -> service.saveNurseData(request, AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveNurseData should notify a scheduled teleconsultation by SMS")
+ void saveNurseData_shouldNotifyScheduledTeleconsultation() throws Exception {
+ when(commonServiceImpl.createTcRequest(any(), any(), anyString()))
+ .thenReturn(teleconsultationRequest(false));
+
+ service.saveNurseData(nurseRequest(), AUTHORIZATION);
+
+ verify(sMSGatewayServiceImpl).smsSenderGateway(eq("schedule"), anyLong(), anyInt(), anyLong(), any(),
+ anyString(), anyString(), any(), eq(AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveNurseData should not notify a walk-in teleconsultation")
+ void saveNurseData_shouldNotNotifyWalkInTeleconsultation() throws Exception {
+ when(commonServiceImpl.createTcRequest(any(), any(), anyString())).thenReturn(teleconsultationRequest(true));
+
+ service.saveNurseData(nurseRequest(), AUTHORIZATION);
+
+ verify(sMSGatewayServiceImpl, never()).smsSenderGateway(anyString(), anyLong(), anyInt(), anyLong(), any(),
+ anyString(), anyString(), any(), anyString());
+ }
+ }
+
+ @Nested
+ @DisplayName("deleteVisitDetails")
+ class DeleteVisitDetailsTests {
+
+ @Test
+ @DisplayName("deleteVisitDetails should remove the visit rows for a created visit")
+ void deleteVisitDetails_shouldRemoveVisitRows() throws Exception {
+ when(benVisitDetailRepo.getVisitCode(BEN_REG_ID, 9)).thenReturn(VISIT_CODE);
+
+ service.deleteVisitDetails(nurseRequest());
+
+ verify(benVisitDetailRepo).deleteVisitDetails(VISIT_CODE);
+ }
+
+ @Test
+ @DisplayName("deleteVisitDetails should do nothing for a request without visit details")
+ void deleteVisitDetails_shouldDoNothingWithoutVisitDetails() throws Exception {
+ service.deleteVisitDetails(json("{}"));
+
+ verify(benVisitDetailRepo, never()).deleteVisitDetails(anyLong());
+ }
+ }
+
+ @Nested
+ @DisplayName("nurse section saves")
+ class SectionSaveTests {
+
+ @Test
+ @DisplayName("saveBenVisitDetails should return the new visit id and code")
+ void saveBenVisitDetails_shouldReturnVisitIdAndCode() throws Exception {
+ Map result = service.saveBenVisitDetails(nurseRequest().getAsJsonObject("visitDetails"),
+ utility());
+
+ assertEquals(VISIT_ID, result.get("visitID"));
+ assertEquals(VISIT_CODE, result.get("visitCode"));
+ }
+
+ @Test
+ @DisplayName("saveBenVisitDetails should return nothing when the visit was already recorded")
+ void saveBenVisitDetails_shouldReturnNothingForAlreadyRecordedVisit() throws Exception {
+ when(commonNurseServiceImpl.getMaxCurrentdate(anyLong(), anyString(), anyString())).thenReturn(1);
+
+ assertTrue(service.saveBenVisitDetails(nurseRequest().getAsJsonObject("visitDetails"), utility())
+ .isEmpty());
+ }
+
+ @Test
+ @DisplayName("saveBenVisitDetails should return nothing for a payload without visit details")
+ void saveBenVisitDetails_shouldReturnNothingWithoutVisitDetails() throws Exception {
+ assertTrue(service.saveBenVisitDetails(json("{}"), utility()).isEmpty());
+ }
+
+ @Test
+ @DisplayName("saveBenGeneralOPDHistoryDetails should succeed when no history section was captured")
+ void saveHistory_shouldSucceedWithoutCapturedSections() throws Exception {
+ assertEquals(1L, service.saveBenGeneralOPDHistoryDetails(json("{}"), VISIT_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("saveBenGeneralOPDHistoryDetails should store every captured history section")
+ void saveHistory_shouldStoreCapturedSections() throws Exception {
+ when(commonNurseServiceImpl.saveBenPastHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenComorbidConditions(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenMedicationHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveFemaleObstetricHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenMenstrualHistory(any())).thenReturn(1);
+ when(commonNurseServiceImpl.saveBenFamilyHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.savePersonalHistory(any())).thenReturn(1);
+ when(commonNurseServiceImpl.saveAllergyHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveChildOptionalVaccineDetail(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveImmunizationHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveChildDevelopmentHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveChildFeedingHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.savePerinatalHistory(any())).thenReturn(1L);
+
+ JsonObject history = json("{\"pastHistory\":{},\"comorbidConditions\":{},"
+ + "\"medicationHistory\":{\"medicationHistoryList\":[{\"currentMedication\":\"Metformin\"}]},"
+ + "\"femaleObstetricHistory\":{},\"menstrualHistory\":{},\"familyHistory\":{},"
+ + "\"personalHistory\":{},\"childVaccineDetails\":{},\"immunizationHistory\":{},"
+ + "\"developmentHistory\":{},\"feedingHistory\":{},\"perinatalHistroy\":{}}");
+
+ assertEquals(1L, service.saveBenGeneralOPDHistoryDetails(history, VISIT_ID, VISIT_CODE));
+ verify(commonNurseServiceImpl).saveBenPastHistory(any());
+ }
+
+ @Test
+ @DisplayName("saveBenGeneralOPDHistoryDetails should report a failure when a section could not be stored")
+ void saveHistory_shouldReportFailureWhenSectionNotStored() throws Exception {
+ when(commonNurseServiceImpl.saveBenPastHistory(any())).thenReturn(null);
+
+ assertNull(service.saveBenGeneralOPDHistoryDetails(json("{\"pastHistory\":{}}"), VISIT_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("saveBenVitalDetails should store the anthropometry and the physical vitals")
+ void saveVitals_shouldStoreAnthropometryAndPhysicalVitals() throws Exception {
+ assertEquals(1L, service.saveBenVitalDetails(json("{\"height_cm\":170}"), VISIT_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("saveBenVitalDetails should report a failure when the physical vitals were not stored")
+ void saveVitals_shouldReportFailureWhenPhysicalVitalsNotStored() throws Exception {
+ when(commonNurseServiceImpl.saveBeneficiaryPhysicalVitalDetails(any())).thenReturn(null);
+
+ assertNull(service.saveBenVitalDetails(json("{}"), VISIT_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("saveBenVitalDetails should succeed for a null payload")
+ void saveVitals_shouldSucceedForNullPayload() throws Exception {
+ assertEquals(1L, service.saveBenVitalDetails(null, VISIT_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("saveBenExaminationDetails should succeed when no examination section was captured")
+ void saveExamination_shouldSucceedWithoutCapturedSections() throws Exception {
+ assertEquals(1L, service.saveBenExaminationDetails(json("{}"), VISIT_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("saveBenExaminationDetails should store every captured examination section")
+ void saveExamination_shouldStoreCapturedSections() throws Exception {
+ when(commonNurseServiceImpl.savePhyHeadToToeExamination(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveSysGastrointestinalExamination(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveSysCardiovascularExamination(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveSysRespiratoryExamination(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveSysCentralNervousExamination(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveSysMusculoskeletalSystemExamination(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveSysGenitourinarySystemExamination(any())).thenReturn(1L);
+
+ JsonObject examination = json("{\"generalExamination\":{},\"headToToeExamination\":{},"
+ + "\"gastroIntestinalExamination\":{},\"cardioVascularExamination\":{},"
+ + "\"respiratorySystemExamination\":{},\"centralNervousSystemExamination\":{},"
+ + "\"musculoskeletalSystemExamination\":{},\"genitoUrinarySystemExamination\":{}}");
+
+ assertEquals(1L, service.saveBenExaminationDetails(examination, VISIT_ID, VISIT_CODE));
+ verify(commonNurseServiceImpl).savePhyHeadToToeExamination(any());
+ }
+
+ @Test
+ @DisplayName("saveBenExaminationDetails should report a failure when a section could not be stored")
+ void saveExamination_shouldReportFailureWhenSectionNotStored() throws Exception {
+ when(commonNurseServiceImpl.savePhyGeneralExamination(any())).thenReturn(null);
+
+ assertNull(service.saveBenExaminationDetails(json("{\"generalExamination\":{}}"), VISIT_ID, VISIT_CODE));
+ }
+ }
+
+ @Nested
+ @DisplayName("read endpoints")
+ class ReadTests {
+
+ @Test
+ @DisplayName("getBenVisitDetailsFrmNurseGOPD should assemble the visit and the chief complaints")
+ void getVisitDetails_shouldAssembleVisitSections() {
+ when(commonNurseServiceImpl.getBenChiefComplaints(BEN_REG_ID, VISIT_CODE)).thenReturn("[]");
+
+ String result = service.getBenVisitDetailsFrmNurseGOPD(BEN_REG_ID, VISIT_CODE);
+
+ assertTrue(result.contains("GOPDNurseVisitDetail"));
+ assertTrue(result.contains("BenChiefComplaints"));
+ }
+
+ @Test
+ @DisplayName("getBenHistoryDetails should assemble every stored history section")
+ void getHistoryDetails_shouldAssembleStoredSections() {
+ when(commonNurseServiceImpl.getPastHistoryData(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(new com.iemr.tm.data.anc.BenMedHistory());
+
+ assertTrue(service.getBenHistoryDetails(BEN_REG_ID, VISIT_CODE).contains("PastHistory"));
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryVitalDetails should assemble the anthropometry and the physical vitals")
+ void getVitalDetails_shouldAssembleVitalSections() {
+ when(commonNurseServiceImpl.getBeneficiaryPhysicalAnthropometryDetails(BEN_REG_ID, VISIT_ID))
+ .thenReturn("{}");
+ when(commonNurseServiceImpl.getBeneficiaryPhysicalVitalDetails(BEN_REG_ID, VISIT_ID)).thenReturn("{}");
+
+ String result = service.getBeneficiaryVitalDetails(BEN_REG_ID, VISIT_ID);
+
+ assertTrue(result.contains("benAnthropometryDetail"));
+ assertTrue(result.contains("benPhysicalVitalDetail"));
+ }
+
+ @Test
+ @DisplayName("getExaminationDetailsData should assemble every stored examination section")
+ void getExaminationDetails_shouldAssembleStoredExaminationSections() {
+ when(commonNurseServiceImpl.getGeneralExaminationData(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(new com.iemr.tm.data.anc.PhyGeneralExamination());
+ when(commonNurseServiceImpl.getGenitourinaryExamination(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(new com.iemr.tm.data.anc.SysGenitourinarySystemExamination());
+
+ String result = service.getExaminationDetailsData(BEN_REG_ID, VISIT_CODE);
+
+ assertTrue(result.contains("generalExamination"));
+ assertTrue(result.contains("genitourinaryExamination"));
+ }
+
+ @Test
+ @DisplayName("getBenGeneralOPDNurseData should assemble the nurse captured sections")
+ void getNurseData_shouldAssembleNurseSections() {
+ assertTrue(service.getBenGeneralOPDNurseData(BEN_REG_ID, VISIT_CODE).contains("history"));
+ }
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorGeneralOPD should assemble the whole doctor case record")
+ void getCaseRecord_shouldAssembleDoctorCaseRecord() throws Exception {
+ when(commonNurseServiceImpl.getGraphicalTrendData(BEN_REG_ID, "genOPD")).thenReturn(new HashMap<>());
+
+ String result = service.getBenCaseRecordFromDoctorGeneralOPD(BEN_REG_ID, VISIT_CODE);
+
+ assertTrue(result.contains("findings"));
+ assertTrue(result.contains("LabReport"));
+ assertTrue(result.contains("GraphData"));
+ }
+ }
+
+ @Nested
+ @DisplayName("saveDoctorData")
+ class SaveDoctorDataTests {
+
+ private JsonObject doctorRequest() {
+ return json("{" + "\"beneficiaryRegID\":11,\"benVisitID\":3,\"visitCode\":22,\"providerServiceMapID\":9,"
+ + "\"createdBy\":\"doctor1\",\"doctorSignatureFlag\":true,\"findings\":{},"
+ + "\"diagnosis\":{\"provisionalDiagnosisList\":[{\"term\":\"Fever\",\"conceptID\":\"1\"}]},"
+ + "\"investigation\":{\"laboratoryList\":[{\"testID\":1}]},"
+ + "\"prescription\":[{\"drugID\":1,\"formName\":\"Tablet\"}],"
+ + "\"refer\":{\"referredToInstituteID\":1}" + "}");
+ }
+
+ @BeforeEach
+ void stubDoctorCollaborators() throws Exception {
+ when(commonDoctorServiceImpl.saveDocFindings(any())).thenReturn(1);
+ when(commonNurseServiceImpl.saveBenPrescription(any())).thenReturn(4L);
+ when(commonNurseServiceImpl.saveBenInvestigation(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenPrescribedDrugsList(any())).thenReturn(1);
+ when(commonDoctorServiceImpl.saveBenReferDetails(any())).thenReturn(1L);
+ when(commonDoctorServiceImpl.updateBenFlowtableAfterDocDataSave(any(), anyBoolean(), anyBoolean(), any(),
+ anyBoolean())).thenReturn(1);
+ }
+
+ @Test
+ @DisplayName("saveDoctorData should save the findings, prescription, tests, drugs and referral")
+ void saveDoctorData_shouldSaveWholeCaseRecord() throws Exception {
+ assertEquals(1L, service.saveDoctorData(doctorRequest(), AUTHORIZATION));
+
+ verify(commonDoctorServiceImpl).saveDocFindings(any());
+ verify(commonNurseServiceImpl).saveBenInvestigation(any());
+ verify(commonNurseServiceImpl).saveBenPrescribedDrugsList(any());
+ verify(commonDoctorServiceImpl).saveBenReferDetails(any());
+ }
+
+ @Test
+ @DisplayName("saveDoctorData should succeed for a case record with only an investigation section")
+ void saveDoctorData_shouldSucceedForMinimalCaseRecord() throws Exception {
+ assertEquals(1L,
+ service.saveDoctorData(json("{\"beneficiaryRegID\":11,\"investigation\":{}}"), AUTHORIZATION));
+
+ verify(commonDoctorServiceImpl, never()).saveDocFindings(any());
+ }
+
+ @Test
+ @DisplayName("saveDoctorData should return nothing for a null request")
+ void saveDoctorData_shouldReturnNothingForNullRequest() throws Exception {
+ assertNull(service.saveDoctorData(null, AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveDoctorData should fail when the beneficiary flow could not be advanced")
+ void saveDoctorData_shouldFailWhenFlowNotAdvanced() throws Exception {
+ when(commonDoctorServiceImpl.updateBenFlowtableAfterDocDataSave(any(), anyBoolean(), anyBoolean(), any(),
+ anyBoolean())).thenReturn(0);
+
+ assertThrows(RuntimeException.class, () -> service.saveDoctorData(doctorRequest(), AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveDoctorData should notify a scheduled teleconsultation by SMS")
+ void saveDoctorData_shouldNotifyScheduledTeleconsultation() throws Exception {
+ when(commonServiceImpl.createTcRequest(any(), any(), anyString()))
+ .thenReturn(teleconsultationRequest(false));
+
+ service.saveDoctorData(doctorRequest(), AUTHORIZATION);
+
+ verify(sMSGatewayServiceImpl).smsSenderGateway(eq("schedule"), anyLong(), anyInt(), anyLong(), any(), any(),
+ anyString(), any(), eq(AUTHORIZATION));
+ }
+ }
+
+ @Nested
+ @DisplayName("update endpoints")
+ class UpdateTests {
+
+ @Test
+ @DisplayName("UpdateVisitDetails should update the chief complaints")
+ void updateVisitDetails_shouldUpdateChiefComplaints() throws Exception {
+ when(commonNurseServiceImpl.updateBenChiefComplaints(any())).thenReturn(1);
+
+ assertEquals(1, service.UpdateVisitDetails(
+ json("{\"visitDetails\":{},\"chiefComplaints\":[{\"chiefComplaintID\":3}]}")));
+ }
+
+ @Test
+ @DisplayName("UpdateVisitDetails should report no change for a payload without chief complaints")
+ void updateVisitDetails_shouldReportNoChangeWithoutChiefComplaints() throws Exception {
+ assertEquals(0, service.UpdateVisitDetails(json("{\"visitDetails\":{}}")));
+ }
+
+ @Test
+ @DisplayName("UpdateVisitDetails should report no change for a payload without visit details")
+ void updateVisitDetails_shouldReportNoChangeWithoutVisitDetails() throws Exception {
+ assertEquals(0, service.UpdateVisitDetails(json("{}")));
+ }
+
+ @Test
+ @DisplayName("updateBenHistoryDetails should succeed when no history section was captured")
+ void updateHistory_shouldSucceedWithoutCapturedSections() throws Exception {
+ assertEquals(1, service.updateBenHistoryDetails(json("{}")));
+ }
+
+ @Test
+ @DisplayName("updateBenVitalDetails should confirm the update when both sections changed")
+ void updateVitals_shouldConfirmUpdate() throws Exception {
+ when(commonNurseServiceImpl.updateANCAnthropometryDetails(any())).thenReturn(1);
+ when(commonNurseServiceImpl.updateANCPhysicalVitalDetails(any())).thenReturn(1);
+
+ assertEquals(1, service.updateBenVitalDetails(json("{\"height_cm\":170}")));
+ }
+
+ @Test
+ @DisplayName("updateBenVitalDetails should report no change when a section did not change")
+ void updateVitals_shouldReportNoChangeWhenSectionUnchanged() throws Exception {
+ when(commonNurseServiceImpl.updateANCAnthropometryDetails(any())).thenReturn(0);
+
+ assertEquals(0, service.updateBenVitalDetails(json("{}")));
+ }
+
+ @Test
+ @DisplayName("updateBenExaminationDetails should succeed when no examination section was captured")
+ void updateExamination_shouldSucceedWithoutCapturedSections() throws Exception {
+ assertEquals(1, service.updateBenExaminationDetails(json("{}")));
+ }
+
+ @Test
+ @DisplayName("updateGeneralOPDDoctorData should return nothing for a null request")
+ void updateDoctorData_shouldReturnNothingForNullRequest() throws Exception {
+ assertNull(service.updateGeneralOPDDoctorData(null, AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("updateGeneralOPDDoctorData should update the whole case record")
+ void updateDoctorData_shouldUpdateWholeCaseRecord() throws Exception {
+ when(commonDoctorServiceImpl.updateDocFindings(any())).thenReturn(1);
+ when(commonNurseServiceImpl.updatePrescription(any())).thenReturn(1);
+ when(commonNurseServiceImpl.saveBenInvestigation(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenPrescribedDrugsList(any())).thenReturn(1);
+ when(commonDoctorServiceImpl.updateBenReferDetails(any())).thenReturn(1L);
+ when(commonDoctorServiceImpl.updateBenFlowtableAfterDocDataUpdate(any(), anyBoolean(), anyBoolean(), any(),
+ anyBoolean())).thenReturn(1);
+
+ JsonObject request = json("{" + "\"beneficiaryRegID\":11,\"benVisitID\":3,\"visitCode\":22,"
+ + "\"findings\":{},\"diagnosis\":{\"prescriptionID\":4},"
+ + "\"investigation\":{\"laboratoryList\":[{\"testID\":1}]},"
+ + "\"prescription\":[{\"drugID\":1,\"formName\":\"Tablet\"}],"
+ + "\"refer\":{\"referredToInstituteID\":1}" + "}");
+
+ assertEquals(1L, service.updateGeneralOPDDoctorData(request, AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("updateGeneralOPDDoctorData should fail when the beneficiary flow could not be advanced")
+ void updateDoctorData_shouldFailWhenFlowNotAdvanced() throws Exception {
+ when(commonDoctorServiceImpl.updateBenFlowtableAfterDocDataUpdate(any(), anyBoolean(), anyBoolean(), any(),
+ anyBoolean())).thenReturn(0);
+
+ assertThrows(RuntimeException.class, () -> service.updateGeneralOPDDoctorData(
+ json("{\"beneficiaryRegID\":11,\"investigation\":{}}"), AUTHORIZATION));
+ }
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("general OPD captured-section updates")
+ class CapturedSectionUpdateTests {
+
+ @Test
+ @DisplayName("updateBenHistoryDetails should update every captured history section")
+ void updateBenHistoryDetails_shouldUpdateEveryCapturedSection() throws Exception {
+ org.junit.jupiter.api.Assertions.assertDoesNotThrow(() -> service.updateBenHistoryDetails(
+ com.google.gson.JsonParser.parseString("{\"pastHistory\":{},\"comorbidConditions\":{},\"medicationHistory\":{},\"personalHistory\":{},\"familyHistory\":{},\"menstrualHistory\":{},\"femaleObstetricHistory\":{},\"immunizationHistory\":{},\"childVaccineDetails\":{},\"developmentHistory\":{},\"feedingHistory\":{},\"perinatalHistroy\":{},\"allergyHistory\":{}}").getAsJsonObject()));
+ }
+
+ @Test
+ @DisplayName("updateBenExaminationDetails should update every captured examination section")
+ void updateBenExaminationDetails_shouldUpdateEveryCapturedSection() throws Exception {
+ org.junit.jupiter.api.Assertions.assertDoesNotThrow(() -> service.updateBenExaminationDetails(
+ com.google.gson.JsonParser.parseString("{\"generalExamination\":{},\"headToToeExamination\":{},\"gastroIntestinalExamination\":{},\"cardioVascularExamination\":{},\"respiratorySystemExamination\":{},\"centralNervousSystemExamination\":{},\"musculoskeletalSystemExamination\":{},\"genitoUrinarySystemExamination\":{},\"obstetricExamination\":{}}").getAsJsonObject()));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/health/HealthServiceTest.java b/src/test/java/com/iemr/tm/service/health/HealthServiceTest.java
new file mode 100644
index 00000000..d30f0134
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/health/HealthServiceTest.java
@@ -0,0 +1,218 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.health;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.when;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Map;
+
+import javax.sql.DataSource;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+import org.springframework.data.redis.core.RedisCallback;
+import org.springframework.data.redis.core.RedisTemplate;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("HealthService Test Suite")
+class HealthServiceTest {
+
+ @Mock
+ private DataSource dataSource;
+ @Mock
+ private RedisTemplate redisTemplate;
+ @Mock
+ private Connection connection;
+ @Mock
+ private PreparedStatement statement;
+ @Mock
+ private ResultSet resultSet;
+
+ private HealthService service;
+
+ @BeforeEach
+ @DisplayName("Wire a service over a mocked datasource and Redis template")
+ void setUp() throws Exception {
+ when(dataSource.getConnection()).thenReturn(connection);
+ when(connection.prepareStatement(any(String.class))).thenReturn(statement);
+ when(statement.executeQuery()).thenReturn(resultSet);
+ when(resultSet.next()).thenReturn(true);
+ when(resultSet.getInt(1)).thenReturn(0);
+ service = new HealthService(dataSource, redisTemplate);
+ }
+
+ @AfterEach
+ @DisplayName("Shut the health check executor down after each test")
+ void tearDown() {
+ service.shutdown();
+ }
+
+ @SuppressWarnings("unchecked")
+ private void redisReplies(String reply) {
+ when(redisTemplate.execute(any(RedisCallback.class))).thenReturn(reply);
+ }
+
+ @Nested
+ @DisplayName("checkHealth")
+ class CheckHealthTests {
+
+ @Test
+ @DisplayName("checkHealth should report both components up when MySQL and Redis answer")
+ void checkHealth_shouldReportBothComponentsUp() {
+ redisReplies("PONG");
+
+ Map result = service.checkHealth();
+
+ assertEquals("UP", result.get("status"));
+ assertNotNull(result.get("timestamp"));
+ assertNotNull(result.get("components"));
+ }
+
+ @Test
+ @DisplayName("checkHealth should report Redis down when the ping is not answered")
+ void checkHealth_shouldReportRedisDownWhenPingUnanswered() {
+ redisReplies("NOPE");
+
+ assertEquals("DOWN", service.checkHealth().get("status"));
+ }
+
+ @Test
+ @DisplayName("checkHealth should report Redis down when the ping fails")
+ void checkHealth_shouldReportRedisDownWhenPingFails() {
+ when(redisTemplate.execute(any(RedisCallback.class))).thenThrow(new IllegalStateException("redis down"));
+
+ assertEquals("DOWN", service.checkHealth().get("status"));
+ }
+
+ @Test
+ @DisplayName("checkHealth should report MySQL down when the connection fails")
+ void checkHealth_shouldReportMysqlDownWhenConnectionFails() throws Exception {
+ when(dataSource.getConnection()).thenThrow(new SQLException("connection refused"));
+ redisReplies("PONG");
+
+ Map result = service.checkHealth();
+
+ assertEquals("DOWN", result.get("status"));
+ }
+
+ @Test
+ @DisplayName("checkHealth should report MySQL down when the probe query returns no row")
+ void checkHealth_shouldReportMysqlDownWithoutProbeRow() throws Exception {
+ when(resultSet.next()).thenReturn(false);
+ redisReplies("PONG");
+
+ assertEquals("DOWN", service.checkHealth().get("status"));
+ }
+
+ @Test
+ @DisplayName("checkHealth should skip Redis when no Redis template is configured")
+ void checkHealth_shouldSkipRedisWhenNotConfigured() {
+ HealthService withoutRedis = new HealthService(dataSource, null);
+ try {
+ Map result = withoutRedis.checkHealth();
+
+ assertEquals("UP", result.get("status"));
+ } finally {
+ withoutRedis.shutdown();
+ }
+ }
+
+ @Test
+ @DisplayName("checkHealth should degrade MySQL when the pool reports lock waits")
+ void checkHealth_shouldDegradeMysqlOnLockWaits() throws Exception {
+ when(resultSet.getInt(1)).thenReturn(3);
+ redisReplies("PONG");
+
+ assertEquals("DEGRADED", service.checkHealth().get("status"));
+ }
+
+ @Test
+ @DisplayName("checkHealth should degrade MySQL when the pool reports slow queries")
+ void checkHealth_shouldDegradeMysqlOnSlowQueries() throws Exception {
+ when(resultSet.getInt(1)).thenReturn(0, 5);
+ redisReplies("PONG");
+
+ assertNotNull(service.checkHealth().get("status"));
+ }
+
+ @Test
+ @DisplayName("checkHealth should still answer when the advanced diagnostics fail")
+ void checkHealth_shouldStillAnswerWhenDiagnosticsFail() throws Exception {
+ when(statement.executeQuery()).thenReturn(resultSet).thenThrow(new SQLException("diagnostics failed"));
+ redisReplies("PONG");
+
+ assertNotNull(service.checkHealth().get("status"));
+ }
+
+ @Test
+ @DisplayName("checkHealth should reuse the throttled diagnostics result on a second call")
+ void checkHealth_shouldReuseThrottledDiagnostics() {
+ redisReplies("PONG");
+
+ service.checkHealth();
+
+ assertEquals("UP", service.checkHealth().get("status"));
+ }
+ }
+
+ @Nested
+ @DisplayName("shutdown")
+ class ShutdownTests {
+
+ @Test
+ @DisplayName("shutdown should stop the executor so later checks report the components down")
+ void shutdown_shouldStopExecutor() {
+ service.shutdown();
+
+ Map result = service.checkHealth();
+
+ assertEquals("DOWN", result.get("status"));
+ }
+
+ @Test
+ @DisplayName("shutdown should be safe to call twice")
+ void shutdown_shouldBeSafeToCallTwice() {
+ service.shutdown();
+ service.shutdown();
+
+ assertTrue(true);
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/labtechnician/LabTechnicianServiceImplTest.java b/src/test/java/com/iemr/tm/service/labtechnician/LabTechnicianServiceImplTest.java
new file mode 100644
index 00000000..fea40a35
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/labtechnician/LabTechnicianServiceImplTest.java
@@ -0,0 +1,464 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.labtechnician;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.labModule.ECGAbnormalFindingMasterRepo;
+import com.iemr.tm.repo.labModule.LabResultEntryRepo;
+import com.iemr.tm.repo.labtechnician.V_benLabTestOrderedDetailsRepo;
+import com.iemr.tm.service.benFlowStatus.CommonBenStatusFlowServiceImpl;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("LabTechnicianServiceImpl Test Suite")
+class LabTechnicianServiceImplTest {
+
+ @Mock
+ private V_benLabTestOrderedDetailsRepo v_benLabTestOrderedDetailsRepo;
+ @Mock
+ private LabResultEntryRepo labResultEntryRepo;
+ @Mock
+ private ECGAbnormalFindingMasterRepo ecgAbnormalFindingMasterRepo;
+ @Mock
+ private CommonBenStatusFlowServiceImpl commonBenStatusFlowServiceImpl;
+ @Mock
+ private com.iemr.tm.repo.nurse.BenVisitDetailRepo benVisitDetailRepo;
+ @Mock
+ private com.iemr.tm.repo.login.UserLoginRepo userLoginRepo;
+
+ @InjectMocks
+ private LabTechnicianServiceImpl service;
+
+ @Test
+ @DisplayName("getBenePrescribedProcedureDetails should answer for a well formed request")
+ void getBenePrescribedProcedureDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenePrescribedProcedureDetails(11L, 11L));
+ }
+
+ @Test
+ @DisplayName("getLabResultDataForBen should answer for a well formed request")
+ void getLabResultDataForBen_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getLabResultDataForBen(11L, 11L));
+ }
+
+ @Test
+ @DisplayName("saveLabTestResult should answer for a well formed request")
+ void saveLabTestResult_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.saveLabTestResult(new com.google.gson.JsonObject()));
+ }
+
+
+ @Test
+ @DisplayName("getLast_3_ArchivedTestVisitList should answer for a well formed request")
+ void getLast_3_ArchivedTestVisitList_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getLast_3_ArchivedTestVisitList(11L, 11L));
+ }
+
+ @Test
+ @DisplayName("getLabResultForVisitcode should answer for a well formed request")
+ void getLabResultForVisitcode_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getLabResultForVisitcode(11L, 11L));
+ }
+
+ @Test
+ @DisplayName("getECGAbnormalFindings should answer for a well formed request")
+ void getECGAbnormalFindings_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getECGAbnormalFindings());
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("lab result capture")
+ class LabResultCaptureTests {
+
+ private static final String LAB_REQUEST = "{\"beneficiaryRegID\":11,\"visitCode\":22,\"benVisitID\":3,"
+ + "\"benFlowID\":5,\"createdBy\":\"lab1\",\"providerServiceMapID\":9,\"labCompleted\":true,"
+ + "\"nurseFlag\":2,\"doctorFlag\":2,\"specialist_flag\":1,"
+ + "\"labTestResults\":[{\"procedureID\":1,\"procedureName\":\"CBC\","
+ + " \"compResult\":[{\"testComponentID\":\"2\",\"testResultValue\":\"12\","
+ + " \"testResultUnit\":\"g/dL\",\"remarks\":\"normal\"}]}],"
+ + "\"radiologyTestResults\":[]}";
+
+ private com.google.gson.JsonObject request() {
+ return com.google.gson.JsonParser.parseString(LAB_REQUEST).getAsJsonObject();
+ }
+
+ @Test
+ @DisplayName("saveLabTestResult should store the entered results and stamp the lab technician")
+ void saveLabTestResult_shouldStoreResultsAndStampTechnician() throws Exception {
+ com.iemr.tm.data.login.Users user = new com.iemr.tm.data.login.Users();
+ user.setUserID(42L);
+ org.mockito.Mockito.when(userLoginRepo.getUserByUsername("lab1")).thenReturn(user);
+ org.mockito.Mockito.when(labResultEntryRepo.saveAll(org.mockito.ArgumentMatchers.any()))
+ .thenAnswer(invocation -> invocation.getArgument(0));
+ org.mockito.Mockito.when(commonBenStatusFlowServiceImpl.updateFlowAfterLabResultEntryForTCSpecialist(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any())).thenReturn(1);
+ org.mockito.Mockito.when(commonBenStatusFlowServiceImpl.updateFlowAfterLabResultEntry(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any())).thenReturn(1);
+
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.saveLabTestResult(request()));
+ org.mockito.Mockito.verify(benVisitDetailRepo).updateLabTechnicianID(42L, 22L);
+ }
+
+ @Test
+ @DisplayName("saveLabTestResult should succeed when the request carries no result to store")
+ void saveLabTestResult_shouldSucceedWithoutResults() throws Exception {
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.saveLabTestResult(
+ com.google.gson.JsonParser.parseString("{\"beneficiaryRegID\":11}").getAsJsonObject()));
+ }
+
+ @Test
+ @DisplayName("saveLabTestResult should store the entered results for a wrapper payload")
+ void saveLabTestResult_shouldStoreWrapperResults() throws Exception {
+ com.iemr.tm.data.labModule.WrapperLabResultEntry wrapper = com.iemr.tm.utils.mapper.InputMapper.gson()
+ .fromJson(request(), com.iemr.tm.data.labModule.WrapperLabResultEntry.class);
+ org.mockito.Mockito.when(labResultEntryRepo.saveAll(org.mockito.ArgumentMatchers.any()))
+ .thenAnswer(invocation -> invocation.getArgument(0));
+
+ org.junit.jupiter.api.Assertions.assertNotNull(service.saveLabTestResult(wrapper));
+ }
+
+ @Test
+ @DisplayName("getLabResultDataForBen should expand the stored result components")
+ void getLabResultDataForBen_shouldExpandStoredComponents() {
+ com.iemr.tm.data.labModule.LabResultEntry entry = new com.iemr.tm.data.labModule.LabResultEntry();
+ entry.setBeneficiaryRegID(11L);
+ entry.setVisitCode(22L);
+ com.iemr.tm.data.labModule.ProcedureData procedure = new com.iemr.tm.data.labModule.ProcedureData();
+ procedure.setProcedureName("CBC");
+ procedure.setProcedureType("Laboratory");
+ entry.setProcedureData(procedure);
+ com.iemr.tm.data.labModule.TestComponentMaster component =
+ new com.iemr.tm.data.labModule.TestComponentMaster();
+ component.setTestComponentName("Haemoglobin");
+ entry.setTestComponentMaster(component);
+ org.mockito.Mockito.when(labResultEntryRepo
+ .findByBeneficiaryRegIDAndVisitCodeOrderByProcedureIDAsc(11L, 22L))
+ .thenReturn(new java.util.ArrayList<>(java.util.Collections.singletonList(entry)));
+
+ org.junit.jupiter.api.Assertions.assertFalse(service.getLabResultDataForBen(11L, 22L).isEmpty());
+ }
+
+ @Test
+ @DisplayName("getLabResultForVisitcode should render the stored results for the visit")
+ void getLabResultForVisitcode_shouldRenderStoredResults() {
+ org.mockito.Mockito.when(labResultEntryRepo
+ .findByBeneficiaryRegIDAndVisitCodeOrderByProcedureIDAsc(11L, 22L))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getLabResultForVisitcode(11L, 22L));
+ }
+
+ @Test
+ @DisplayName("getLast_3_ArchivedTestVisitList should render the three most recent tested visits")
+ void getArchivedVisitList_shouldRenderRecentVisits() throws Exception {
+ org.mockito.Mockito.when(labResultEntryRepo.getLast_3_visitForLabTestDone(11L, 22L))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getLast_3_ArchivedTestVisitList(11L, 22L));
+ }
+
+ @Test
+ @DisplayName("getECGAbnormalFindings should render the ECG findings master")
+ void getECGAbnormalFindings_shouldRenderFindingsMaster() {
+ org.mockito.Mockito.when(ecgAbnormalFindingMasterRepo.findByDeleted(false))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getECGAbnormalFindings());
+ }
+
+ @Test
+ @DisplayName("getBenePrescribedProcedureDetails should render the prescribed procedures")
+ void getPrescribedProcedures_shouldRenderProcedures() {
+ org.mockito.Mockito.when(v_benLabTestOrderedDetailsRepo
+ .findDistinctByBeneficiaryRegIDAndVisitCodeAndProcedureTypeAndProcedureIDNotInOrderByProcedureIDAscTestComponentIDAscResultValueAsc(
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyString(), org.mockito.ArgumentMatchers.any()))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getBenePrescribedProcedureDetails(11L, 22L));
+ }
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("prescribed procedure assembly")
+ class PrescribedProcedureTests {
+
+ private com.iemr.tm.data.labtechnician.V_benLabTestOrderedDetails orderedTest(String procedureType,
+ Integer procedureId, Integer componentId) {
+ com.iemr.tm.data.labtechnician.V_benLabTestOrderedDetails ordered =
+ new com.iemr.tm.data.labtechnician.V_benLabTestOrderedDetails();
+ ordered.setBeneficiaryRegID(11L);
+ ordered.setVisitCode(22L);
+ ordered.setProcedureID(procedureId);
+ ordered.setProcedureName("CBC");
+ ordered.setProcedureType(procedureType);
+ ordered.setPrescriptionID(4L);
+ ordered.setIsMandatory(true);
+ ordered.setTestComponentID(componentId);
+ ordered.setTestComponentName("Haemoglobin");
+ ordered.setInputType("Text");
+ ordered.setMeasurementUnit("g/dL");
+ return ordered;
+ }
+
+ private void orderedTestsAre(String procedureType,
+ java.util.ArrayList ordered) {
+ org.mockito.Mockito.when(v_benLabTestOrderedDetailsRepo
+ .findDistinctByBeneficiaryRegIDAndVisitCodeAndProcedureTypeAndProcedureIDNotInOrderByProcedureIDAscTestComponentIDAscResultValueAsc(
+ org.mockito.ArgumentMatchers.eq(11L), org.mockito.ArgumentMatchers.eq(22L),
+ org.mockito.ArgumentMatchers.eq(procedureType), org.mockito.ArgumentMatchers.any()))
+ .thenReturn(ordered);
+ }
+
+ @Test
+ @DisplayName("getBenePrescribedProcedureDetails should group the components of an ordered laboratory test")
+ void getPrescribedProcedures_shouldGroupLaboratoryComponents() {
+ java.util.ArrayList ordered =
+ new java.util.ArrayList<>();
+ ordered.add(orderedTest("Laboratory", 1, 2));
+ ordered.add(orderedTest("Laboratory", 1, 3));
+ ordered.add(orderedTest("Laboratory", 5, 6));
+ orderedTestsAre("Laboratory", ordered);
+ orderedTestsAre("Radiology",
+ new java.util.ArrayList());
+ org.mockito.Mockito.when(labResultEntryRepo
+ .findByBeneficiaryRegIDAndVisitCodeOrderByProcedureIDAsc(11L, 22L))
+ .thenReturn(new java.util.ArrayList<>());
+
+ String result = service.getBenePrescribedProcedureDetails(11L, 22L);
+
+ org.junit.jupiter.api.Assertions.assertTrue(result.contains("CBC"));
+ org.junit.jupiter.api.Assertions.assertTrue(result.contains("Haemoglobin"));
+ }
+
+ @Test
+ @DisplayName("getBenePrescribedProcedureDetails should list an ordered radiology test")
+ void getPrescribedProcedures_shouldListRadiologyTest() {
+ java.util.ArrayList ordered =
+ new java.util.ArrayList<>();
+ ordered.add(orderedTest("Radiology", 7, null));
+ orderedTestsAre("Radiology", ordered);
+ orderedTestsAre("Laboratory",
+ new java.util.ArrayList());
+ org.mockito.Mockito.when(labResultEntryRepo
+ .findByBeneficiaryRegIDAndVisitCodeOrderByProcedureIDAsc(11L, 22L))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getBenePrescribedProcedureDetails(11L, 22L));
+ }
+
+ @Test
+ @DisplayName("getBenePrescribedProcedureDetails should skip procedures whose result is already entered")
+ void getPrescribedProcedures_shouldSkipAlreadyEnteredResults() {
+ com.iemr.tm.data.labModule.LabResultEntry entered = new com.iemr.tm.data.labModule.LabResultEntry();
+ entered.setProcedureID(1);
+ com.iemr.tm.data.labModule.ProcedureData procedure = new com.iemr.tm.data.labModule.ProcedureData();
+ procedure.setProcedureName("CBC");
+ procedure.setProcedureType("Laboratory");
+ entered.setProcedureData(procedure);
+ com.iemr.tm.data.labModule.TestComponentMaster component =
+ new com.iemr.tm.data.labModule.TestComponentMaster();
+ component.setTestComponentName("Haemoglobin");
+ entered.setTestComponentMaster(component);
+ org.mockito.Mockito.when(labResultEntryRepo
+ .findByBeneficiaryRegIDAndVisitCodeOrderByProcedureIDAsc(11L, 22L))
+ .thenReturn(new java.util.ArrayList<>(java.util.Collections.singletonList(entered)));
+ orderedTestsAre("Laboratory",
+ new java.util.ArrayList());
+ orderedTestsAre("Radiology",
+ new java.util.ArrayList());
+
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getBenePrescribedProcedureDetails(11L, 22L));
+ }
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("lab result entry payload")
+ class LabResultPayloadTests {
+
+ private static final String WITH_COMPONENTS = "{\"beneficiaryRegID\":11,\"visitCode\":22,\"visitID\":3,"
+ + "\"benFlowID\":5,\"createdBy\":\"lab1\",\"providerServiceMapID\":9,\"vanID\":7,"
+ + "\"parkingPlaceID\":2,\"labCompleted\":true,\"nurseFlag\":2,\"doctorFlag\":2,\"specialist_flag\":1,"
+ + "\"labTestResults\":[{\"prescriptionID\":4,\"procedureID\":1,\"abnormalFindings\":[3],"
+ + " \"compList\":["
+ + " {\"testComponentID\":\"2\",\"testResultValue\":\"12\",\"testResultUnit\":\"g/dL\","
+ + " \"remarks\":\"normal\"},"
+ + " {\"testComponentID\":\"3\",\"stripsNotAvailable\":\"true\"},"
+ + " {\"testComponentID\":\"4\",\"testResultValue\":\"\"},"
+ + " {\"testComponentID\":\"\",\"testResultValue\":\"9\"}]}],"
+ + "\"radiologyTestResults\":[{\"prescriptionID\":4,\"procedureID\":7,"
+ + " \"testResultValue\":\"No abnormality\",\"fileIDs\":[81,82]}]}";
+
+ private com.iemr.tm.data.labModule.WrapperLabResultEntry wrapper(String raw) throws Exception {
+ return com.iemr.tm.utils.mapper.InputMapper.gson().fromJson(
+ com.google.gson.JsonParser.parseString(raw).getAsJsonObject(),
+ com.iemr.tm.data.labModule.WrapperLabResultEntry.class);
+ }
+
+ @Test
+ @DisplayName("saveLabTestResult should store one row per measured component and attach the report files")
+ void saveLabTestResult_shouldStoreOneRowPerMeasuredComponent() throws Exception {
+ org.mockito.Mockito.when(labResultEntryRepo.saveAll(org.mockito.ArgumentMatchers.any()))
+ .thenAnswer(invocation -> invocation.getArgument(0));
+
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.saveLabTestResult(wrapper(WITH_COMPONENTS)));
+
+ @SuppressWarnings("unchecked")
+ org.mockito.ArgumentCaptor> captor =
+ org.mockito.ArgumentCaptor.forClass(java.util.List.class);
+ org.mockito.Mockito.verify(labResultEntryRepo).saveAll(captor.capture());
+ java.util.List stored = captor.getValue();
+ org.junit.jupiter.api.Assertions.assertEquals(3, stored.size());
+ org.junit.jupiter.api.Assertions.assertEquals("12", stored.get(0).getTestResultValue());
+ org.junit.jupiter.api.Assertions.assertEquals("g/dL", stored.get(0).getTestResultUnit());
+ org.junit.jupiter.api.Assertions.assertEquals("normal", stored.get(0).getRemarks());
+ org.junit.jupiter.api.Assertions.assertEquals(Boolean.TRUE, stored.get(1).getStripsNotAvailable());
+ org.junit.jupiter.api.Assertions.assertEquals("81,82,", stored.get(2).getTestReportFilePath());
+ org.junit.jupiter.api.Assertions.assertEquals(7, stored.get(2).getProcedureID());
+ }
+
+ @Test
+ @DisplayName("saveLabTestResult should report a failure when the stored rows do not match")
+ void saveLabTestResult_shouldReportStoreMismatch() throws Exception {
+ org.mockito.Mockito.when(labResultEntryRepo.saveAll(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertNull(service.saveLabTestResult(wrapper(WITH_COMPONENTS)));
+ }
+
+ @Test
+ @DisplayName("saveLabTestResult should succeed when the wrapper carries no result at all")
+ void saveLabTestResult_shouldSucceedForEmptyWrapper() throws Exception {
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.saveLabTestResult(wrapper(
+ "{\"beneficiaryRegID\":11,\"labTestResults\":[],\"radiologyTestResults\":[]}")));
+ }
+
+ @Test
+ @DisplayName("saveLabTestResult should succeed when every component was left blank")
+ void saveLabTestResult_shouldSucceedWhenEveryComponentBlank() throws Exception {
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.saveLabTestResult(wrapper(
+ "{\"beneficiaryRegID\":11,\"labTestResults\":[{\"procedureID\":1,"
+ + "\"compList\":[{\"testComponentID\":\"2\",\"testResultValue\":\"\"}]}],"
+ + "\"radiologyTestResults\":[]}")));
+ }
+
+ @Test
+ @DisplayName("saveLabTestResult should send a completed specialist visit back to the specialist")
+ void saveLabTestResult_shouldReturnCompletedSpecialistVisit() throws Exception {
+ org.mockito.Mockito.when(labResultEntryRepo.saveAll(org.mockito.ArgumentMatchers.any()))
+ .thenAnswer(invocation -> invocation.getArgument(0));
+ org.mockito.Mockito.when(commonBenStatusFlowServiceImpl.updateFlowAfterLabResultEntryForTCSpecialist(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any())).thenReturn(1);
+
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.saveLabTestResult(
+ com.google.gson.JsonParser.parseString(
+ WITH_COMPONENTS.replace("\"specialist_flag\":1", "\"specialist_flag\":2"))
+ .getAsJsonObject()));
+
+ org.mockito.Mockito.verify(commonBenStatusFlowServiceImpl)
+ .updateFlowAfterLabResultEntryForTCSpecialist(5L, 11L, (short) 3);
+ }
+
+ @Test
+ @DisplayName("saveLabTestResult should keep a partly tested specialist visit with the lab")
+ void saveLabTestResult_shouldKeepPartlyTestedSpecialistVisitWithLab() throws Exception {
+ org.mockito.Mockito.when(labResultEntryRepo.saveAll(org.mockito.ArgumentMatchers.any()))
+ .thenAnswer(invocation -> invocation.getArgument(0));
+ org.mockito.Mockito.when(commonBenStatusFlowServiceImpl.updateFlowAfterLabResultEntryForTCSpecialist(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any())).thenReturn(1);
+
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.saveLabTestResult(
+ com.google.gson.JsonParser.parseString(WITH_COMPONENTS
+ .replace("\"specialist_flag\":1", "\"specialist_flag\":2")
+ .replace("\"labCompleted\":true", "\"labCompleted\":false")).getAsJsonObject()));
+
+ org.mockito.Mockito.verify(commonBenStatusFlowServiceImpl)
+ .updateFlowAfterLabResultEntryForTCSpecialist(5L, 11L, (short) 2);
+ }
+
+ @Test
+ @DisplayName("saveLabTestResult should hand a completed nurse visit to the doctor")
+ void saveLabTestResult_shouldHandCompletedNurseVisitToDoctor() throws Exception {
+ org.mockito.Mockito.when(labResultEntryRepo.saveAll(org.mockito.ArgumentMatchers.any()))
+ .thenAnswer(invocation -> invocation.getArgument(0));
+ org.mockito.Mockito.when(commonBenStatusFlowServiceImpl.updateFlowAfterLabResultEntry(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any())).thenReturn(1);
+
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.saveLabTestResult(
+ com.google.gson.JsonParser.parseString(WITH_COMPONENTS).getAsJsonObject()));
+
+ org.mockito.Mockito.verify(commonBenStatusFlowServiceImpl).updateFlowAfterLabResultEntry(5L, 11L, 3L,
+ (short) 3, (short) 1, (short) 1);
+ }
+
+ @Test
+ @DisplayName("saveLabTestResult should hand a completed doctor visit back to the doctor")
+ void saveLabTestResult_shouldHandCompletedDoctorVisitBackToDoctor() throws Exception {
+ org.mockito.Mockito.when(labResultEntryRepo.saveAll(org.mockito.ArgumentMatchers.any()))
+ .thenAnswer(invocation -> invocation.getArgument(0));
+ org.mockito.Mockito.when(commonBenStatusFlowServiceImpl.updateFlowAfterLabResultEntry(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any())).thenReturn(1);
+
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.saveLabTestResult(
+ com.google.gson.JsonParser.parseString(
+ WITH_COMPONENTS.replace("\"nurseFlag\":2", "\"nurseFlag\":3")).getAsJsonObject()));
+
+ org.mockito.Mockito.verify(commonBenStatusFlowServiceImpl).updateFlowAfterLabResultEntry(5L, 11L, 3L,
+ (short) 3, (short) 3, (short) 1);
+ }
+
+ @Test
+ @DisplayName("saveLabTestResult should keep a partly tested visit with the lab")
+ void saveLabTestResult_shouldKeepPartlyTestedVisitWithLab() throws Exception {
+ org.mockito.Mockito.when(labResultEntryRepo.saveAll(org.mockito.ArgumentMatchers.any()))
+ .thenAnswer(invocation -> invocation.getArgument(0));
+ org.mockito.Mockito.when(commonBenStatusFlowServiceImpl.updateFlowAfterLabResultEntry(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any())).thenReturn(1);
+
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.saveLabTestResult(
+ com.google.gson.JsonParser.parseString(
+ WITH_COMPONENTS.replace("\"labCompleted\":true", "\"labCompleted\":false"))
+ .getAsJsonObject()));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/location/LocationServiceImplTest.java b/src/test/java/com/iemr/tm/service/location/LocationServiceImplTest.java
new file mode 100644
index 00000000..7b1b85a1
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/location/LocationServiceImplTest.java
@@ -0,0 +1,300 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.location;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.location.CountryCityMasterRepo;
+import com.iemr.tm.repo.location.CountryMasterRepo;
+import com.iemr.tm.repo.location.DistrictBlockMasterRepo;
+import com.iemr.tm.repo.location.DistrictBranchMasterRepo;
+import com.iemr.tm.repo.location.DistrictMasterRepo;
+import com.iemr.tm.repo.location.ParkingPlaceMasterRepo;
+import com.iemr.tm.repo.location.ServicePointMasterRepo;
+import com.iemr.tm.repo.location.StateMasterRepo;
+import com.iemr.tm.repo.location.V_GetLocDetailsFromSPidAndPSMidRepo;
+import com.iemr.tm.repo.location.V_getVanLocDetailsRepo;
+import com.iemr.tm.repo.location.V_get_prkngplc_dist_zone_state_from_spidRepo;
+import com.iemr.tm.repo.location.ZoneMasterRepo;
+import com.iemr.tm.repo.login.ServicePointVillageMappingRepo;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("LocationServiceImpl Test Suite")
+class LocationServiceImplTest {
+
+ @Mock
+ private CountryMasterRepo countryMasterRepo;
+ @Mock
+ private CountryCityMasterRepo countryCityMasterRepo;
+ @Mock
+ private StateMasterRepo stateMasterRepo;
+ @Mock
+ private ZoneMasterRepo zoneMasterRepo;
+ @Mock
+ private DistrictMasterRepo districtMasterRepo;
+ @Mock
+ private DistrictBlockMasterRepo districtBlockMasterRepo;
+ @Mock
+ private ParkingPlaceMasterRepo parkingPlaceMasterRepo;
+ @Mock
+ private ServicePointMasterRepo servicePointMasterRepo;
+ @Mock
+ private V_GetLocDetailsFromSPidAndPSMidRepo v_GetLocDetailsFromSPidAndPSMidRepo;
+ @Mock
+ private ServicePointVillageMappingRepo servicePointVillageMappingRepo;
+ @Mock
+ private DistrictBranchMasterRepo districtBranchMasterRepo;
+ @Mock
+ private V_get_prkngplc_dist_zone_state_from_spidRepo v_get_prkngplc_dist_zone_state_from_spidRepo;
+ @Mock
+ private V_getVanLocDetailsRepo v_getVanLocDetailsRepo;
+
+ @InjectMocks
+ private LocationServiceImpl service;
+
+ @Test
+ @DisplayName("getCountryList should answer for a well formed request")
+ void getCountryList_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getCountryList());
+ }
+
+ @Test
+ @DisplayName("getCountryCityList should answer for a well formed request")
+ void getCountryCityList_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getCountryCityList(9));
+ }
+
+ @Test
+ @DisplayName("getStateList should answer for a well formed request")
+ void getStateList_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getStateList());
+ }
+
+ @Test
+ @DisplayName("getZoneList should answer for a well formed request")
+ void getZoneList_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getZoneList(9));
+ }
+
+ @Test
+ @DisplayName("getDistrictList should answer for a well formed request")
+ void getDistrictList_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getDistrictList(9));
+ }
+
+ @Test
+ @DisplayName("getDistrictBlockList should answer for a well formed request")
+ void getDistrictBlockList_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getDistrictBlockList(9));
+ }
+
+ @Test
+ @DisplayName("getParkingPlaceList should answer for a well formed request")
+ void getParkingPlaceList_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getParkingPlaceList(9));
+ }
+
+ @Test
+ @DisplayName("getServicePointPlaceList should answer for a well formed request")
+ void getServicePointPlaceList_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getServicePointPlaceList(9));
+ }
+
+ @Test
+ @DisplayName("getVillageMasterFromBlockID should answer for a well formed request")
+ void getVillageMasterFromBlockID_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getVillageMasterFromBlockID(9));
+ }
+
+ @Test
+ @DisplayName("getLocDetailsNew should answer for a well formed request")
+ void getLocDetailsNew_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getLocDetailsNew(9, 9));
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("location master lookups")
+ class LocationMasterTests {
+
+ private java.util.ArrayList rows(Object[]... values) {
+ return new java.util.ArrayList<>(java.util.Arrays.asList(values));
+ }
+
+ @Test
+ @DisplayName("getStateList should name every configured state")
+ void getStateList_shouldNameEveryState() {
+ org.mockito.Mockito.when(stateMasterRepo.getStateMaster())
+ .thenReturn(rows(new Object[] { 21, "Maharashtra" }));
+
+ org.junit.jupiter.api.Assertions.assertTrue(service.getStateList().contains("Maharashtra"));
+ }
+
+ @Test
+ @DisplayName("getStateList should answer with an empty list when no state is configured")
+ void getStateList_shouldAnswerWithEmptyList() {
+ org.mockito.Mockito.when(stateMasterRepo.getStateMaster()).thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertEquals("[]", service.getStateList());
+ }
+
+ @Test
+ @DisplayName("getZoneList should name every zone of the provider")
+ void getZoneList_shouldNameEveryZone() {
+ org.mockito.Mockito.when(zoneMasterRepo.getZoneMaster(9))
+ .thenReturn(rows(new Object[] { 5, "West Zone" }));
+
+ org.junit.jupiter.api.Assertions.assertTrue(service.getZoneList(9).contains("West Zone"));
+ }
+
+ @Test
+ @DisplayName("getZoneList should answer with an empty list when the provider has no zone")
+ void getZoneList_shouldAnswerWithEmptyList() {
+ org.mockito.Mockito.when(zoneMasterRepo.getZoneMaster(9)).thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertEquals("[]", service.getZoneList(9));
+ }
+
+ @Test
+ @DisplayName("getDistrictList should name every district of the state")
+ void getDistrictList_shouldNameEveryDistrict() {
+ org.mockito.Mockito.when(districtMasterRepo.getDistrictMaster(21))
+ .thenReturn(rows(new Object[] { 31, "Nagpur", 21, 5 }));
+
+ org.junit.jupiter.api.Assertions.assertTrue(service.getDistrictList(21).contains("Nagpur"));
+ }
+
+ @Test
+ @DisplayName("getDistrictList should answer with an empty list when the state has no district")
+ void getDistrictList_shouldAnswerWithEmptyList() {
+ org.mockito.Mockito.when(districtMasterRepo.getDistrictMaster(21)).thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertEquals("[]", service.getDistrictList(21));
+ }
+
+ @Test
+ @DisplayName("getDistrictBlockList should name every block of the district")
+ void getDistrictBlockList_shouldNameEveryBlock() {
+ org.mockito.Mockito.when(districtBlockMasterRepo.getDistrictBlockMaster(31))
+ .thenReturn(rows(new Object[] { 41, "Kamptee" }));
+
+ org.junit.jupiter.api.Assertions.assertTrue(service.getDistrictBlockList(31).contains("Kamptee"));
+ }
+
+ @Test
+ @DisplayName("getDistrictBlockList should answer with an empty list when the district has no block")
+ void getDistrictBlockList_shouldAnswerWithEmptyList() {
+ org.mockito.Mockito.when(districtBlockMasterRepo.getDistrictBlockMaster(31))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertEquals("[]", service.getDistrictBlockList(31));
+ }
+
+ @Test
+ @DisplayName("getParkingPlaceList should name every parking place of the provider")
+ void getParkingPlaceList_shouldNameEveryParkingPlace() {
+ org.mockito.Mockito.when(parkingPlaceMasterRepo.getParkingPlaceMaster(9))
+ .thenReturn(rows(new Object[] { 2, "Kamptee Depot" }));
+
+ org.junit.jupiter.api.Assertions.assertTrue(service.getParkingPlaceList(9).contains("Kamptee Depot"));
+ }
+
+ @Test
+ @DisplayName("getParkingPlaceList should answer with an empty list when the provider has no parking place")
+ void getParkingPlaceList_shouldAnswerWithEmptyList() {
+ org.mockito.Mockito.when(parkingPlaceMasterRepo.getParkingPlaceMaster(9))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertEquals("[]", service.getParkingPlaceList(9));
+ }
+
+ @Test
+ @DisplayName("getServicePointPlaceList should name every service point of the parking place")
+ void getServicePointPlaceList_shouldNameEveryServicePoint() {
+ org.mockito.Mockito.when(servicePointMasterRepo.getServicePointMaster(2))
+ .thenReturn(rows(new Object[] { 51, "PHC Kamptee" }));
+
+ org.junit.jupiter.api.Assertions.assertTrue(service.getServicePointPlaceList(2).contains("PHC Kamptee"));
+ }
+
+ @Test
+ @DisplayName("getServicePointPlaceList should answer with an empty list when the parking place has no service point")
+ void getServicePointPlaceList_shouldAnswerWithEmptyList() {
+ org.mockito.Mockito.when(servicePointMasterRepo.getServicePointMaster(2))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertEquals("[]", service.getServicePointPlaceList(2));
+ }
+
+ @Test
+ @DisplayName("getCountryCityList should list the cities of the country")
+ void getCountryCityList_shouldListCities() {
+ org.mockito.Mockito.when(countryCityMasterRepo.findByCountryIDAndDeleted(1, false))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertEquals("[]", service.getCountryCityList(1));
+ }
+
+ @Test
+ @DisplayName("getVillageMasterFromBlockID should list the villages of the block")
+ void getVillageMasterFromBlockID_shouldListVillages() {
+ org.mockito.Mockito.when(districtBranchMasterRepo.findByBlockID(41))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getVillageMasterFromBlockID(41));
+ }
+
+ @Test
+ @DisplayName("getLocDetailsNew should answer with the van location and the state master")
+ void getLocDetailsNew_shouldAnswerWithVanLocationAndStateMaster() {
+ org.mockito.Mockito.when(v_getVanLocDetailsRepo.getVanLocDetails(7))
+ .thenReturn(rows(new Object[] { 21, 2, 31, "Nagpur" }, new Object[] { 21, 2, 32, "Wardha" }));
+ org.mockito.Mockito.when(stateMasterRepo.getStateMaster())
+ .thenReturn(rows(new Object[] { 21, "Maharashtra", 1 }));
+
+ String result = service.getLocDetailsNew(7, 9);
+
+ org.junit.jupiter.api.Assertions.assertTrue(result.contains("Maharashtra"));
+ org.junit.jupiter.api.Assertions.assertTrue(result.contains("Nagpur"));
+ org.junit.jupiter.api.Assertions.assertTrue(result.contains("parkingPlaceID"));
+ }
+
+ @Test
+ @DisplayName("getLocDetailsNew should answer with an empty location when the van is not mapped")
+ void getLocDetailsNew_shouldAnswerWithEmptyLocation() {
+ org.mockito.Mockito.when(v_getVanLocDetailsRepo.getVanLocDetails(7))
+ .thenReturn(new java.util.ArrayList<>());
+ org.mockito.Mockito.when(stateMasterRepo.getStateMaster()).thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertTrue(service.getLocDetailsNew(7, 9).contains("otherLoc"));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/login/IemrMmuLoginServiceImplTest.java b/src/test/java/com/iemr/tm/service/login/IemrMmuLoginServiceImplTest.java
new file mode 100644
index 00000000..9310bfa0
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/login/IemrMmuLoginServiceImplTest.java
@@ -0,0 +1,207 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.login;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.login.MasterVanRepo;
+import com.iemr.tm.repo.login.ServicePointVillageMappingRepo;
+import com.iemr.tm.repo.login.UserParkingplaceMappingRepo;
+import com.iemr.tm.repo.login.UserVanSpDetails_View_Repo;
+import com.iemr.tm.repo.login.VanServicepointMappingRepo;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("IemrMmuLoginServiceImpl Test Suite")
+class IemrMmuLoginServiceImplTest {
+
+ @Mock
+ private UserParkingplaceMappingRepo userParkingplaceMappingRepo;
+ @Mock
+ private MasterVanRepo masterVanRepo;
+ @Mock
+ private VanServicepointMappingRepo vanServicepointMappingRepo;
+ @Mock
+ private ServicePointVillageMappingRepo servicePointVillageMappingRepo;
+ @Mock
+ private UserVanSpDetails_View_Repo userVanSpDetails_View_Repo;
+
+ @InjectMocks
+ private IemrMmuLoginServiceImpl service;
+
+ @Test
+ @DisplayName("getUserServicePointVanDetails should answer for a well formed request")
+ void getUserServicePointVanDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getUserServicePointVanDetails(9));
+ }
+
+ @Test
+ @DisplayName("getServicepointVillages should answer for a well formed request")
+ void getServicepointVillages_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getServicepointVillages(9));
+ }
+
+ @Test
+ @DisplayName("getUserVanSpDetails should answer for a well formed request")
+ void getUserVanSpDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getUserVanSpDetails(9, 9));
+ }
+
+ @Test
+ @DisplayName("getUserSpokeDetails should answer for a well formed request")
+ void getUserSpokeDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getUserSpokeDetails(9));
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("van and service point lookup")
+ class VanAndServicePointTests {
+
+ /** parkingPlaceID, stateID, stateName, districtID, districtName, blockID, blockName. */
+ private java.util.List parkingPlaceRows() {
+ return new java.util.ArrayList<>(java.util.Collections.singletonList(
+ new Object[] { 2, 21, "Maharashtra", 31, "Nagpur", 41, "Kamptee" }));
+ }
+
+ @Test
+ @DisplayName("getUserServicePointVanDetails should assemble the vans and service points for the parking place")
+ void getUserServicePointVanDetails_shouldAssembleVansAndServicePoints() {
+ org.mockito.Mockito.when(userParkingplaceMappingRepo.getUserParkingPlce(41))
+ .thenReturn(parkingPlaceRows());
+ org.mockito.Mockito.when(masterVanRepo.getUserVanDatails(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(new java.util.ArrayList<>(java.util.Collections.singletonList(
+ new Object[] { 7, "MH-31-AB-1234" })));
+ org.mockito.Mockito.when(vanServicepointMappingRepo
+ .getuserSpSessionDetails(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(new java.util.ArrayList<>(java.util.Collections.singletonList(
+ new Object[] { 51, "PHC Kamptee", "Morning" })));
+
+ String result = service.getUserServicePointVanDetails(41);
+
+ org.junit.jupiter.api.Assertions.assertTrue(result.contains("MH-31-AB-1234"));
+ org.junit.jupiter.api.Assertions.assertTrue(result.contains("PHC Kamptee"));
+ org.junit.jupiter.api.Assertions.assertTrue(result.contains("Maharashtra"));
+ }
+
+ @Test
+ @DisplayName("getUserServicePointVanDetails should answer with placeholders when no van or service point is mapped")
+ void getUserServicePointVanDetails_shouldAnswerWithPlaceholders() {
+ org.mockito.Mockito.when(userParkingplaceMappingRepo.getUserParkingPlce(41))
+ .thenReturn(parkingPlaceRows());
+ org.mockito.Mockito.when(masterVanRepo.getUserVanDatails(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(new java.util.ArrayList<>());
+ org.mockito.Mockito.when(vanServicepointMappingRepo
+ .getuserSpSessionDetails(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(new java.util.ArrayList<>());
+
+ String result = service.getUserServicePointVanDetails(41);
+
+ org.junit.jupiter.api.Assertions.assertTrue(result.contains("userVanDetails"));
+ org.junit.jupiter.api.Assertions.assertTrue(result.contains("userSpDetails"));
+ }
+
+ @Test
+ @DisplayName("getUserServicePointVanDetails should answer with nothing when no parking place is mapped")
+ void getUserServicePointVanDetails_shouldAnswerWithNothingWithoutParkingPlace() {
+ org.mockito.Mockito.when(userParkingplaceMappingRepo.getUserParkingPlce(41))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertEquals("{}", service.getUserServicePointVanDetails(41));
+ }
+
+ @Test
+ @DisplayName("getServicepointVillages should list the villages mapped to the service point")
+ void getServicepointVillages_shouldListMappedVillages() {
+ org.mockito.Mockito.when(servicePointVillageMappingRepo.getServicePointVillages(51))
+ .thenReturn(new java.util.ArrayList<>(java.util.Collections.singletonList(
+ new Object[] { 61, "Kanhan" })));
+
+ org.junit.jupiter.api.Assertions.assertTrue(service.getServicepointVillages(51).contains("Kanhan"));
+ }
+
+ @Test
+ @DisplayName("getServicepointVillages should answer with an empty list when no village is mapped")
+ void getServicepointVillages_shouldAnswerWithEmptyList() {
+ org.mockito.Mockito.when(servicePointVillageMappingRepo.getServicePointVillages(51))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertEquals("[]", service.getServicepointVillages(51));
+ }
+
+ @Test
+ @DisplayName("getUserVanSpDetails should assemble the van, service point and location for the user")
+ void getUserVanSpDetails_shouldAssembleVanServicePointAndLocation() {
+ org.mockito.Mockito.when(userVanSpDetails_View_Repo.getUserVanSpDetails_View(41, 9))
+ .thenReturn(new java.util.ArrayList<>(java.util.Collections.singletonList(
+ new Object[] { 41, 7, "MH-31-AB-1234", (short) 1, 51, "PHC Kamptee", 2, 9 })));
+ org.mockito.Mockito.when(userParkingplaceMappingRepo.getUserParkingPlce(41))
+ .thenReturn(parkingPlaceRows());
+
+ String result = service.getUserVanSpDetails(41, 9);
+
+ org.junit.jupiter.api.Assertions.assertTrue(result.contains("UserVanSpDetails"));
+ org.junit.jupiter.api.Assertions.assertTrue(result.contains("Nagpur"));
+ }
+
+ @Test
+ @DisplayName("getUserVanSpDetails should answer with empty sections when nothing is mapped to the user")
+ void getUserVanSpDetails_shouldAnswerWithEmptySections() {
+ org.mockito.Mockito.when(userVanSpDetails_View_Repo.getUserVanSpDetails_View(41, 9))
+ .thenReturn(new java.util.ArrayList<>());
+ org.mockito.Mockito.when(userParkingplaceMappingRepo.getUserParkingPlce(41))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertTrue(
+ service.getUserVanSpDetails(41, 9).contains("UserLocDetails"));
+ }
+
+ @Test
+ @DisplayName("getUserSpokeDetails should list every van after the all option")
+ void getUserSpokeDetails_shouldListEveryVanAfterAllOption() {
+ org.mockito.Mockito.when(masterVanRepo.getVanMaster(9))
+ .thenReturn(new java.util.ArrayList<>(java.util.Collections.singletonList(
+ new Object[] { 7, "MH-31-AB-1234" })));
+
+ String result = service.getUserSpokeDetails(9);
+
+ org.junit.jupiter.api.Assertions.assertTrue(result.contains("All"));
+ org.junit.jupiter.api.Assertions.assertTrue(result.contains("MH-31-AB-1234"));
+ }
+
+ @Test
+ @DisplayName("getUserSpokeDetails should offer only the all option when no van is configured")
+ void getUserSpokeDetails_shouldOfferOnlyAllOption() {
+ org.mockito.Mockito.when(masterVanRepo.getVanMaster(9)).thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertTrue(service.getUserSpokeDetails(9).contains("All"));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/ncdCare/NCDCareDoctorServiceImplTest.java b/src/test/java/com/iemr/tm/service/ncdCare/NCDCareDoctorServiceImplTest.java
new file mode 100644
index 00000000..a1ddd424
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/ncdCare/NCDCareDoctorServiceImplTest.java
@@ -0,0 +1,110 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.ncdCare;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.nurse.ncdcare.NCDCareDiagnosisRepo;
+import com.iemr.tm.repo.quickConsultation.PrescriptionDetailRepo;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("NCDCareDoctorServiceImpl Test Suite")
+class NCDCareDoctorServiceImplTest {
+
+ @Mock
+ private NCDCareDiagnosisRepo ncdCareDiagnosisRepo;
+ @Mock
+ private PrescriptionDetailRepo prescriptionDetailRepo;
+
+ @InjectMocks
+ private NCDCareDoctorServiceImpl service;
+
+ @Test
+ @DisplayName("saveNCDDiagnosisData should answer for a well formed request")
+ void saveNCDDiagnosisData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.saveNCDDiagnosisData(org.mockito.Mockito.mock(com.iemr.tm.data.ncdcare.NCDCareDiagnosis.class)));
+ }
+
+ @Test
+ @DisplayName("getNCDCareDiagnosisDetails should answer for a well formed request")
+ void getNCDCareDiagnosisDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getNCDCareDiagnosisDetails(11L, 11L));
+ }
+
+ @Test
+ @DisplayName("updateBenNCDCareDiagnosis should answer for a well formed request")
+ void updateBenNCDCareDiagnosis_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateBenNCDCareDiagnosis(org.mockito.Mockito.mock(com.iemr.tm.data.ncdcare.NCDCareDiagnosis.class)));
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("NCD care diagnosis")
+ class DiagnosisTests {
+
+ private com.iemr.tm.data.ncdcare.NCDCareDiagnosis diagnosis() throws Exception {
+ com.iemr.tm.data.ncdcare.NCDCareDiagnosis diagnosis = com.iemr.tm.utils.mapper.InputMapper.gson().fromJson(
+ "{\"beneficiaryRegID\":11,\"visitCode\":22,\"benVisitID\":3,"
+ + "\"ncdScreeningConditionArray\":[\"Diabetes\",\"Hypertension\"]}",
+ com.iemr.tm.data.ncdcare.NCDCareDiagnosis.class);
+ return diagnosis;
+ }
+
+ @Test
+ @DisplayName("saveNCDDiagnosisData should flatten the screening conditions before storing")
+ void saveDiagnosis_shouldFlattenScreeningConditions() throws Exception {
+ com.iemr.tm.data.ncdcare.NCDCareDiagnosis stored = diagnosis();
+ stored.setID(4L);
+ org.mockito.Mockito.when(ncdCareDiagnosisRepo.save(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(stored);
+
+ org.junit.jupiter.api.Assertions.assertEquals(4L, service.saveNCDDiagnosisData(diagnosis()));
+ }
+
+ @Test
+ @DisplayName("getNCDCareDiagnosisDetails should render the stored diagnosis for the visit")
+ void getDiagnosisDetails_shouldRenderStoredDiagnosis() {
+ org.mockito.Mockito.when(ncdCareDiagnosisRepo.getNCDCareDiagnosisDetails(11L, 22L))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getNCDCareDiagnosisDetails(11L, 22L));
+ }
+
+ @Test
+ @DisplayName("updateBenNCDCareDiagnosis should mark an already processed diagnosis as updated")
+ void updateDiagnosis_shouldMarkProcessedAsUpdated() throws Exception {
+ org.mockito.Mockito.when(ncdCareDiagnosisRepo.getNCDCareDiagnosisStatus(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.any())).thenReturn("P");
+
+ org.junit.jupiter.api.Assertions.assertEquals(0, service.updateBenNCDCareDiagnosis(diagnosis()));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/ncdCare/NCDCareServiceImplTest.java b/src/test/java/com/iemr/tm/service/ncdCare/NCDCareServiceImplTest.java
new file mode 100644
index 00000000..ae63cb41
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/ncdCare/NCDCareServiceImplTest.java
@@ -0,0 +1,644 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.ncdCare;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyShort;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.sql.Timestamp;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.iemr.tm.data.nurse.CommonUtilityClass;
+import com.iemr.tm.data.tele_consultation.TeleconsultationRequestOBJ;
+import com.iemr.tm.repo.nurse.BenVisitDetailRepo;
+import com.iemr.tm.repo.nurse.anc.BenAdherenceRepo;
+import com.iemr.tm.repo.quickConsultation.BenChiefComplaintRepo;
+import com.iemr.tm.service.benFlowStatus.CommonBenStatusFlowServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonDoctorServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonNurseServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonServiceImpl;
+import com.iemr.tm.service.labtechnician.LabTechnicianServiceImpl;
+import com.iemr.tm.service.tele_consultation.SMSGatewayServiceImpl;
+import com.iemr.tm.service.tele_consultation.TeleConsultationServiceImpl;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("NCDCareServiceImpl Test Suite")
+class NCDCareServiceImplTest {
+
+ private static final String AUTHORIZATION = "Bearer session-token";
+ private static final Long BEN_REG_ID = 11L;
+ private static final Long VISIT_ID = 3L;
+ private static final Long VISIT_CODE = 22L;
+
+ @Mock
+ private CommonNurseServiceImpl commonNurseServiceImpl;
+ @Mock
+ private CommonDoctorServiceImpl commonDoctorServiceImpl;
+ @Mock
+ private NCDCareDoctorServiceImpl ncdCareDoctorServiceImpl;
+ @Mock
+ private CommonBenStatusFlowServiceImpl commonBenStatusFlowServiceImpl;
+ @Mock
+ private LabTechnicianServiceImpl labTechnicianServiceImpl;
+ @Mock
+ private CommonServiceImpl commonServiceImpl;
+ @Mock
+ private TeleConsultationServiceImpl teleConsultationServiceImpl;
+ @Mock
+ private BenVisitDetailRepo benVisitDetailRepo;
+ @Mock
+ private BenChiefComplaintRepo benChiefComplaintRepo;
+ @Mock
+ private BenAdherenceRepo benAdherenceRepo;
+ @Mock
+ private SMSGatewayServiceImpl sMSGatewayServiceImpl;
+
+ @InjectMocks
+ private NCDCareServiceImpl service;
+
+ private JsonObject json(String raw) {
+ return JsonParser.parseString(raw).getAsJsonObject();
+ }
+
+ /** A nurse request carrying a visit, an ordered lab test, history and vitals. */
+ private JsonObject nurseRequest() {
+ return json("{" + "\"beneficiaryRegID\":11,\"providerServiceMapID\":9,\"vanID\":7,\"sessionID\":1,"
+ + "\"benFlowID\":5,\"createdBy\":\"nurse1\","
+ + "\"visitDetails\":{"
+ + " \"visitDetails\":{\"beneficiaryRegID\":11,\"visitReason\":\"New Chief Complaint\","
+ + " \"visitCategory\":\"NCD care\"},"
+ + " \"adherence\":{\"toDrugs\":true},"
+ + " \"investigation\":{\"laboratoryList\":[{\"testID\":1}]}"
+ + "},"
+ + "\"historyDetails\":{},\"vitalDetails\":{\"height_cm\":170}" + "}");
+ }
+
+ private CommonUtilityClass utility() {
+ CommonUtilityClass utility = new CommonUtilityClass();
+ utility.setBeneficiaryRegID(BEN_REG_ID);
+ utility.setVisitCode(VISIT_CODE);
+ utility.setBenVisitID(VISIT_ID);
+ utility.setProviderServiceMapID(9);
+ utility.setCreatedBy("nurse1");
+ return utility;
+ }
+
+ private TeleconsultationRequestOBJ teleconsultationRequest(boolean walkIn) {
+ TeleconsultationRequestOBJ request = new TeleconsultationRequestOBJ();
+ request.setWalkIn(walkIn);
+ request.setUserID(42);
+ request.setSpecializationID(2);
+ request.setTmRequestID(8L);
+ request.setAllocationDate(new Timestamp(1_700_000_000_000L));
+ return request;
+ }
+
+ @BeforeEach
+ @DisplayName("Wire the collaborators that every save path needs")
+ void setUp() throws Exception {
+ when(commonNurseServiceImpl.getMaxCurrentdate(anyLong(), anyString(), anyString())).thenReturn(0);
+ when(commonNurseServiceImpl.saveBeneficiaryVisitDetails(any())).thenReturn(VISIT_ID);
+ when(commonNurseServiceImpl.generateVisitCode(anyLong(), any(), any())).thenReturn(VISIT_CODE);
+ when(commonNurseServiceImpl.saveBenAdherenceDetails(any())).thenReturn(1);
+ when(commonNurseServiceImpl.saveBenInvestigationDetails(any())).thenReturn(1);
+ when(commonNurseServiceImpl.saveBeneficiaryPhysicalAnthropometryDetails(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBeneficiaryPhysicalVitalDetails(any())).thenReturn(1L);
+ when(commonBenStatusFlowServiceImpl.updateBenFlowNurseAfterNurseActivity(any(), anyLong(), anyLong(),
+ anyString(), anyString(), anyShort(), anyShort(), anyShort(), anyShort(), anyShort(), anyLong(), any(),
+ anyShort(), any(), any())).thenReturn(1);
+ }
+
+ @Nested
+ @DisplayName("saveNCDCareNurseData")
+ class SaveNurseDataTests {
+
+ @Test
+ @DisplayName("saveNCDCareNurseData should save the visit, history and vitals and return the visit code")
+ void saveNurseData_shouldSaveVisitHistoryAndVitals() throws Exception {
+ String result = service.saveNCDCareNurseData(nurseRequest(), AUTHORIZATION);
+
+ assertTrue(result.contains("Data saved successfully"));
+ assertTrue(result.contains("\"visitCode\":\"22\""));
+ }
+
+ @Test
+ @DisplayName("saveNCDCareNurseData should report an already saved visit without touching the history")
+ void saveNurseData_shouldReportAlreadySavedVisit() throws Exception {
+ when(commonNurseServiceImpl.getMaxCurrentdate(anyLong(), anyString(), anyString())).thenReturn(1);
+
+ String result = service.saveNCDCareNurseData(nurseRequest(), AUTHORIZATION);
+
+ assertTrue(result.contains("Data already saved"));
+ verify(commonNurseServiceImpl, never()).saveBeneficiaryVisitDetails(any());
+ }
+
+ @Test
+ @DisplayName("saveNCDCareNurseData should reject a request without visit details")
+ void saveNurseData_shouldRejectRequestWithoutVisitDetails() {
+ assertThrows(Exception.class, () -> service.saveNCDCareNurseData(json("{}"), AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveNCDCareNurseData should reject a null request")
+ void saveNurseData_shouldRejectNullRequest() {
+ assertThrows(Exception.class, () -> service.saveNCDCareNurseData(null, AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveNCDCareNurseData should fail when the visit could not be created")
+ void saveNurseData_shouldFailWhenVisitNotCreated() throws Exception {
+ when(commonNurseServiceImpl.saveBeneficiaryVisitDetails(any())).thenReturn(0L);
+
+ assertThrows(RuntimeException.class, () -> service.saveNCDCareNurseData(nurseRequest(), AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveNCDCareNurseData should fail when the vitals could not be stored")
+ void saveNurseData_shouldFailWhenVitalsNotStored() throws Exception {
+ when(commonNurseServiceImpl.saveBeneficiaryPhysicalVitalDetails(any())).thenReturn(null);
+
+ assertThrows(RuntimeException.class, () -> service.saveNCDCareNurseData(nurseRequest(), AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveNCDCareNurseData should fail when the beneficiary flow could not be advanced")
+ void saveNurseData_shouldFailWhenFlowNotAdvanced() throws Exception {
+ when(commonBenStatusFlowServiceImpl.updateBenFlowNurseAfterNurseActivity(any(), anyLong(), anyLong(),
+ anyString(), anyString(), anyShort(), anyShort(), anyShort(), anyShort(), anyShort(), anyLong(),
+ any(), anyShort(), any(), any())).thenReturn(0);
+
+ assertThrows(RuntimeException.class, () -> service.saveNCDCareNurseData(nurseRequest(), AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveNCDCareNurseData should notify a scheduled teleconsultation by SMS")
+ void saveNurseData_shouldNotifyScheduledTeleconsultation() throws Exception {
+ when(commonServiceImpl.createTcRequest(any(), any(), anyString()))
+ .thenReturn(teleconsultationRequest(false));
+
+ service.saveNCDCareNurseData(nurseRequest(), AUTHORIZATION);
+
+ verify(sMSGatewayServiceImpl).smsSenderGateway(eq("schedule"), anyLong(), anyInt(), anyLong(), any(),
+ anyString(), anyString(), any(), eq(AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveNCDCareNurseData should not notify a walk-in teleconsultation")
+ void saveNurseData_shouldNotNotifyWalkInTeleconsultation() throws Exception {
+ when(commonServiceImpl.createTcRequest(any(), any(), anyString()))
+ .thenReturn(teleconsultationRequest(true));
+
+ service.saveNCDCareNurseData(nurseRequest(), AUTHORIZATION);
+
+ verify(sMSGatewayServiceImpl, never()).smsSenderGateway(anyString(), anyLong(), anyInt(), anyLong(), any(),
+ anyString(), anyString(), any(), anyString());
+ }
+
+ @Test
+ @DisplayName("saveNCDCareNurseData should route the beneficiary to the doctor only when no test was ordered")
+ void saveNurseData_shouldRouteToDoctorOnlyWithoutOrderedTest() throws Exception {
+ JsonObject request = nurseRequest();
+ request.getAsJsonObject("visitDetails").getAsJsonObject("investigation").add("laboratoryList",
+ new com.google.gson.JsonArray());
+
+ service.saveNCDCareNurseData(request, AUTHORIZATION);
+
+ verify(commonBenStatusFlowServiceImpl).updateBenFlowNurseAfterNurseActivity(any(), anyLong(), anyLong(),
+ anyString(), anyString(), eq((short) 9), eq((short) 1), eq((short) 0), anyShort(), anyShort(),
+ anyLong(), any(), anyShort(), any(), any());
+ }
+ }
+
+ @Nested
+ @DisplayName("deleteVisitDetails")
+ class DeleteVisitDetailsTests {
+
+ @Test
+ @DisplayName("deleteVisitDetails should remove the complaint, adherence and visit rows")
+ void deleteVisitDetails_shouldRemoveVisitRows() throws Exception {
+ when(benVisitDetailRepo.getVisitCode(BEN_REG_ID, 9)).thenReturn(VISIT_CODE);
+
+ service.deleteVisitDetails(nurseRequest());
+
+ verify(benChiefComplaintRepo).deleteVisitDetails(VISIT_CODE);
+ verify(benAdherenceRepo).deleteVisitDetails(VISIT_CODE);
+ verify(benVisitDetailRepo).deleteVisitDetails(VISIT_CODE);
+ }
+
+ @Test
+ @DisplayName("deleteVisitDetails should do nothing when no visit was created")
+ void deleteVisitDetails_shouldDoNothingWithoutVisit() throws Exception {
+ when(benVisitDetailRepo.getVisitCode(BEN_REG_ID, 9)).thenReturn(null);
+
+ service.deleteVisitDetails(nurseRequest());
+
+ verify(benVisitDetailRepo, never()).deleteVisitDetails(anyLong());
+ }
+
+ @Test
+ @DisplayName("deleteVisitDetails should do nothing for a request without visit details")
+ void deleteVisitDetails_shouldDoNothingWithoutVisitDetails() throws Exception {
+ service.deleteVisitDetails(json("{}"));
+
+ verify(benVisitDetailRepo, never()).deleteVisitDetails(anyLong());
+ }
+ }
+
+ @Nested
+ @DisplayName("saveBenVisitDetails")
+ class SaveVisitDetailsTests {
+
+ @Test
+ @DisplayName("saveBenVisitDetails should return the new visit id and code")
+ void saveBenVisitDetails_shouldReturnVisitIdAndCode() throws Exception {
+ Map result = service.saveBenVisitDetails(
+ nurseRequest().getAsJsonObject("visitDetails"), utility());
+
+ assertEquals(VISIT_ID, result.get("visitID"));
+ assertEquals(VISIT_CODE, result.get("visitCode"));
+ }
+
+ @Test
+ @DisplayName("saveBenVisitDetails should return nothing when the visit was already recorded")
+ void saveBenVisitDetails_shouldReturnNothingForAlreadyRecordedVisit() throws Exception {
+ when(commonNurseServiceImpl.getMaxCurrentdate(anyLong(), anyString(), anyString())).thenReturn(1);
+
+ assertTrue(service.saveBenVisitDetails(nurseRequest().getAsJsonObject("visitDetails"), utility())
+ .isEmpty());
+ }
+
+ @Test
+ @DisplayName("saveBenVisitDetails should return nothing for a payload without visit details")
+ void saveBenVisitDetails_shouldReturnNothingWithoutVisitDetails() throws Exception {
+ assertTrue(service.saveBenVisitDetails(json("{}"), utility()).isEmpty());
+ }
+
+ @Test
+ @DisplayName("saveBenVisitDetails should skip the adherence and investigation when they are absent")
+ void saveBenVisitDetails_shouldSkipAbsentAdherenceAndInvestigation() throws Exception {
+ JsonObject payload = json("{\"visitDetails\":{\"beneficiaryRegID\":11,\"visitReason\":\"New\","
+ + "\"visitCategory\":\"NCD care\"}}");
+
+ assertEquals(VISIT_ID, service.saveBenVisitDetails(payload, utility()).get("visitID"));
+ verify(commonNurseServiceImpl, never()).saveBenAdherenceDetails(any());
+ }
+ }
+
+ @Nested
+ @DisplayName("saveBenNCDCareHistoryDetails")
+ class SaveHistoryDetailsTests {
+
+ @Test
+ @DisplayName("saveBenNCDCareHistoryDetails should succeed when no history section was captured")
+ void saveHistory_shouldSucceedWithoutCapturedSections() throws Exception {
+ assertEquals(1L, service.saveBenNCDCareHistoryDetails(json("{}"), VISIT_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("saveBenNCDCareHistoryDetails should store every captured history section")
+ void saveHistory_shouldStoreCapturedSections() throws Exception {
+ when(commonNurseServiceImpl.saveBenPastHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenComorbidConditions(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenMedicationHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveFemaleObstetricHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenMenstrualHistory(any())).thenReturn(1);
+ when(commonNurseServiceImpl.saveBenFamilyHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.savePersonalHistory(any())).thenReturn(1);
+ when(commonNurseServiceImpl.saveAllergyHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveChildOptionalVaccineDetail(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveImmunizationHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveChildDevelopmentHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveChildFeedingHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.savePerinatalHistory(any())).thenReturn(1L);
+
+ JsonObject history = json("{\"pastHistory\":{},\"comorbidConditions\":{},"
+ + "\"medicationHistory\":{\"medicationHistoryList\":[{\"currentMedication\":\"Metformin\"}]},"
+ + "\"femaleObstetricHistory\":{},\"menstrualHistory\":{},\"familyHistory\":{},"
+ + "\"personalHistory\":{},\"allergyHistory\":{},\"childVaccineDetails\":{},"
+ + "\"immunizationHistory\":{},\"developmentHistory\":{},\"childFeedingDetails\":{},"
+ + "\"perinatalHistroy\":{}}");
+
+ assertEquals(1L, service.saveBenNCDCareHistoryDetails(history, VISIT_ID, VISIT_CODE));
+ verify(commonNurseServiceImpl).saveBenPastHistory(any());
+ verify(commonNurseServiceImpl).saveBenComorbidConditions(any());
+ }
+
+ @Test
+ @DisplayName("saveBenNCDCareHistoryDetails should report a failure when a section could not be stored")
+ void saveHistory_shouldReportFailureWhenSectionNotStored() throws Exception {
+ when(commonNurseServiceImpl.saveBenPastHistory(any())).thenReturn(null);
+
+ assertNull(service.saveBenNCDCareHistoryDetails(json("{\"pastHistory\":{}}"), VISIT_ID, VISIT_CODE));
+ }
+ }
+
+ @Nested
+ @DisplayName("saveBenNCDCareVitalDetails")
+ class SaveVitalDetailsTests {
+
+ @Test
+ @DisplayName("saveBenNCDCareVitalDetails should store the anthropometry and the physical vitals")
+ void saveVitals_shouldStoreAnthropometryAndPhysicalVitals() throws Exception {
+ assertEquals(1L, service.saveBenNCDCareVitalDetails(json("{\"height_cm\":170}"), VISIT_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("saveBenNCDCareVitalDetails should report a failure when the anthropometry was not stored")
+ void saveVitals_shouldReportFailureWhenAnthropometryNotStored() throws Exception {
+ when(commonNurseServiceImpl.saveBeneficiaryPhysicalAnthropometryDetails(any())).thenReturn(null);
+
+ assertNull(service.saveBenNCDCareVitalDetails(json("{}"), VISIT_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("saveBenNCDCareVitalDetails should report nothing for a null payload")
+ void saveVitals_shouldReportNothingForNullPayload() throws Exception {
+ assertNull(service.saveBenNCDCareVitalDetails(null, VISIT_ID, VISIT_CODE));
+ }
+ }
+
+ @Nested
+ @DisplayName("read endpoints")
+ class ReadTests {
+
+ @Test
+ @DisplayName("getBenVisitDetailsFrmNurseNCDCare should assemble the visit, adherence and investigations")
+ void getVisitDetails_shouldAssembleVisitSections() {
+ when(commonNurseServiceImpl.getBenAdherence(BEN_REG_ID, VISIT_CODE)).thenReturn("{}");
+ when(commonNurseServiceImpl.getLabTestOrders(BEN_REG_ID, VISIT_CODE)).thenReturn("{}");
+
+ String result = service.getBenVisitDetailsFrmNurseNCDCare(BEN_REG_ID, VISIT_CODE);
+
+ assertTrue(result.contains("NCDCareNurseVisitDetail"));
+ assertTrue(result.contains("BenAdherence"));
+ assertTrue(result.contains("Investigation"));
+ }
+
+ @Test
+ @DisplayName("getBenNCDCareHistoryDetails should assemble every stored history section")
+ void getHistoryDetails_shouldAssembleStoredHistorySections() {
+ when(commonNurseServiceImpl.getPastHistoryData(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(new com.iemr.tm.data.anc.BenMedHistory());
+ when(commonNurseServiceImpl.getFeedingHistory(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(new com.iemr.tm.data.anc.ChildFeedingDetails());
+
+ String result = service.getBenNCDCareHistoryDetails(BEN_REG_ID, VISIT_CODE);
+
+ assertTrue(result.contains("PastHistory"));
+ assertTrue(result.contains("FeedingHistory"));
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryVitalDetails should assemble the anthropometry and the physical vitals")
+ void getVitalDetails_shouldAssembleVitalSections() {
+ when(commonNurseServiceImpl.getBeneficiaryPhysicalAnthropometryDetails(BEN_REG_ID, VISIT_CODE))
+ .thenReturn("{}");
+ when(commonNurseServiceImpl.getBeneficiaryPhysicalVitalDetails(BEN_REG_ID, VISIT_CODE)).thenReturn("{}");
+
+ String result = service.getBeneficiaryVitalDetails(BEN_REG_ID, VISIT_CODE);
+
+ assertTrue(result.contains("benAnthropometryDetail"));
+ assertTrue(result.contains("benPhysicalVitalDetail"));
+ }
+
+ @Test
+ @DisplayName("getBenNCDCareNurseData should assemble the vitals and the history")
+ void getNurseData_shouldAssembleVitalsAndHistory() {
+ String result = service.getBenNCDCareNurseData(BEN_REG_ID, VISIT_CODE);
+
+ assertTrue(result.contains("vitals"));
+ assertTrue(result.contains("history"));
+ }
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorNCDCare should assemble the whole doctor case record")
+ void getCaseRecord_shouldAssembleDoctorCaseRecord() throws Exception {
+ when(commonNurseServiceImpl.getGraphicalTrendData(BEN_REG_ID, "ncdCare")).thenReturn(new HashMap<>());
+
+ String result = service.getBenCaseRecordFromDoctorNCDCare(BEN_REG_ID, VISIT_CODE);
+
+ assertTrue(result.contains("findings"));
+ assertTrue(result.contains("diagnosis"));
+ assertTrue(result.contains("prescription"));
+ assertTrue(result.contains("LabReport"));
+ assertTrue(result.contains("GraphData"));
+ }
+ }
+
+ @Nested
+ @DisplayName("saveDoctorData")
+ class SaveDoctorDataTests
+
+ {
+ private JsonObject doctorRequest() {
+ return json("{" + "\"beneficiaryRegID\":11,\"benVisitID\":3,\"visitCode\":22,\"providerServiceMapID\":9,"
+ + "\"createdBy\":\"doctor1\",\"doctorSignatureFlag\":true,"
+ + "\"findings\":{},"
+ + "\"diagnosis\":{\"specialistDiagnosis\":\"NCD follow up\","
+ + " \"provisionalDiagnosisList\":[{\"term\":\"Diabetes\",\"conceptID\":\"73211009\"}]},"
+ + "\"investigation\":{\"laboratoryList\":[{\"testID\":1}]},"
+ + "\"prescription\":[{\"drugID\":1,\"formName\":\"Tablet\"}],"
+ + "\"refer\":{\"referredToInstituteID\":1}" + "}");
+ }
+
+ @BeforeEach
+ void stubDoctorCollaborators() throws Exception {
+ when(commonDoctorServiceImpl.saveDocFindings(any())).thenReturn(1);
+ when(commonNurseServiceImpl.savePrescriptionDetailsAndGetPrescriptionID(any(), any(), any(), any(), any(),
+ any(), any(), any(), any(), any())).thenReturn(4L);
+ when(ncdCareDoctorServiceImpl.saveNCDDiagnosisData(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenInvestigation(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenPrescribedDrugsList(any())).thenReturn(1);
+ when(commonDoctorServiceImpl.saveBenReferDetails(any())).thenReturn(1L);
+ when(commonDoctorServiceImpl.updateBenFlowtableAfterDocDataSave(any(), anyBoolean(), anyBoolean(), any(),
+ anyBoolean())).thenReturn(1);
+ }
+
+ @Test
+ @DisplayName("saveDoctorData should save the findings, diagnosis, tests, drugs and referral")
+ void saveDoctorData_shouldSaveWholeCaseRecord() throws Exception {
+ assertEquals(1L, service.saveDoctorData(doctorRequest(), AUTHORIZATION));
+
+ verify(commonDoctorServiceImpl).saveDocFindings(any());
+ verify(ncdCareDoctorServiceImpl).saveNCDDiagnosisData(any());
+ verify(commonNurseServiceImpl).saveBenInvestigation(any());
+ verify(commonNurseServiceImpl).saveBenPrescribedDrugsList(any());
+ verify(commonDoctorServiceImpl).saveBenReferDetails(any());
+ }
+
+ @Test
+ @DisplayName("saveDoctorData should succeed for a case record with only an investigation section")
+ void saveDoctorData_shouldSucceedForMinimalCaseRecord() throws Exception {
+ assertEquals(1L, service.saveDoctorData(json("{\"beneficiaryRegID\":11,\"investigation\":{}}"),
+ AUTHORIZATION));
+
+ verify(commonDoctorServiceImpl, never()).saveDocFindings(any());
+ verify(commonNurseServiceImpl, never()).saveBenPrescribedDrugsList(any());
+ }
+
+ @Test
+ @DisplayName("saveDoctorData should return nothing for a null request")
+ void saveDoctorData_shouldReturnNothingForNullRequest() throws Exception {
+ assertNull(service.saveDoctorData(null, AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveDoctorData should fail when a section could not be stored")
+ void saveDoctorData_shouldFailWhenSectionNotStored() throws Exception {
+ when(ncdCareDoctorServiceImpl.saveNCDDiagnosisData(any())).thenReturn(0L);
+
+ assertThrows(RuntimeException.class, () -> service.saveDoctorData(doctorRequest(), AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveDoctorData should fail when the beneficiary flow could not be advanced")
+ void saveDoctorData_shouldFailWhenFlowNotAdvanced() throws Exception {
+ when(commonDoctorServiceImpl.updateBenFlowtableAfterDocDataSave(any(), anyBoolean(), anyBoolean(), any(),
+ anyBoolean())).thenReturn(0);
+
+ assertThrows(RuntimeException.class, () -> service.saveDoctorData(doctorRequest(), AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveDoctorData should notify a scheduled teleconsultation by SMS")
+ void saveDoctorData_shouldNotifyScheduledTeleconsultation() throws Exception {
+ when(commonServiceImpl.createTcRequest(any(), any(), anyString()))
+ .thenReturn(teleconsultationRequest(false));
+
+ service.saveDoctorData(doctorRequest(), AUTHORIZATION);
+
+ verify(sMSGatewayServiceImpl).smsSenderGateway(eq("schedule"), anyLong(), anyInt(), anyLong(), any(),
+ any(), anyString(), any(), eq(AUTHORIZATION));
+ }
+ }
+
+ @Nested
+ @DisplayName("update endpoints")
+ class UpdateTests {
+
+ @Test
+ @DisplayName("updateBenHistoryDetails should succeed when no history section was captured")
+ void updateHistory_shouldSucceedWithoutCapturedSections() throws Exception {
+ assertEquals(1, service.updateBenHistoryDetails(json("{}")));
+ }
+
+ @Test
+ @DisplayName("updateBenVitalDetails should confirm the update when both sections changed")
+ void updateVitals_shouldConfirmUpdate() throws Exception {
+ when(commonNurseServiceImpl.updateANCAnthropometryDetails(any())).thenReturn(1);
+ when(commonNurseServiceImpl.updateANCPhysicalVitalDetails(any())).thenReturn(1);
+
+ assertEquals(1, service.updateBenVitalDetails(json("{\"height_cm\":170}")));
+ }
+
+ @Test
+ @DisplayName("updateBenVitalDetails should report no change when a section did not change")
+ void updateVitals_shouldReportNoChangeWhenSectionUnchanged() throws Exception {
+ when(commonNurseServiceImpl.updateANCAnthropometryDetails(any())).thenReturn(1);
+ when(commonNurseServiceImpl.updateANCPhysicalVitalDetails(any())).thenReturn(0);
+
+ assertEquals(0, service.updateBenVitalDetails(json("{}")));
+ }
+
+ @Test
+ @DisplayName("updateBenVitalDetails should succeed for a null payload")
+ void updateVitals_shouldSucceedForNullPayload() throws Exception {
+ assertEquals(1, service.updateBenVitalDetails(null));
+ }
+
+ @Test
+ @DisplayName("updateNCDCareDoctorData should return nothing for a null request")
+ void updateDoctorData_shouldReturnNothingForNullRequest() throws Exception {
+ assertNull(service.updateNCDCareDoctorData(null, AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("updateNCDCareDoctorData should update the whole case record")
+ void updateDoctorData_shouldUpdateWholeCaseRecord() throws Exception {
+ when(commonDoctorServiceImpl.updateDocFindings(any())).thenReturn(1);
+ when(ncdCareDoctorServiceImpl.updateBenNCDCareDiagnosis(any())).thenReturn(1);
+ when(commonNurseServiceImpl.saveBenInvestigation(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenPrescribedDrugsList(any())).thenReturn(1);
+ when(commonDoctorServiceImpl.updateBenReferDetails(any())).thenReturn(1L);
+ when(commonDoctorServiceImpl.updateBenFlowtableAfterDocDataUpdate(any(), anyBoolean(), anyBoolean(), any(),
+ anyBoolean())).thenReturn(1);
+
+ JsonObject request = json("{" + "\"beneficiaryRegID\":11,\"benVisitID\":3,\"visitCode\":22,"
+ + "\"findings\":{},\"diagnosis\":{\"prescriptionID\":4,\"specialistDiagnosis\":\"NCD\"},"
+ + "\"investigation\":{\"laboratoryList\":[{\"testID\":1}]},"
+ + "\"prescription\":[{\"drugID\":1,\"formName\":\"Tablet\"}],"
+ + "\"refer\":{\"referredToInstituteID\":1}" + "}");
+
+ assertEquals(1L, service.updateNCDCareDoctorData(request, AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("updateNCDCareDoctorData should fail when the beneficiary flow could not be advanced")
+ void updateDoctorData_shouldFailWhenFlowNotAdvanced() throws Exception {
+ when(commonDoctorServiceImpl.updateBenFlowtableAfterDocDataUpdate(any(), anyBoolean(), anyBoolean(), any(),
+ anyBoolean())).thenReturn(0);
+
+ assertThrows(RuntimeException.class, () -> service.updateNCDCareDoctorData(
+ json("{\"beneficiaryRegID\":11,\"investigation\":{}}"), AUTHORIZATION));
+ }
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("NCD care captured-section updates")
+ class CapturedSectionUpdateTests {
+
+ @Test
+ @DisplayName("updateBenHistoryDetails should update every captured history section")
+ void updateBenHistoryDetails_shouldUpdateEveryCapturedSection() throws Exception {
+ org.junit.jupiter.api.Assertions.assertDoesNotThrow(() -> service.updateBenHistoryDetails(
+ com.google.gson.JsonParser.parseString("{\"pastHistory\":{},\"comorbidConditions\":{},\"medicationHistory\":{},\"personalHistory\":{},\"familyHistory\":{},\"menstrualHistory\":{},\"femaleObstetricHistory\":{},\"immunizationHistory\":{},\"childVaccineDetails\":{},\"developmentHistory\":{},\"feedingHistory\":{},\"perinatalHistroy\":{},\"allergyHistory\":{}}").getAsJsonObject()));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/ncdscreening/NCDSCreeningDoctorServiceImplTest.java b/src/test/java/com/iemr/tm/service/ncdscreening/NCDSCreeningDoctorServiceImplTest.java
new file mode 100644
index 00000000..3a350c14
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/ncdscreening/NCDSCreeningDoctorServiceImplTest.java
@@ -0,0 +1,75 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.ncdscreening;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.quickConsultation.PrescriptionDetailRepo;
+import com.iemr.tm.service.common.transaction.CommonDoctorServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonNurseServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonServiceImpl;
+import com.iemr.tm.service.tele_consultation.SMSGatewayServiceImpl;
+import com.iemr.tm.service.tele_consultation.TeleConsultationServiceImpl;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("NCDSCreeningDoctorServiceImpl Test Suite")
+class NCDSCreeningDoctorServiceImplTest {
+
+ @Mock
+ private PrescriptionDetailRepo prescriptionDetailRepo;
+ @Mock
+ private CommonDoctorServiceImpl commonDoctorServiceImpl;
+ @Mock
+ private TeleConsultationServiceImpl teleConsultationServiceImpl;
+ @Mock
+ private CommonNurseServiceImpl commonNurseServiceImpl;
+ @Mock
+ private CommonServiceImpl commonServiceImpl;
+ @Mock
+ private SMSGatewayServiceImpl sMSGatewayServiceImpl;
+
+ @InjectMocks
+ private NCDSCreeningDoctorServiceImpl service;
+
+ @Test
+ @DisplayName("updateDoctorData should reject a request that carries no beneficiary details")
+ void updateDoctorData_shouldRejectRequestWithoutBeneficiaryDetails() {
+ assertThrows(RuntimeException.class, () -> service.updateDoctorData(new com.google.gson.JsonObject(), "{}"));
+ }
+
+ @Test
+ @DisplayName("getNCDDiagnosisData should answer for a well formed request")
+ void getNCDDiagnosisData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getNCDDiagnosisData(11L, 11L));
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/ncdscreening/NCDScreeningNurseServiceImplTest.java b/src/test/java/com/iemr/tm/service/ncdscreening/NCDScreeningNurseServiceImplTest.java
new file mode 100644
index 00000000..856f73a0
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/ncdscreening/NCDScreeningNurseServiceImplTest.java
@@ -0,0 +1,65 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.ncdscreening;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.nurse.ncdscreening.NCDScreeningRepo;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("NCDScreeningNurseServiceImpl Test Suite")
+class NCDScreeningNurseServiceImplTest {
+
+ @Mock
+ private NCDScreeningRepo ncdScreeningRepo;
+
+ @InjectMocks
+ private NCDScreeningNurseServiceImpl service;
+
+ @Test
+ @DisplayName("saveNCDScreeningDetails should answer for a well formed request")
+ void saveNCDScreeningDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.saveNCDScreeningDetails(org.mockito.Mockito.mock(com.iemr.tm.data.ncdScreening.NCDScreening.class)));
+ }
+
+ @Test
+ @DisplayName("getNCDScreeningDetails should answer for a well formed request")
+ void getNCDScreeningDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getNCDScreeningDetails(11L, 11L));
+ }
+
+ @Test
+ @DisplayName("updateNCDScreeningDetails should answer for a well formed request")
+ void updateNCDScreeningDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateNCDScreeningDetails(org.mockito.Mockito.mock(com.iemr.tm.data.ncdScreening.NCDScreening.class)));
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/ncdscreening/NCDScreeningServiceImplTest.java b/src/test/java/com/iemr/tm/service/ncdscreening/NCDScreeningServiceImplTest.java
new file mode 100644
index 00000000..5d5cddfd
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/ncdscreening/NCDScreeningServiceImplTest.java
@@ -0,0 +1,633 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.ncdscreening;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyShort;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.sql.Timestamp;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.iemr.tm.data.nurse.CommonUtilityClass;
+import com.iemr.tm.data.tele_consultation.TeleconsultationRequestOBJ;
+import com.iemr.tm.repo.benFlowStatus.BeneficiaryFlowStatusRepo;
+import com.iemr.tm.repo.nurse.BenVisitDetailRepo;
+import com.iemr.tm.repo.nurse.anc.BenAdherenceRepo;
+import com.iemr.tm.repo.nurse.ncdscreening.IDRSDataRepo;
+import com.iemr.tm.repo.quickConsultation.BenChiefComplaintRepo;
+import com.iemr.tm.repo.quickConsultation.PrescriptionDetailRepo;
+import com.iemr.tm.service.benFlowStatus.CommonBenStatusFlowServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonDoctorServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonNurseServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonServiceImpl;
+import com.iemr.tm.service.labtechnician.LabTechnicianServiceImpl;
+import com.iemr.tm.service.tele_consultation.SMSGatewayServiceImpl;
+import com.iemr.tm.service.tele_consultation.TeleConsultationServiceImpl;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("NCDScreeningServiceImpl Test Suite")
+class NCDScreeningServiceImplTest {
+
+ private static final String AUTHORIZATION = "Bearer session-token";
+ private static final Long BEN_REG_ID = 11L;
+ private static final Long VISIT_ID = 3L;
+ private static final Long VISIT_CODE = 22L;
+
+ private static final String FULL_HISTORY = "{\"pastHistory\":{},\"comorbidConditions\":{},"
+ + "\"medicationHistory\":{\"medicationHistoryList\":[{\"currentMedication\":\"Iron\"}]},"
+ + "\"personalHistory\":{},\"familyHistory\":{},\"menstrualHistory\":{},"
+ + "\"femaleObstetricHistory\":{},\"immunizationHistory\":{},\"childVaccineDetails\":{},"
+ + "\"developmentHistory\":{},\"feedingHistory\":{},\"perinatalHistroy\":{},"
+ + "\"physicalActivityHistory\":{}}";
+
+ /** One answered IDRS question, as the screening form submits it. */
+ private static final String IDRS_REQUEST = "{\"beneficiaryRegID\":11,\"questionArray\":"
+ + "[{\"idrsQuestionID\":1,\"answer\":\"Yes\",\"question\":\"Family history?\","
+ + " \"diseaseQuestionType\":\"Diabetes\"}]}";
+
+ @Mock
+ private NCDScreeningNurseServiceImpl ncdScreeningNurseServiceImpl;
+ @Mock
+ private CommonNurseServiceImpl commonNurseServiceImpl;
+ @Mock
+ private CommonBenStatusFlowServiceImpl commonBenStatusFlowServiceImpl;
+ @Mock
+ private BeneficiaryFlowStatusRepo beneficiaryFlowStatusRepo;
+ @Mock
+ private LabTechnicianServiceImpl labTechnicianServiceImpl;
+ @Mock
+ private CommonDoctorServiceImpl commonDoctorServiceImpl;
+ @Mock
+ private CommonServiceImpl commonServiceImpl;
+ @Mock
+ private TeleConsultationServiceImpl teleConsultationServiceImpl;
+ @Mock
+ private BenVisitDetailRepo benVisitDetailRepo;
+ @Mock
+ private SMSGatewayServiceImpl sMSGatewayServiceImpl;
+ @Mock
+ private PrescriptionDetailRepo prescriptionDetailRepo;
+ @Mock
+ private NCDSCreeningDoctorServiceImpl ncdSCreeningDoctorServiceImpl;
+ @Mock
+ private IDRSDataRepo iDrsDataRepo;
+ @Mock
+ private BenChiefComplaintRepo benChiefComplaintRepo;
+ @Mock
+ private BenAdherenceRepo benAdherenceRepo;
+
+ @InjectMocks
+ private NCDScreeningServiceImpl service;
+
+ private JsonObject json(String raw) {
+ return JsonParser.parseString(raw).getAsJsonObject();
+ }
+
+ private JsonObject nurseRequest() {
+ return json("{" + "\"beneficiaryRegID\":11,\"providerServiceMapID\":9,\"vanID\":7,\"sessionID\":1,"
+ + "\"benFlowID\":5,\"createdBy\":\"nurse1\","
+ + "\"visitDetails\":{"
+ + " \"visitDetails\":{\"beneficiaryRegID\":11,\"visitReason\":\"New Chief Complaint\","
+ + " \"visitCategory\":\"NCD screening\"},"
+ + " \"chiefComplaints\":[{\"chiefComplaintID\":3}]"
+ + "},"
+ + "\"historyDetails\":" + FULL_HISTORY + ",\"vitalDetails\":{\"height_cm\":170}}");
+ }
+
+ private CommonUtilityClass utility() {
+ CommonUtilityClass utility = new CommonUtilityClass();
+ utility.setBeneficiaryRegID(BEN_REG_ID);
+ utility.setVanID(7);
+ utility.setSessionID(1);
+ utility.setProviderServiceMapID(9);
+ utility.setCreatedBy("nurse1");
+ return utility;
+ }
+
+ private TeleconsultationRequestOBJ teleconsultationRequest(boolean walkIn) {
+ TeleconsultationRequestOBJ request = new TeleconsultationRequestOBJ();
+ request.setWalkIn(walkIn);
+ request.setUserID(42);
+ request.setSpecializationID(2);
+ request.setTmRequestID(8L);
+ request.setAllocationDate(new Timestamp(1_700_000_000_000L));
+ return request;
+ }
+
+ @BeforeEach
+ @DisplayName("Wire the collaborators that every save path needs")
+ void setUp() throws Exception {
+ when(commonNurseServiceImpl.getMaxCurrentdate(anyLong(), anyString(), anyString())).thenReturn(0);
+ when(commonNurseServiceImpl.saveBeneficiaryVisitDetails(any())).thenReturn(VISIT_ID);
+ when(commonNurseServiceImpl.generateVisitCode(anyLong(), any(), any())).thenReturn(VISIT_CODE);
+ when(commonNurseServiceImpl.saveBenChiefComplaints(any())).thenReturn(1);
+ when(commonNurseServiceImpl.saveBeneficiaryPhysicalAnthropometryDetails(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBeneficiaryPhysicalVitalDetails(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenPastHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenComorbidConditions(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenMedicationHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.savePersonalHistory(any())).thenReturn(1);
+ when(commonNurseServiceImpl.saveAllergyHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenFamilyHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenFamilyHistoryNCDScreening(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenMenstrualHistory(any())).thenReturn(1);
+ when(commonNurseServiceImpl.saveFemaleObstetricHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveImmunizationHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveChildOptionalVaccineDetail(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveChildDevelopmentHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveChildFeedingHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.savePerinatalHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.savePhysicalActivity(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveIDRS(any())).thenReturn(1L);
+ when(commonBenStatusFlowServiceImpl.updateBenFlowNurseAfterNurseActivity(any(), anyLong(), anyLong(),
+ anyString(), anyString(), anyShort(), anyShort(), anyShort(), anyShort(), anyShort(), anyLong(), any(),
+ anyShort(), any(), any())).thenReturn(1);
+ }
+
+ @Nested
+ @DisplayName("saveNCDScreeningNurseData")
+ class SaveNurseDataTests {
+
+ @Test
+ @DisplayName("saveNCDScreeningNurseData should save the visit, history and vitals")
+ void saveNurseData_shouldSaveEverySection() throws Exception {
+ String result = service.saveNCDScreeningNurseData(nurseRequest(), AUTHORIZATION);
+
+ assertTrue(result.contains("Data saved successfully"));
+ assertTrue(result.contains("\"visitCode\":\"22\""));
+ }
+
+ @Test
+ @DisplayName("saveNCDScreeningNurseData should report an already saved visit")
+ void saveNurseData_shouldReportAlreadySavedVisit() throws Exception {
+ when(commonNurseServiceImpl.getMaxCurrentdate(anyLong(), anyString(), anyString())).thenReturn(1);
+
+ assertTrue(service.saveNCDScreeningNurseData(nurseRequest(), AUTHORIZATION)
+ .contains("Data already saved"));
+ }
+
+ @Test
+ @DisplayName("saveNCDScreeningNurseData should reject a request without visit details")
+ void saveNurseData_shouldRejectRequestWithoutVisitDetails() {
+ assertThrows(Exception.class, () -> service.saveNCDScreeningNurseData(json("{}"), AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveNCDScreeningNurseData should fail when the visit could not be created")
+ void saveNurseData_shouldFailWhenVisitNotCreated() throws Exception {
+ when(commonNurseServiceImpl.saveBeneficiaryVisitDetails(any())).thenReturn(0L);
+
+ assertThrows(RuntimeException.class,
+ () -> service.saveNCDScreeningNurseData(nurseRequest(), AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveNCDScreeningNurseData should notify a scheduled teleconsultation by SMS")
+ void saveNurseData_shouldNotifyScheduledTeleconsultation() throws Exception {
+ when(commonServiceImpl.createTcRequest(any(), any(), anyString()))
+ .thenReturn(teleconsultationRequest(false));
+
+ service.saveNCDScreeningNurseData(nurseRequest(), AUTHORIZATION);
+
+ verify(sMSGatewayServiceImpl).smsSenderGateway(eq("schedule"), anyLong(), anyInt(), anyLong(), any(),
+ anyString(), anyString(), any(), eq(AUTHORIZATION));
+ }
+ }
+
+ @Nested
+ @DisplayName("deleteVisitDetails")
+ class DeleteVisitDetailsTests {
+
+ @Test
+ @DisplayName("deleteVisitDetails should remove the visit rows for a created visit")
+ void deleteVisitDetails_shouldRemoveVisitRows() throws Exception {
+ when(benVisitDetailRepo.getVisitCode(BEN_REG_ID, 9)).thenReturn(VISIT_CODE);
+
+ service.deleteVisitDetails(nurseRequest());
+
+ verify(benVisitDetailRepo).deleteVisitDetails(VISIT_CODE);
+ }
+
+ @Test
+ @DisplayName("deleteVisitDetails should do nothing for a request without visit details")
+ void deleteVisitDetails_shouldDoNothingWithoutVisitDetails() throws Exception {
+ service.deleteVisitDetails(json("{}"));
+
+ verify(benVisitDetailRepo, never()).deleteVisitDetails(anyLong());
+ }
+ }
+
+ @Nested
+ @DisplayName("nurse section saves")
+ class SectionSaveTests {
+
+ @Test
+ @DisplayName("saveBenVisitDetails should return the new visit id and code")
+ void saveBenVisitDetails_shouldReturnVisitIdAndCode() throws Exception {
+ Map result = service.saveBenVisitDetails(nurseRequest().getAsJsonObject("visitDetails"),
+ utility());
+
+ assertEquals(VISIT_ID, result.get("visitID"));
+ assertEquals(VISIT_CODE, result.get("visitCode"));
+ }
+
+ @Test
+ @DisplayName("saveBenVisitDetails should return nothing when the visit was already recorded")
+ void saveBenVisitDetails_shouldReturnNothingForAlreadyRecordedVisit() throws Exception {
+ when(commonNurseServiceImpl.getMaxCurrentdate(anyLong(), anyString(), anyString())).thenReturn(1);
+
+ assertTrue(service.saveBenVisitDetails(nurseRequest().getAsJsonObject("visitDetails"), utility())
+ .isEmpty());
+ }
+
+ @Test
+ @DisplayName("saveNCDScreeningVitalDetails should store the anthropometry and the physical vitals")
+ void saveScreeningVitals_shouldStoreAnthropometryAndPhysicalVitals() throws Exception {
+ assertEquals(1L, service.saveNCDScreeningVitalDetails(
+ json("{\"ncdScreeningDetails\":{\"height_cm\":170}}"), VISIT_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("saveNCDScreeningVitalDetails should report a failure when the physical vitals were not stored")
+ void saveScreeningVitals_shouldReportFailureWhenPhysicalVitalsNotStored() throws Exception {
+ when(commonNurseServiceImpl.saveBeneficiaryPhysicalVitalDetails(any())).thenReturn(null);
+
+ assertNull(service.saveNCDScreeningVitalDetails(json("{\"ncdScreeningDetails\":{}}"), VISIT_ID,
+ VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("saveBenNCDCareHistoryDetails should store every captured history section")
+ void saveHistory_shouldStoreCapturedSections() throws Exception {
+ assertEquals(1L, service.saveBenNCDCareHistoryDetails(json(FULL_HISTORY), VISIT_ID, VISIT_CODE));
+ verify(commonNurseServiceImpl).saveBenPastHistory(any());
+ }
+
+ @Test
+ @DisplayName("saveidrsDetails should store the captured IDRS answers")
+ void saveIdrsDetails_shouldStoreCapturedAnswers() throws Exception {
+ assertEquals(1L, service.saveidrsDetails(json(IDRS_REQUEST), VISIT_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("saveidrsDetails should succeed when no IDRS answer was captured")
+ void saveIdrsDetails_shouldSucceedWithoutCapturedAnswers() throws Exception {
+ assertEquals(1L, service.saveidrsDetails(json("{}"), VISIT_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("savePhysicalActivityDetails should store the captured physical activity")
+ void savePhysicalActivity_shouldStoreCapturedActivity() throws Exception {
+ assertEquals(1L, service.savePhysicalActivityDetails(
+ json("{\"physicalActivityHistory\":{\"physicalActivityType\":\"Moderate\"}}"), VISIT_ID,
+ VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("savePhysicalActivityDetails should succeed when no physical activity was captured")
+ void savePhysicalActivity_shouldSucceedWithoutCapturedActivity() throws Exception {
+ assertEquals(1L, service.savePhysicalActivityDetails(json("{}"), VISIT_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("saveBenNCDCareVitalDetails should store the anthropometry and the physical vitals")
+ void saveCareVitals_shouldStoreAnthropometryAndPhysicalVitals() throws Exception {
+ assertEquals(1L, service.saveBenNCDCareVitalDetails(json("{\"height_cm\":170}"), VISIT_ID, VISIT_CODE));
+ }
+ }
+
+ @Nested
+ @DisplayName("read endpoints")
+ class ReadTests {
+
+ @Test
+ @DisplayName("getNCDScreeningDetails should assemble the screening, anthropometry and vitals")
+ void getScreeningDetails_shouldAssembleScreeningSections() {
+ when(ncdScreeningNurseServiceImpl.getNCDScreeningDetails(BEN_REG_ID, VISIT_CODE)).thenReturn("{}");
+ when(commonNurseServiceImpl.getBeneficiaryPhysicalAnthropometryDetails(BEN_REG_ID, VISIT_CODE))
+ .thenReturn("{}");
+ when(commonNurseServiceImpl.getBeneficiaryPhysicalVitalDetails(BEN_REG_ID, VISIT_CODE)).thenReturn("{}");
+
+ String result = service.getNCDScreeningDetails(BEN_REG_ID, VISIT_CODE);
+
+ assertTrue(result.contains("ncdScreeningDetails"));
+ assertTrue(result.contains("anthropometryDetails"));
+ }
+
+ @Test
+ @DisplayName("getNCDScreeningDetails should return an empty payload when a section is missing")
+ void getScreeningDetails_shouldReturnEmptyPayloadWhenSectionMissing() {
+ when(ncdScreeningNurseServiceImpl.getNCDScreeningDetails(BEN_REG_ID, VISIT_CODE)).thenReturn(null);
+
+ assertEquals("{}", service.getNCDScreeningDetails(BEN_REG_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("getNcdScreeningVisitCnt should report the next screening visit number")
+ void getVisitCount_shouldReportNextVisitNumber() {
+ when(beneficiaryFlowStatusRepo.getNcdScreeningVisitCount(BEN_REG_ID)).thenReturn(2L);
+
+ assertTrue(service.getNcdScreeningVisitCnt(BEN_REG_ID).contains("3"));
+ }
+
+ @Test
+ @DisplayName("getBenVisitDetailsFrmNurseNCDScreening should assemble the visit and the chief complaints")
+ void getVisitDetails_shouldAssembleVisitSections() {
+ when(commonNurseServiceImpl.getBenChiefComplaints(BEN_REG_ID, VISIT_CODE)).thenReturn("[]");
+
+ assertTrue(service.getBenVisitDetailsFrmNurseNCDScreening(BEN_REG_ID, VISIT_CODE)
+ .contains("BenChiefComplaints"));
+ }
+
+ @Test
+ @DisplayName("getBenHistoryDetails should assemble the stored screening history")
+ void getHistoryDetails_shouldAssembleStoredSections() {
+ when(commonNurseServiceImpl.getFamilyHistoryDetail(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(new com.iemr.tm.data.anc.BenFamilyHistory());
+
+ assertTrue(service.getBenHistoryDetails(BEN_REG_ID, VISIT_CODE).contains("FamilyHistory"));
+ }
+
+ @Test
+ @DisplayName("getBenIdrsDetailsFrmNurse should assemble the stored IDRS answers")
+ void getIdrsDetails_shouldAssembleStoredAnswers() {
+ when(commonNurseServiceImpl.getBeneficiaryIdrsDetails(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(new com.iemr.tm.data.ncdScreening.IDRSData());
+
+ assertTrue(service.getBenIdrsDetailsFrmNurse(BEN_REG_ID, VISIT_CODE).contains("IDRSDetail"));
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryVitalDetails should assemble the anthropometry and the physical vitals")
+ void getVitalDetails_shouldAssembleVitalSections() {
+ when(commonNurseServiceImpl.getBeneficiaryPhysicalAnthropometryDetails(BEN_REG_ID, VISIT_CODE))
+ .thenReturn("{}");
+ when(commonNurseServiceImpl.getBeneficiaryPhysicalVitalDetails(BEN_REG_ID, VISIT_CODE)).thenReturn("{}");
+
+ assertTrue(service.getBeneficiaryVitalDetails(BEN_REG_ID, VISIT_CODE).contains("benAnthropometryDetail"));
+ }
+
+ @Test
+ @DisplayName("getBenNCDScreeningNurseData should assemble the nurse captured sections")
+ void getNurseData_shouldAssembleNurseSections() {
+ assertTrue(service.getBenNCDScreeningNurseData(BEN_REG_ID, VISIT_CODE).length() > 0);
+ }
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorNCDScreening should assemble the whole doctor case record")
+ void getCaseRecord_shouldAssembleDoctorCaseRecord() throws Exception {
+ when(commonNurseServiceImpl.getGraphicalTrendData(anyLong(), anyString())).thenReturn(new HashMap<>());
+
+ String result = service.getBenCaseRecordFromDoctorNCDScreening(BEN_REG_ID, VISIT_CODE);
+
+ assertTrue(result.contains("findings"));
+ assertTrue(result.contains("LabReport"));
+ }
+ }
+
+ @Nested
+ @DisplayName("saveDoctorData")
+ class SaveDoctorDataTests {
+
+ private JsonObject doctorRequest() {
+ return json("{" + "\"beneficiaryRegID\":11,\"benVisitID\":3,\"visitCode\":22,\"providerServiceMapID\":9,"
+ + "\"createdBy\":\"doctor1\",\"doctorSignatureFlag\":true,\"findings\":{},"
+ + "\"diagnosis\":{\"specialistDiagnosis\":\"Diabetes suspect\"},"
+ + "\"investigation\":{\"laboratoryList\":[{\"testID\":1}]},"
+ + "\"prescription\":[{\"drugID\":1,\"formName\":\"Tablet\"}],"
+ + "\"refer\":{\"referredToInstituteID\":1}" + "}");
+ }
+
+ @BeforeEach
+ void stubDoctorCollaborators() throws Exception {
+ when(commonDoctorServiceImpl.saveDocFindings(any())).thenReturn(1);
+ when(commonNurseServiceImpl.savePrescriptionDetailsAndGetPrescriptionID(any(), any(), any(), any(), any(),
+ any(), any(), any(), any(), any())).thenReturn(4L);
+ when(commonNurseServiceImpl.saveBenPrescription(any())).thenReturn(4L);
+ when(commonNurseServiceImpl.saveBenInvestigation(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenPrescribedDrugsList(any())).thenReturn(1);
+ when(commonDoctorServiceImpl.saveBenReferDetails(any())).thenReturn(1L);
+ when(commonDoctorServiceImpl.updateBenFlowtableAfterDocDataSave(any(), anyBoolean(), anyBoolean(), any(),
+ anyBoolean())).thenReturn(1);
+ }
+
+ @Test
+ @DisplayName("saveDoctorData should save the findings, diagnosis, tests, drugs and referral")
+ void saveDoctorData_shouldSaveWholeCaseRecord() throws Exception {
+ assertEquals(1L, service.saveDoctorData(doctorRequest(), AUTHORIZATION));
+
+ verify(commonDoctorServiceImpl).saveDocFindings(any());
+ verify(commonNurseServiceImpl).saveBenInvestigation(any());
+ }
+
+ @Test
+ @DisplayName("saveDoctorData should return nothing for a null request")
+ void saveDoctorData_shouldReturnNothingForNullRequest() throws Exception {
+ assertNull(service.saveDoctorData(null, AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("saveDoctorData should fail when the beneficiary flow could not be advanced")
+ void saveDoctorData_shouldFailWhenFlowNotAdvanced() throws Exception {
+ when(commonDoctorServiceImpl.updateBenFlowtableAfterDocDataSave(any(), anyBoolean(), anyBoolean(), any(),
+ anyBoolean())).thenReturn(0);
+
+ assertThrows(RuntimeException.class, () -> service.saveDoctorData(doctorRequest(), AUTHORIZATION));
+ }
+ }
+
+ @Nested
+ @DisplayName("update endpoints")
+ class UpdateTests {
+
+ @Test
+ @DisplayName("updateNurseNCDScreeningDetails should update the captured screening details")
+ void updateScreeningDetails_shouldUpdateCapturedDetails() throws Exception {
+ when(ncdScreeningNurseServiceImpl.updateNCDScreeningDetails(any())).thenReturn(1);
+
+ assertEquals(1, service.updateNurseNCDScreeningDetails(json("{\"beneficiaryRegID\":11}")));
+ }
+
+ @Test
+ @DisplayName("updateBenVitalDetails should confirm the update when both sections changed")
+ void updateVitals_shouldConfirmUpdate() throws Exception {
+ when(commonNurseServiceImpl.updateANCAnthropometryDetails(any())).thenReturn(1);
+ when(commonNurseServiceImpl.updateANCPhysicalVitalDetails(any())).thenReturn(1);
+
+ assertEquals(1, service.updateBenVitalDetails(json("{\"height_cm\":170}")));
+ }
+
+ @Test
+ @DisplayName("updateBenVitalDetails should report no change when a section did not change")
+ void updateVitals_shouldReportNoChangeWhenSectionUnchanged() throws Exception {
+ when(commonNurseServiceImpl.updateANCAnthropometryDetails(any())).thenReturn(0);
+
+ assertEquals(0, service.updateBenVitalDetails(json("{}")));
+ }
+
+ @Test
+ @DisplayName("UpdateIDRSScreen should update the captured IDRS answers")
+ void updateIdrsScreen_shouldUpdateCapturedAnswers() throws Exception {
+ assertEquals(1L, service.UpdateIDRSScreen(json("{\"idrsDetails\":" + IDRS_REQUEST + "}")));
+ }
+
+ @Test
+ @DisplayName("UpdateIDRSScreen should return nothing when no IDRS answer was captured")
+ void updateIdrsScreen_shouldReturnNothingWithoutCapturedAnswers() throws Exception {
+ assertNull(service.UpdateIDRSScreen(json("{}")));
+ }
+
+ @Test
+ @DisplayName("UpdateNCDScreeningHistory should update the captured screening history")
+ void updateScreeningHistory_shouldUpdateCapturedHistory() throws Exception {
+ when(commonNurseServiceImpl.updateBenFamilyHistoryNCDScreening(any())).thenReturn(1);
+ when(commonNurseServiceImpl.updateBenPhysicalActivityHistoryNCDScreening(any())).thenReturn(1);
+
+ assertEquals(1, service.UpdateNCDScreeningHistory(
+ json("{\"familyHistory\":{},\"physicalActivityHistory\":{},\"personalHistory\":{}}")));
+ }
+
+ @Test
+ @DisplayName("UpdateNCDScreeningHistory should report no change when no history section was captured")
+ void updateScreeningHistory_shouldReportNoChangeWithoutCapturedHistory() throws Exception {
+ assertEquals(0, service.UpdateNCDScreeningHistory(json("{}")));
+ }
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("IDRS suspected and confirmed diseases")
+ class IdrsDiseaseTests {
+
+ private static final String WITH_DISEASES = "{\"beneficiaryRegID\":11,\"visitCode\":22,\"idrsScore\":40,"
+ + "\"suspectArray\":[\"Diabetes\",\"Hypertension\"],"
+ + "\"confirmArray\":[\"Diabetes\"],"
+ + "\"questionArray\":[{\"idrsQuestionID\":1,\"answer\":\"Yes\",\"question\":\"Family history?\","
+ + " \"diseaseQuestionType\":\"Diabetes\"},"
+ + " {\"idrsQuestionID\":2,\"answer\":\"No\",\"question\":\"Waist?\","
+ + " \"diseaseQuestionType\":\"Diabetes\"}]}";
+
+ private static final String WITHOUT_QUESTIONS = "{\"beneficiaryRegID\":11,\"visitCode\":22,\"idrsScore\":40,"
+ + "\"suspectArray\":[\"Diabetes\",\"Hypertension\"],\"confirmArray\":[\"Diabetes\"]}";
+
+ @Test
+ @DisplayName("saveidrsDetails should flatten the suspected and confirmed diseases per answered question")
+ void saveIdrs_shouldFlattenDiseasesPerQuestion() throws Exception {
+ assertEquals(1L, service.saveidrsDetails(json(WITH_DISEASES), VISIT_ID, VISIT_CODE));
+
+ org.mockito.ArgumentCaptor captor =
+ org.mockito.ArgumentCaptor.forClass(com.iemr.tm.data.ncdScreening.IDRSData.class);
+ org.mockito.Mockito.verify(commonNurseServiceImpl, org.mockito.Mockito.atLeastOnce())
+ .saveIDRS(captor.capture());
+ com.iemr.tm.data.ncdScreening.IDRSData saved = captor.getValue();
+ assertEquals("Diabetes,Hypertension", saved.getSuspectedDisease());
+ assertEquals("Diabetes", saved.getConfirmedDisease());
+ }
+
+ @Test
+ @DisplayName("saveidrsDetails should flatten the diseases when no question was answered")
+ void saveIdrs_shouldFlattenDiseasesWithoutQuestions() throws Exception {
+ assertEquals(1L, service.saveidrsDetails(json(WITHOUT_QUESTIONS), VISIT_ID, VISIT_CODE));
+
+ org.mockito.ArgumentCaptor captor =
+ org.mockito.ArgumentCaptor.forClass(com.iemr.tm.data.ncdScreening.IDRSData.class);
+ org.mockito.Mockito.verify(commonNurseServiceImpl).saveIDRS(captor.capture());
+ assertEquals("Diabetes,Hypertension", captor.getValue().getSuspectedDisease());
+ }
+
+ @Test
+ @DisplayName("UpdateIDRSScreen should update the suspected diseases for each answered question")
+ void updateIdrs_shouldUpdateSuspectedDiseasesPerQuestion() throws Exception {
+ when(iDrsDataRepo.updateSuspectedDiseases(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyString()))
+ .thenReturn(1);
+
+ assertEquals(1L, service.UpdateIDRSScreen(json("{\"idrsDetails\":" + WITH_DISEASES + "}")));
+
+ org.mockito.Mockito.verify(iDrsDataRepo, org.mockito.Mockito.atLeastOnce())
+ .updateSuspectedDiseases(11L, 22L, "Diabetes,Hypertension");
+ }
+
+ @Test
+ @DisplayName("UpdateIDRSScreen should update the diseases and the score when no question was answered")
+ void updateIdrs_shouldUpdateDiseasesAndScoreWithoutQuestions() throws Exception {
+ when(iDrsDataRepo.updateConfirmedDiseases(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyString()))
+ .thenReturn(1);
+ when(iDrsDataRepo.updateSuspectedDiseases(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyString()))
+ .thenReturn(1);
+ when(iDrsDataRepo.updateIdrsScore(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyInt()))
+ .thenReturn(1);
+
+ assertEquals(1L, service.UpdateIDRSScreen(json("{\"idrsDetails\":" + WITHOUT_QUESTIONS + "}")));
+
+ org.mockito.Mockito.verify(iDrsDataRepo).updateConfirmedDiseases(11L, 22L, "Diabetes");
+ org.mockito.Mockito.verify(iDrsDataRepo, org.mockito.Mockito.atLeastOnce())
+ .updateIdrsScore(org.mockito.ArgumentMatchers.eq(11L), org.mockito.ArgumentMatchers.eq(22L),
+ org.mockito.ArgumentMatchers.anyInt());
+ }
+
+ @Test
+ @DisplayName("UpdateIDRSScreen should report nothing when no disease could be updated")
+ void updateIdrs_shouldReportNothingWhenNoDiseaseUpdated() throws Exception {
+ when(iDrsDataRepo.updateConfirmedDiseases(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyString()))
+ .thenReturn(0);
+ when(iDrsDataRepo.updateSuspectedDiseases(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyString()))
+ .thenReturn(0);
+ when(iDrsDataRepo.updateIdrsScore(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyInt()))
+ .thenReturn(0);
+
+ assertNull(service.UpdateIDRSScreen(json("{\"idrsDetails\":" + WITHOUT_QUESTIONS + "}")));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/nurse/NurseServiceImplTest.java b/src/test/java/com/iemr/tm/service/nurse/NurseServiceImplTest.java
new file mode 100644
index 00000000..613f482c
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/nurse/NurseServiceImplTest.java
@@ -0,0 +1,54 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.nurse;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.nurse.BenVisitDetailRepo;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("NurseServiceImpl Test Suite")
+class NurseServiceImplTest {
+
+ @Mock
+ private BenVisitDetailRepo benVisitDetailRepo;
+
+ @InjectMocks
+ private NurseServiceImpl service;
+
+
+ @Test
+ @DisplayName("getBeneficiaryVisitHistory should answer for a well formed request")
+ void getBeneficiaryVisitHistory_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBeneficiaryVisitHistory(11L));
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/nurse/vitals/AnthropometryVitalsServiceImplTest.java b/src/test/java/com/iemr/tm/service/nurse/vitals/AnthropometryVitalsServiceImplTest.java
new file mode 100644
index 00000000..9aa99640
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/nurse/vitals/AnthropometryVitalsServiceImplTest.java
@@ -0,0 +1,53 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.nurse.vitals;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.nurse.BenAnthropometryRepo;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("AnthropometryVitalsServiceImpl Test Suite")
+class AnthropometryVitalsServiceImplTest {
+
+ @Mock
+ private BenAnthropometryRepo benAnthropometryRepo;
+
+ @InjectMocks
+ private AnthropometryVitalsServiceImpl service;
+
+ @Test
+ @DisplayName("getBeneficiaryHeightDetails should answer for a well formed request")
+ void getBeneficiaryHeightDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBeneficiaryHeightDetails(11L));
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/patientApp/master/CommonPatientAppMasterServiceImplTest.java b/src/test/java/com/iemr/tm/service/patientApp/master/CommonPatientAppMasterServiceImplTest.java
new file mode 100644
index 00000000..705bc61a
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/patientApp/master/CommonPatientAppMasterServiceImplTest.java
@@ -0,0 +1,427 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.patientApp.master;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.benFlowStatus.BeneficiaryFlowStatusRepo;
+import com.iemr.tm.repo.doctor.ChiefComplaintMasterRepo;
+import com.iemr.tm.repo.masterrepo.covid19.CovidContactHistoryMasterRepo;
+import com.iemr.tm.repo.masterrepo.covid19.CovidRecommnedationMasterRepo;
+import com.iemr.tm.repo.masterrepo.covid19.CovidSymptomsMasterRepo;
+import com.iemr.tm.repo.nurse.BenVisitDetailRepo;
+import com.iemr.tm.repo.quickBlox.QuickBloxRepo;
+import com.iemr.tm.service.common.transaction.CommonNurseServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonServiceImpl;
+import com.iemr.tm.service.covid19.Covid19ServiceImpl;
+import com.iemr.tm.service.generalOPD.GeneralOPDDoctorServiceImpl;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("CommonPatientAppMasterServiceImpl Test Suite")
+class CommonPatientAppMasterServiceImplTest {
+
+ @Mock
+ private CovidSymptomsMasterRepo covidSymptomsMasterRepo;
+ @Mock
+ private CovidContactHistoryMasterRepo covidContactHistoryMasterRepo;
+ @Mock
+ private CovidRecommnedationMasterRepo covidRecommnedationMasterRepo;
+ @Mock
+ private ChiefComplaintMasterRepo chiefComplaintMasterRepo;
+ @Mock
+ private CommonNurseServiceImpl commonNurseServiceImpl;
+ @Mock
+ private Covid19ServiceImpl covid19ServiceImpl;
+ @Mock
+ private BenVisitDetailRepo benVisitDetailRepo;
+ @Mock
+ private CommonServiceImpl commonServiceImpl;
+ @Mock
+ private BeneficiaryFlowStatusRepo beneficiaryFlowStatusRepo;
+ @Mock
+ private GeneralOPDDoctorServiceImpl generalOPDDoctorServiceImpl;
+ @Mock
+ private QuickBloxRepo quickBloxRepo;
+
+ @InjectMocks
+ private CommonPatientAppMasterServiceImpl service;
+
+ @Test
+ @DisplayName("getChiefComplaintsMaster should answer for a well formed request")
+ void getChiefComplaintsMaster_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getChiefComplaintsMaster(9, 9, "{}"));
+ }
+
+ @Test
+ @DisplayName("getCovidMaster should answer for a well formed request")
+ void getCovidMaster_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getCovidMaster(9, 9, "{}"));
+ }
+
+ @Test
+ @DisplayName("saveCovidScreeningData should reject a request that carries no beneficiary details")
+ void saveCovidScreeningData_shouldRejectRequestWithoutBeneficiaryDetails() {
+ assertThrows(RuntimeException.class, () -> service.saveCovidScreeningData("{}"));
+ }
+
+ @Test
+ @DisplayName("savechiefComplaintsData should reject a request that carries no beneficiary details")
+ void savechiefComplaintsData_shouldRejectRequestWithoutBeneficiaryDetails() {
+ assertThrows(RuntimeException.class, () -> service.savechiefComplaintsData("{}"));
+ }
+
+ @Test
+ @DisplayName("bookTCSlotData should reject a request that carries no beneficiary details")
+ void bookTCSlotData_shouldRejectRequestWithoutBeneficiaryDetails() {
+ assertThrows(RuntimeException.class, () -> service.bookTCSlotData("{}", "{}"));
+ }
+
+ @Test
+ @DisplayName("getPatientEpisodeData should reject a request that carries no beneficiary details")
+ void getPatientEpisodeData_shouldRejectRequestWithoutBeneficiaryDetails() {
+ assertThrows(RuntimeException.class, () -> service.getPatientEpisodeData("{}"));
+ }
+
+ @Test
+ @DisplayName("getPatientBookedSlots should reject a request that carries no beneficiary details")
+ void getPatientBookedSlots_shouldRejectRequestWithoutBeneficiaryDetails() {
+ assertThrows(RuntimeException.class, () -> service.getPatientBookedSlots("{}"));
+ }
+
+ @Test
+ @DisplayName("saveSpecialistDiagnosisData should reject a request that carries no beneficiary details")
+ void saveSpecialistDiagnosisData_shouldRejectRequestWithoutBeneficiaryDetails() {
+ assertThrows(RuntimeException.class, () -> service.saveSpecialistDiagnosisData("{}"));
+ }
+
+ @Test
+ @DisplayName("getSpecialistDiagnosisData should reject a request that carries no beneficiary details")
+ void getSpecialistDiagnosisData_shouldRejectRequestWithoutBeneficiaryDetails() {
+ assertThrows(RuntimeException.class, () -> service.getSpecialistDiagnosisData("{}"));
+ }
+
+ @Test
+ @DisplayName("getPatientsLast_3_Episode should reject a request that carries no beneficiary details")
+ void getPatientsLast_3_Episode_shouldRejectRequestWithoutBeneficiaryDetails() {
+ assertThrows(RuntimeException.class, () -> service.getPatientsLast_3_Episode("{}"));
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("patient app episodes and diagnosis")
+ class PatientAppEpisodeTests {
+
+ private static final String BEN_REQUEST = "{\"beneficiaryRegID\":11,\"beneficiaryID\":7,\"vanID\":7,"
+ + "\"visitCode\":22,\"benVisitID\":3,\"providerServiceMapID\":9,\"createdBy\":\"patient1\","
+ + "\"parkingPlaceID\":8,\"specialistDiagnosis\":\"Covid suspect\",\"benFlowID\":5,"
+ + "\"visitReason\":\"New Chief Complaint\",\"visitCategory\":\"COVID-19 Screening\","
+ + "\"isCovidFlowDone\":true,"
+ + "\"chiefComplaints\":{\"pastIllness\":[{\"illnessTypeID\":3,\"illnessType\":\"Fever\"}]},"
+ + "\"covidDetails\":{\"suspectedStatusUI\":\"Suspected\"}}";
+
+ @org.junit.jupiter.api.BeforeEach
+ void stubVisitCreation() {
+ org.mockito.Mockito.when(commonNurseServiceImpl
+ .saveBeneficiaryVisitDetails(org.mockito.ArgumentMatchers.any())).thenReturn(3L);
+ org.mockito.Mockito.when(commonNurseServiceImpl.generateVisitCode(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any())).thenReturn(22L);
+ }
+
+ @Test
+ @DisplayName("getChiefComplaintsMaster should render the chief complaint master")
+ void getChiefComplaintsMaster_shouldRenderMaster() {
+ org.mockito.Mockito.when(chiefComplaintMasterRepo.getChiefComplaintMaster())
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getChiefComplaintsMaster(1, 9, "Female"));
+ }
+
+ @Test
+ @DisplayName("getCovidMaster should render the covid screening master")
+ void getCovidMaster_shouldRenderMaster() {
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getCovidMaster(1, 9, "Female"));
+ }
+
+ @Test
+ @DisplayName("saveCovidScreeningData should create the episode and store the screening feedback")
+ void saveCovidScreening_shouldCreateEpisodeAndStoreFeedback() throws Exception {
+ org.mockito.Mockito.when(covid19ServiceImpl.saveCovidDetails(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(1);
+
+ org.junit.jupiter.api.Assertions.assertNotNull(service.saveCovidScreeningData(BEN_REQUEST));
+ }
+
+ @Test
+ @DisplayName("saveCovidScreeningData should still answer when the screening feedback was not stored")
+ void saveCovidScreening_shouldStillAnswerWhenFeedbackNotStored() throws Exception {
+ org.mockito.Mockito.when(covid19ServiceImpl.saveCovidDetails(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(null);
+
+ org.junit.jupiter.api.Assertions.assertNotNull(service.saveCovidScreeningData(BEN_REQUEST));
+ }
+
+ @Test
+ @DisplayName("saveCovidScreeningData should fail when the episode could not be created")
+ void saveCovidScreening_shouldFailWhenEpisodeNotCreated() {
+ org.mockito.Mockito.when(commonNurseServiceImpl
+ .saveBeneficiaryVisitDetails(org.mockito.ArgumentMatchers.any())).thenReturn(null);
+
+ org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class,
+ () -> service.saveCovidScreeningData(BEN_REQUEST));
+ }
+
+ @Test
+ @DisplayName("savechiefComplaintsData should create the episode and store the complaints")
+ void saveChiefComplaints_shouldCreateEpisodeAndStoreComplaints() throws Exception {
+ org.mockito.Mockito.when(commonNurseServiceImpl
+ .saveBenChiefComplaints(org.mockito.ArgumentMatchers.any())).thenReturn(1);
+
+ org.junit.jupiter.api.Assertions.assertNotNull(service.savechiefComplaintsData(BEN_REQUEST));
+ }
+
+
+ @Test
+ @DisplayName("getPatientEpisodeData should assemble the covid details and the complaints")
+ void getPatientEpisodeData_shouldAssembleEpisode() throws Exception {
+ org.mockito.Mockito.when(covid19ServiceImpl.getBenVisitDetailsFrmNurseCovid19(11L, 22L))
+ .thenReturn("{\"covidDetails\":\"{}\"}");
+ org.mockito.Mockito.when(commonNurseServiceImpl.getBenChiefComplaints(11L, 22L)).thenReturn("[]");
+
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getPatientEpisodeData(BEN_REQUEST));
+ }
+
+ @Test
+ @DisplayName("saveSpecialistDiagnosisData should store the diagnosis and advance the flow")
+ void saveSpecialistDiagnosis_shouldStoreAndAdvanceFlow() throws Exception {
+ org.mockito.Mockito.when(commonNurseServiceImpl.saveBenPrescription(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(4L);
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.updateBenFlowStatusAfterSpecialistMobileAPP(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any())).thenReturn(1);
+
+ org.junit.jupiter.api.Assertions.assertEquals(4L, service.saveSpecialistDiagnosisData(BEN_REQUEST));
+ }
+
+ @Test
+ @DisplayName("saveSpecialistDiagnosisData should fail when the flow could not be advanced")
+ void saveSpecialistDiagnosis_shouldFailWhenFlowNotAdvanced() {
+ org.mockito.Mockito.when(commonNurseServiceImpl.saveBenPrescription(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(4L);
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.updateBenFlowStatusAfterSpecialistMobileAPP(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any())).thenReturn(0);
+
+ org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class,
+ () -> service.saveSpecialistDiagnosisData(BEN_REQUEST));
+ }
+
+ @Test
+ @DisplayName("getSpecialistDiagnosisData should return the recorded diagnosis")
+ void getSpecialistDiagnosis_shouldReturnRecordedDiagnosis() throws Exception {
+ org.mockito.Mockito.when(generalOPDDoctorServiceImpl.getGeneralOPDDiagnosisDetails(11L, 22L))
+ .thenReturn("{}");
+
+ org.junit.jupiter.api.Assertions.assertEquals("{}", service.getSpecialistDiagnosisData(BEN_REQUEST));
+ }
+
+ @Test
+ @DisplayName("getSpecialistDiagnosisData should fail when no diagnosis was recorded")
+ void getSpecialistDiagnosis_shouldFailWithoutRecordedDiagnosis() {
+ org.mockito.Mockito.when(generalOPDDoctorServiceImpl.getGeneralOPDDiagnosisDetails(11L, 22L))
+ .thenReturn(null);
+
+ org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class,
+ () -> service.getSpecialistDiagnosisData(BEN_REQUEST));
+ }
+
+ @Test
+ @DisplayName("getPatientsLast_3_Episode should render the three most recent episodes")
+ void getLastThreeEpisodes_shouldRenderRecentEpisodes() throws Exception {
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getPatientsLast_3_Episode(BEN_REQUEST));
+ }
+
+ @Test
+ @DisplayName("getPatientBookedSlots should render the slots booked for the beneficiary")
+ void getBookedSlots_shouldRenderBookedSlots() throws Exception {
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getPatientBookedSlots(BEN_REQUEST));
+ }
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("teleconsultation slot booking and booked slots")
+ class SlotBookingTests {
+
+ private static final String BOOK_REQUEST = "{\"beneficiaryRegID\":11,\"beneficiaryID\":7,\"visitCode\":22,"
+ + "\"createdBy\":\"9999999999\",\"firstName\":\"Asha\",\"lastName\":\"Devi\",\"age\":31,"
+ + "\"ageUnits\":\"years\",\"genderID\":2,\"genderName\":\"Female\",\"districtID\":31,"
+ + "\"districtName\":\"Nagpur\",\"villageId\":41,\"villageName\":\"Kamptee\","
+ + "\"providerServiceMapID\":9,\"vanID\":7,\"parkingPlaceID\":8}";
+
+ private com.iemr.tm.data.nurse.BeneficiaryVisitDetail visit() {
+ com.iemr.tm.data.nurse.BeneficiaryVisitDetail visit = new com.iemr.tm.data.nurse.BeneficiaryVisitDetail();
+ visit.setBeneficiaryRegID(11L);
+ visit.setBenVisitID(3L);
+ visit.setVisitCode(22L);
+ visit.setVisitReason("New Chief Complaint");
+ visit.setVisitCategory("COVID-19 Screening");
+ visit.setVisitNo((short) 1);
+ return visit;
+ }
+
+ private com.iemr.tm.data.tele_consultation.TeleconsultationRequestOBJ tcRequest(Long tmRequestID) {
+ com.iemr.tm.data.tele_consultation.TeleconsultationRequestOBJ tcRequest =
+ new com.iemr.tm.data.tele_consultation.TeleconsultationRequestOBJ();
+ tcRequest.setUserID(41);
+ tcRequest.setSpecializationID(3);
+ tcRequest.setTmRequestID(tmRequestID);
+ tcRequest.setAllocationDate(new java.sql.Timestamp(System.currentTimeMillis()));
+ return tcRequest;
+ }
+
+ @Test
+ @DisplayName("bookTCSlotData should create the beneficiary flow record for the booked slot")
+ void bookTCSlot_shouldCreateFlowRecord() throws Exception {
+ org.mockito.Mockito.when(benVisitDetailRepo.getVisitDetails(11L, 22L)).thenReturn(visit());
+ org.mockito.Mockito.when(commonServiceImpl.createTcRequest(org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.anyString()))
+ .thenReturn(tcRequest(77L));
+ com.iemr.tm.data.benFlowStatus.BeneficiaryFlowStatus saved =
+ new com.iemr.tm.data.benFlowStatus.BeneficiaryFlowStatus();
+ saved.setBenFlowID(5L);
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.save(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(saved);
+
+ org.junit.jupiter.api.Assertions.assertEquals(1,
+ service.bookTCSlotData(BOOK_REQUEST, "Bearer session-token"));
+
+ org.mockito.ArgumentCaptor captor =
+ org.mockito.ArgumentCaptor.forClass(com.iemr.tm.data.benFlowStatus.BeneficiaryFlowStatus.class);
+ org.mockito.Mockito.verify(beneficiaryFlowStatusRepo).save(captor.capture());
+ org.junit.jupiter.api.Assertions.assertEquals("Asha Devi", captor.getValue().getBenName());
+ org.junit.jupiter.api.Assertions.assertEquals((short) 1, captor.getValue().getSpecialist_flag());
+ }
+
+ @Test
+ @DisplayName("bookTCSlotData should fail when the flow record could not be created")
+ void bookTCSlot_shouldFailWhenFlowRecordNotCreated() throws Exception {
+ org.mockito.Mockito.when(benVisitDetailRepo.getVisitDetails(11L, 22L)).thenReturn(visit());
+ org.mockito.Mockito.when(commonServiceImpl.createTcRequest(org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.anyString()))
+ .thenReturn(tcRequest(77L));
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.save(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(null);
+
+ org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class,
+ () -> service.bookTCSlotData(BOOK_REQUEST, "Bearer session-token"));
+ }
+
+ @Test
+ @DisplayName("bookTCSlotData should fail when the slot could not be booked")
+ void bookTCSlot_shouldFailWhenSlotNotBooked() throws Exception {
+ org.mockito.Mockito.when(benVisitDetailRepo.getVisitDetails(11L, 22L)).thenReturn(visit());
+ org.mockito.Mockito.when(commonServiceImpl.createTcRequest(org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.anyString()))
+ .thenReturn(tcRequest(null));
+
+ org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class,
+ () -> service.bookTCSlotData(BOOK_REQUEST, "Bearer session-token"));
+ }
+
+ @Test
+ @DisplayName("bookTCSlotData should fail when the beneficiary has no visit")
+ void bookTCSlot_shouldFailWithoutVisit() {
+ org.mockito.Mockito.when(benVisitDetailRepo.getVisitDetails(11L, 22L)).thenReturn(null);
+
+ org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class,
+ () -> service.bookTCSlotData(BOOK_REQUEST, "Bearer session-token"));
+ }
+
+ private com.iemr.tm.data.benFlowStatus.BeneficiaryFlowStatus bookedSlot(Long beneficiaryRegID) {
+ com.iemr.tm.data.benFlowStatus.BeneficiaryFlowStatus slot =
+ new com.iemr.tm.data.benFlowStatus.BeneficiaryFlowStatus();
+ slot.setBeneficiaryRegID(beneficiaryRegID);
+ slot.setBeneficiaryID(7L);
+ slot.setBenName("Asha Devi");
+ slot.setAge("31 years");
+ slot.setGenderName("Female");
+ slot.settCSpecialistUserID(41);
+ slot.settCRequestDate(new java.sql.Timestamp(System.currentTimeMillis()));
+ return slot;
+ }
+
+ private void stubQuickblox() {
+ com.iemr.tm.data.quickBlox.Quickblox quickblox =
+ new com.iemr.tm.data.quickBlox.Quickblox();
+ quickblox.setSpecialistBenQuickbloxID(1L);
+ quickblox.setSpecialistBenQuickBloxPass("qb-pass");
+ org.mockito.Mockito.when(quickBloxRepo.getQuickbloxIds(org.mockito.ArgumentMatchers.anyInt()))
+ .thenReturn(quickblox);
+ }
+
+ @Test
+ @DisplayName("getPatientBookedSlots should return the slot booked for this beneficiary")
+ void getBookedSlots_shouldReturnSlotForThisBeneficiary() throws Exception {
+ stubQuickblox();
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.getBenSlotDetails("9999999999"))
+ .thenReturn(new java.util.ArrayList<>(java.util.Arrays.asList(bookedSlot(11L))));
+
+ String result = service.getPatientBookedSlots(BOOK_REQUEST);
+
+ org.junit.jupiter.api.Assertions.assertTrue(result.contains("\"isAnyActiveSlotForSameBen\":true"));
+ org.junit.jupiter.api.Assertions.assertTrue(result.contains("qb-pass"));
+ }
+
+ @Test
+ @DisplayName("getPatientBookedSlots should return the last slot when none belongs to this beneficiary")
+ void getBookedSlots_shouldReturnLastSlotForAnotherBeneficiary() throws Exception {
+ stubQuickblox();
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.getBenSlotDetails("9999999999"))
+ .thenReturn(new java.util.ArrayList<>(
+ java.util.Arrays.asList(bookedSlot(99L), bookedSlot(98L))));
+
+ String result = service.getPatientBookedSlots(BOOK_REQUEST);
+
+ org.junit.jupiter.api.Assertions.assertTrue(result.contains("\"isAnyActiveSlotForSameBen\":false"));
+ org.junit.jupiter.api.Assertions.assertTrue(result.contains("patientDetails"));
+ }
+
+ @Test
+ @DisplayName("getPatientBookedSlots should report no active slot")
+ void getBookedSlots_shouldReportNoActiveSlot() throws Exception {
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.getBenSlotDetails("9999999999"))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertTrue(
+ service.getPatientBookedSlots(BOOK_REQUEST).contains("\"isAnyActiveSlot\":false"));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/pnc/PNCDoctorServiceImplTest.java b/src/test/java/com/iemr/tm/service/pnc/PNCDoctorServiceImplTest.java
new file mode 100644
index 00000000..b510e6f3
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/pnc/PNCDoctorServiceImplTest.java
@@ -0,0 +1,235 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.pnc;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.nurse.pnc.PNCDiagnosisRepo;
+import com.iemr.tm.repo.quickConsultation.PrescriptionDetailRepo;
+import com.iemr.tm.service.common.transaction.CommonDoctorServiceImpl;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("PNCDoctorServiceImpl Test Suite")
+class PNCDoctorServiceImplTest {
+
+ @Mock
+ private PNCDiagnosisRepo pncDiagnosisRepo;
+ @Mock
+ private PrescriptionDetailRepo prescriptionDetailRepo;
+ @Mock
+ private CommonDoctorServiceImpl commonDoctorServiceImpl;
+
+ @InjectMocks
+ private PNCDoctorServiceImpl service;
+
+ @Test
+ @DisplayName("saveBenPNCDiagnosis should answer for a well formed request")
+ void saveBenPNCDiagnosis_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.saveBenPNCDiagnosis(new com.google.gson.JsonObject(), 11L));
+ }
+
+ @Test
+ @DisplayName("getPNCDiagnosisDetails should answer for a well formed request")
+ void getPNCDiagnosisDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getPNCDiagnosisDetails(11L, 11L));
+ }
+
+ @Test
+ @DisplayName("updateBenPNCDiagnosis should answer for a well formed request")
+ void updateBenPNCDiagnosis_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateBenPNCDiagnosis(new com.iemr.tm.data.pnc.PNCDiagnosis()));
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("PNC diagnosis")
+ class DiagnosisTests {
+
+ @Test
+ @DisplayName("saveBenPNCDiagnosis should store the diagnosis against the prescription")
+ void saveDiagnosis_shouldStoreAgainstPrescription() throws Exception {
+ com.iemr.tm.data.pnc.PNCDiagnosis stored = new com.iemr.tm.data.pnc.PNCDiagnosis();
+ stored.setID(4L);
+ org.mockito.Mockito.when(pncDiagnosisRepo.save(org.mockito.ArgumentMatchers.any())).thenReturn(stored);
+
+ com.google.gson.JsonObject request = com.google.gson.JsonParser.parseString(
+ "{\"beneficiaryRegID\":11,\"visitCode\":22,\"benVisitID\":3,\"providerServiceMapID\":9,"
+ + "\"createdBy\":\"doctor1\",\"pncDiagnosis\":\"Anaemia\"}").getAsJsonObject();
+
+ org.junit.jupiter.api.Assertions.assertEquals(4L, service.saveBenPNCDiagnosis(request, 5L));
+ }
+
+ @Test
+ @DisplayName("saveBenPNCDiagnosis should report a failure when nothing was stored")
+ void saveDiagnosis_shouldReportFailureWhenNothingStored() throws Exception {
+ org.mockito.Mockito.when(pncDiagnosisRepo.save(org.mockito.ArgumentMatchers.any())).thenReturn(null);
+
+ org.junit.jupiter.api.Assertions.assertNull(service.saveBenPNCDiagnosis(
+ com.google.gson.JsonParser.parseString("{\"beneficiaryRegID\":11}").getAsJsonObject(), 5L));
+ }
+
+ @Test
+ @DisplayName("getPNCDiagnosisDetails should render the stored diagnosis for the visit")
+ void getDiagnosisDetails_shouldRenderStoredDiagnosis() {
+ com.iemr.tm.data.pnc.PNCDiagnosis stored = new com.iemr.tm.data.pnc.PNCDiagnosis();
+ stored.setID(4L);
+ org.mockito.Mockito.when(pncDiagnosisRepo.findByBeneficiaryRegIDAndVisitCode(11L, 22L))
+ .thenReturn(new java.util.ArrayList<>(java.util.Collections.singletonList(stored)));
+
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getPNCDiagnosisDetails(11L, 22L));
+ }
+
+ @Test
+ @DisplayName("getPNCDiagnosisDetails should render an empty payload when the visit has no diagnosis")
+ void getDiagnosisDetails_shouldRenderEmptyPayloadWithoutDiagnosis() {
+ org.mockito.Mockito.when(pncDiagnosisRepo.findByBeneficiaryRegIDAndVisitCode(11L, 22L))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getPNCDiagnosisDetails(11L, 22L));
+ }
+
+ @Test
+ @DisplayName("updateBenPNCDiagnosis should mark an already processed diagnosis as updated")
+ void updateDiagnosis_shouldMarkProcessedAsUpdated() throws Exception {
+ com.iemr.tm.data.pnc.PNCDiagnosis diagnosis = new com.iemr.tm.data.pnc.PNCDiagnosis();
+ diagnosis.setBeneficiaryRegID(11L);
+ diagnosis.setVisitCode(22L);
+ org.mockito.Mockito.when(pncDiagnosisRepo.getPNCDiagnosisStatus(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.any())).thenReturn("P");
+
+ org.junit.jupiter.api.Assertions.assertEquals(0, service.updateBenPNCDiagnosis(diagnosis));
+ }
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("SNOMED diagnosis lists")
+ class SnomedDiagnosisTests {
+
+ private static final String TWO_DIAGNOSES = "{\"beneficiaryRegID\":11,\"visitCode\":22,\"benVisitID\":3,"
+ + "\"createdBy\":\"doctor1\","
+ + "\"provisionalDiagnosisList\":[{\"conceptID\":\"111\",\"term\":\"Anaemia\"},"
+ + " {\"term\":\"Hypertension\"}],"
+ + "\"confirmatoryDiagnosisList\":[{\"conceptID\":\"222\",\"term\":\"Sepsis\"},"
+ + " {\"term\":\"Fever\"}]}";
+
+ @Test
+ @DisplayName("saveBenPNCDiagnosis should flatten both diagnosis lists with their concept ids")
+ void saveDiagnosis_shouldFlattenBothDiagnosisLists() throws Exception {
+ com.iemr.tm.data.pnc.PNCDiagnosis stored = new com.iemr.tm.data.pnc.PNCDiagnosis();
+ stored.setID(4L);
+ org.mockito.Mockito.when(pncDiagnosisRepo.save(org.mockito.ArgumentMatchers.any())).thenReturn(stored);
+
+ org.junit.jupiter.api.Assertions.assertEquals(4L, service.saveBenPNCDiagnosis(
+ com.google.gson.JsonParser.parseString(TWO_DIAGNOSES).getAsJsonObject(), 31L));
+
+ org.mockito.ArgumentCaptor captor =
+ org.mockito.ArgumentCaptor.forClass(com.iemr.tm.data.pnc.PNCDiagnosis.class);
+ org.mockito.Mockito.verify(pncDiagnosisRepo).save(captor.capture());
+ com.iemr.tm.data.pnc.PNCDiagnosis saved = captor.getValue();
+ org.junit.jupiter.api.Assertions.assertEquals(31L, saved.getPrescriptionID());
+ org.junit.jupiter.api.Assertions.assertEquals("Anaemia || Hypertension", saved.getProvisionalDiagnosis());
+ org.junit.jupiter.api.Assertions.assertEquals("111 || N/A", saved.getProvisionalDiagnosisSCTCode());
+ org.junit.jupiter.api.Assertions.assertEquals("Sepsis || Fever", saved.getConfirmatoryDiagnosis());
+ org.junit.jupiter.api.Assertions.assertEquals("222 || N/A", saved.getConfirmatoryDiagnosisSCTCode());
+ }
+
+ @Test
+ @DisplayName("getPNCDiagnosisDetails should expand the stored diagnosis back into concept lists")
+ void getDiagnosisDetails_shouldExpandStoredDiagnosisIntoLists() {
+ com.iemr.tm.data.pnc.PNCDiagnosis stored = new com.iemr.tm.data.pnc.PNCDiagnosis();
+ stored.setProvisionalDiagnosis("Anaemia || Hypertension");
+ stored.setProvisionalDiagnosisSCTCode("111 || N/A");
+ stored.setConfirmatoryDiagnosis("Sepsis || Fever");
+ stored.setConfirmatoryDiagnosisSCTCode("222 || N/A");
+ org.mockito.Mockito.when(pncDiagnosisRepo.findByBeneficiaryRegIDAndVisitCode(11L, 22L))
+ .thenReturn(new java.util.ArrayList<>(java.util.Collections.singletonList(stored)));
+ java.util.ArrayList prescription = new java.util.ArrayList<>();
+ prescription.add(new Object[] { "Ultrasound", "review in a week" });
+ org.mockito.Mockito.when(prescriptionDetailRepo.getExternalinvestigationForVisitCode(11L, 22L))
+ .thenReturn(prescription);
+
+ String result = service.getPNCDiagnosisDetails(11L, 22L);
+
+ org.junit.jupiter.api.Assertions.assertTrue(result.contains("Anaemia"));
+ org.junit.jupiter.api.Assertions.assertTrue(result.contains("Hypertension"));
+ org.junit.jupiter.api.Assertions.assertTrue(result.contains("Sepsis"));
+ org.junit.jupiter.api.Assertions.assertTrue(result.contains("Ultrasound"));
+ org.junit.jupiter.api.Assertions.assertTrue(result.contains("review in a week"));
+ }
+
+ @Test
+ @DisplayName("updateBenPNCDiagnosis should flatten both diagnosis lists before updating")
+ void updateDiagnosis_shouldFlattenBothDiagnosisLists() throws Exception {
+ com.iemr.tm.data.pnc.PNCDiagnosis diagnosis = com.iemr.tm.utils.mapper.InputMapper.gson().fromJson(
+ TWO_DIAGNOSES, com.iemr.tm.data.pnc.PNCDiagnosis.class);
+ org.mockito.Mockito.when(pncDiagnosisRepo.getPNCDiagnosisStatus(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.any())).thenReturn("P");
+ org.mockito.Mockito.when(pncDiagnosisRepo.updatePNCDiagnosis(org.mockito.ArgumentMatchers.anyString(),
+ org.mockito.ArgumentMatchers.anyString(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.eq("U"), org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any())).thenReturn(1);
+
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.updateBenPNCDiagnosis(diagnosis));
+ org.junit.jupiter.api.Assertions.assertEquals("Anaemia || Hypertension",
+ diagnosis.getProvisionalDiagnosis());
+ }
+
+ @Test
+ @DisplayName("updateBenPNCDiagnosis should store a fresh diagnosis when none was recorded before")
+ void updateDiagnosis_shouldStoreFreshDiagnosis() throws Exception {
+ com.iemr.tm.data.pnc.PNCDiagnosis diagnosis = com.iemr.tm.utils.mapper.InputMapper.gson().fromJson(
+ TWO_DIAGNOSES, com.iemr.tm.data.pnc.PNCDiagnosis.class);
+ com.iemr.tm.data.pnc.PNCDiagnosis stored = new com.iemr.tm.data.pnc.PNCDiagnosis();
+ stored.setID(4L);
+ org.mockito.Mockito.when(pncDiagnosisRepo.getPNCDiagnosisStatus(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.any())).thenReturn(null);
+ org.mockito.Mockito.when(pncDiagnosisRepo.save(org.mockito.ArgumentMatchers.any())).thenReturn(stored);
+
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.updateBenPNCDiagnosis(diagnosis));
+ }
+
+ @Test
+ @DisplayName("saveBenPNCDiagnosis should store an empty diagnosis when no concept was picked")
+ void saveDiagnosis_shouldStoreEmptyDiagnosisWithoutConcepts() throws Exception {
+ com.iemr.tm.data.pnc.PNCDiagnosis stored = new com.iemr.tm.data.pnc.PNCDiagnosis();
+ stored.setID(4L);
+ org.mockito.Mockito.when(pncDiagnosisRepo.save(org.mockito.ArgumentMatchers.any())).thenReturn(stored);
+
+ org.junit.jupiter.api.Assertions.assertEquals(4L, service.saveBenPNCDiagnosis(
+ com.google.gson.JsonParser.parseString("{\"beneficiaryRegID\":11,\"visitCode\":22}")
+ .getAsJsonObject(), 31L));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/pnc/PNCNurseServiceImplTest.java b/src/test/java/com/iemr/tm/service/pnc/PNCNurseServiceImplTest.java
new file mode 100644
index 00000000..1fb7d889
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/pnc/PNCNurseServiceImplTest.java
@@ -0,0 +1,71 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.pnc;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.nurse.pnc.PNCCareRepo;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("PNCNurseServiceImpl Test Suite")
+class PNCNurseServiceImplTest {
+
+ @Mock
+ private PNCCareRepo pncCareRepo;
+
+ @InjectMocks
+ private PNCNurseServiceImpl service;
+
+ @Test
+ @DisplayName("saveBenPncCareDetails should answer for a well formed request")
+ void saveBenPncCareDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.saveBenPncCareDetails(org.mockito.Mockito.mock(com.iemr.tm.data.pnc.PNCCare.class)));
+ }
+
+ @Test
+ @DisplayName("getPNCCareDetails should answer for a well formed request")
+ void getPNCCareDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getPNCCareDetails(11L, 11L));
+ }
+
+ @Test
+ @DisplayName("updateBenPNCCareDetails should answer for a well formed request")
+ void updateBenPNCCareDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateBenPNCCareDetails(org.mockito.Mockito.mock(com.iemr.tm.data.pnc.PNCCare.class)));
+ }
+
+ @Test
+ @DisplayName("updateBenPNCCare should answer for a well formed request")
+ void updateBenPNCCare_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateBenPNCCare(org.mockito.Mockito.mock(com.iemr.tm.data.pnc.PNCCare.class)));
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/pnc/PNCServiceImplTest.java b/src/test/java/com/iemr/tm/service/pnc/PNCServiceImplTest.java
new file mode 100644
index 00000000..060b429a
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/pnc/PNCServiceImplTest.java
@@ -0,0 +1,572 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.pnc;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyShort;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.sql.Timestamp;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.iemr.tm.data.nurse.CommonUtilityClass;
+import com.iemr.tm.data.tele_consultation.TeleconsultationRequestOBJ;
+import com.iemr.tm.repo.nurse.BenVisitDetailRepo;
+import com.iemr.tm.repo.nurse.anc.BenAdherenceRepo;
+import com.iemr.tm.repo.quickConsultation.BenChiefComplaintRepo;
+import com.iemr.tm.service.benFlowStatus.CommonBenStatusFlowServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonDoctorServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonNurseServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonServiceImpl;
+import com.iemr.tm.service.labtechnician.LabTechnicianServiceImpl;
+import com.iemr.tm.service.tele_consultation.SMSGatewayServiceImpl;
+import com.iemr.tm.service.tele_consultation.TeleConsultationServiceImpl;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("PNCServiceImpl Test Suite")
+class PNCServiceImplTest {
+
+ private static final String AUTHORIZATION = "Bearer session-token";
+ private static final Long BEN_REG_ID = 11L;
+ private static final Long VISIT_ID = 3L;
+ private static final Long VISIT_CODE = 22L;
+
+ private static final String FULL_HISTORY = "{\"pastHistory\":{},\"comorbidConditions\":{},"
+ + "\"medicationHistory\":{\"medicationHistoryList\":[{\"currentMedication\":\"Iron\"}]},"
+ + "\"personalHistory\":{},\"familyHistory\":{},\"menstrualHistory\":{},"
+ + "\"femaleObstetricHistory\":{},\"immunizationHistory\":{},\"childVaccineDetails\":{}}";
+
+ private static final String FULL_EXAMINATION = "{\"generalExamination\":{},\"headToToeExamination\":{},"
+ + "\"gastroIntestinalExamination\":{},\"cardioVascularExamination\":{},"
+ + "\"respiratorySystemExamination\":{},\"centralNervousSystemExamination\":{},"
+ + "\"musculoskeletalSystemExamination\":{},\"genitoUrinarySystemExamination\":{}}";
+
+ @Mock
+ private CommonNurseServiceImpl commonNurseServiceImpl;
+ @Mock
+ private CommonDoctorServiceImpl commonDoctorServiceImpl;
+ @Mock
+ private PNCNurseServiceImpl pncNurseServiceImpl;
+ @Mock
+ private PNCDoctorServiceImpl pncDoctorServiceImpl;
+ @Mock
+ private CommonBenStatusFlowServiceImpl commonBenStatusFlowServiceImpl;
+ @Mock
+ private LabTechnicianServiceImpl labTechnicianServiceImpl;
+ @Mock
+ private TeleConsultationServiceImpl teleConsultationServiceImpl;
+ @Mock
+ private CommonServiceImpl commonServiceImpl;
+ @Mock
+ private BenVisitDetailRepo benVisitDetailRepo;
+ @Mock
+ private BenChiefComplaintRepo benChiefComplaintRepo;
+ @Mock
+ private BenAdherenceRepo benAdherenceRepo;
+ @Mock
+ private SMSGatewayServiceImpl sMSGatewayServiceImpl;
+
+ @InjectMocks
+ private PNCServiceImpl service;
+
+ private JsonObject json(String raw) {
+ return JsonParser.parseString(raw).getAsJsonObject();
+ }
+
+ private JsonObject nurseRequest() {
+ return json("{" + "\"beneficiaryRegID\":11,\"providerServiceMapID\":9,\"vanID\":7,\"sessionID\":1,"
+ + "\"benFlowID\":5,\"createdBy\":\"nurse1\","
+ + "\"visitDetails\":{"
+ + " \"visitDetails\":{\"beneficiaryRegID\":11,\"visitReason\":\"New Chief Complaint\","
+ + " \"visitCategory\":\"PNC\"},"
+ + " \"chiefComplaints\":[{\"chiefComplaintID\":3}]"
+ + "},"
+ + "\"pNCDeatils\":{},\"historyDetails\":" + FULL_HISTORY
+ + ",\"vitalDetails\":{\"height_cm\":170},\"examinationDetails\":" + FULL_EXAMINATION + "}");
+ }
+
+ private CommonUtilityClass utility() {
+ CommonUtilityClass utility = new CommonUtilityClass();
+ utility.setBeneficiaryRegID(BEN_REG_ID);
+ utility.setVanID(7);
+ utility.setSessionID(1);
+ utility.setProviderServiceMapID(9);
+ utility.setCreatedBy("nurse1");
+ return utility;
+ }
+
+ private TeleconsultationRequestOBJ teleconsultationRequest(boolean walkIn) {
+ TeleconsultationRequestOBJ request = new TeleconsultationRequestOBJ();
+ request.setWalkIn(walkIn);
+ request.setUserID(42);
+ request.setSpecializationID(2);
+ request.setTmRequestID(8L);
+ request.setAllocationDate(new Timestamp(1_700_000_000_000L));
+ return request;
+ }
+
+ @BeforeEach
+ @DisplayName("Wire the collaborators that every save path needs")
+ void setUp() throws Exception {
+ when(commonNurseServiceImpl.getMaxCurrentdate(anyLong(), anyString(), anyString())).thenReturn(0);
+ when(commonNurseServiceImpl.saveBeneficiaryVisitDetails(any())).thenReturn(VISIT_ID);
+ when(commonNurseServiceImpl.generateVisitCode(anyLong(), any(), any())).thenReturn(VISIT_CODE);
+ when(commonNurseServiceImpl.saveBenChiefComplaints(any())).thenReturn(1);
+ when(commonNurseServiceImpl.saveBeneficiaryPhysicalAnthropometryDetails(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBeneficiaryPhysicalVitalDetails(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenPastHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenComorbidConditions(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenMedicationHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.savePersonalHistory(any())).thenReturn(1);
+ when(commonNurseServiceImpl.saveAllergyHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenFamilyHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenMenstrualHistory(any())).thenReturn(1);
+ when(commonNurseServiceImpl.saveFemaleObstetricHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveImmunizationHistory(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveChildOptionalVaccineDetail(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.savePhyGeneralExamination(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.savePhyHeadToToeExamination(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveSysGastrointestinalExamination(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveSysCardiovascularExamination(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveSysRespiratoryExamination(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveSysCentralNervousExamination(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveSysMusculoskeletalSystemExamination(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveSysGenitourinarySystemExamination(any())).thenReturn(1L);
+ when(pncNurseServiceImpl.saveBenPncCareDetails(any())).thenReturn(1L);
+ when(commonBenStatusFlowServiceImpl.updateBenFlowNurseAfterNurseActivity(any(), anyLong(), anyLong(),
+ anyString(), anyString(), anyShort(), anyShort(), anyShort(), anyShort(), anyShort(), anyLong(), any(),
+ anyShort(), any(), any())).thenReturn(1);
+ }
+
+ @Nested
+ @DisplayName("savePNCNurseData")
+ class SaveNurseDataTests {
+
+ @Test
+ @DisplayName("savePNCNurseData should save the visit, PNC care, history, vitals and examination")
+ void saveNurseData_shouldSaveEverySection() throws Exception {
+ String result = service.savePNCNurseData(nurseRequest(), AUTHORIZATION);
+
+ assertTrue(result.contains("Data saved successfully"));
+ assertTrue(result.contains("\"visitCode\":\"22\""));
+ }
+
+ @Test
+ @DisplayName("savePNCNurseData should report an already saved visit")
+ void saveNurseData_shouldReportAlreadySavedVisit() throws Exception {
+ when(commonNurseServiceImpl.getMaxCurrentdate(anyLong(), anyString(), anyString())).thenReturn(1);
+
+ assertTrue(service.savePNCNurseData(nurseRequest(), AUTHORIZATION).contains("Data already saved"));
+ }
+
+ @Test
+ @DisplayName("savePNCNurseData should reject a request without visit details")
+ void saveNurseData_shouldRejectRequestWithoutVisitDetails() {
+ assertThrows(Exception.class, () -> service.savePNCNurseData(json("{}"), AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("savePNCNurseData should fail when the visit could not be created")
+ void saveNurseData_shouldFailWhenVisitNotCreated() throws Exception {
+ when(commonNurseServiceImpl.saveBeneficiaryVisitDetails(any())).thenReturn(0L);
+
+ assertThrows(RuntimeException.class, () -> service.savePNCNurseData(nurseRequest(), AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("savePNCNurseData should fail when the PNC care details could not be stored")
+ void saveNurseData_shouldFailWhenPncCareNotStored() throws Exception {
+ when(pncNurseServiceImpl.saveBenPncCareDetails(any())).thenReturn(null);
+
+ assertThrows(RuntimeException.class, () -> service.savePNCNurseData(nurseRequest(), AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("savePNCNurseData should notify a scheduled teleconsultation by SMS")
+ void saveNurseData_shouldNotifyScheduledTeleconsultation() throws Exception {
+ when(commonServiceImpl.createTcRequest(any(), any(), anyString()))
+ .thenReturn(teleconsultationRequest(false));
+
+ service.savePNCNurseData(nurseRequest(), AUTHORIZATION);
+
+ verify(sMSGatewayServiceImpl).smsSenderGateway(eq("schedule"), anyLong(), anyInt(), anyLong(), any(),
+ anyString(), anyString(), any(), eq(AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("savePNCNurseData should not notify a walk-in teleconsultation")
+ void saveNurseData_shouldNotNotifyWalkInTeleconsultation() throws Exception {
+ when(commonServiceImpl.createTcRequest(any(), any(), anyString())).thenReturn(teleconsultationRequest(true));
+
+ service.savePNCNurseData(nurseRequest(), AUTHORIZATION);
+
+ verify(sMSGatewayServiceImpl, never()).smsSenderGateway(anyString(), anyLong(), anyInt(), anyLong(), any(),
+ anyString(), anyString(), any(), anyString());
+ }
+ }
+
+ @Nested
+ @DisplayName("deleteVisitDetails")
+ class DeleteVisitDetailsTests {
+
+ @Test
+ @DisplayName("deleteVisitDetails should remove the visit rows for a created visit")
+ void deleteVisitDetails_shouldRemoveVisitRows() throws Exception {
+ when(benVisitDetailRepo.getVisitCode(BEN_REG_ID, 9)).thenReturn(VISIT_CODE);
+
+ service.deleteVisitDetails(nurseRequest());
+
+ verify(benVisitDetailRepo).deleteVisitDetails(VISIT_CODE);
+ }
+
+ @Test
+ @DisplayName("deleteVisitDetails should do nothing for a request without visit details")
+ void deleteVisitDetails_shouldDoNothingWithoutVisitDetails() throws Exception {
+ service.deleteVisitDetails(json("{}"));
+
+ verify(benVisitDetailRepo, never()).deleteVisitDetails(anyLong());
+ }
+ }
+
+ @Nested
+ @DisplayName("nurse section saves")
+ class SectionSaveTests {
+
+ @Test
+ @DisplayName("saveBenVisitDetails should return the new visit id and code")
+ void saveBenVisitDetails_shouldReturnVisitIdAndCode() throws Exception {
+ Map result = service.saveBenVisitDetails(nurseRequest().getAsJsonObject("visitDetails"),
+ utility());
+
+ assertEquals(VISIT_ID, result.get("visitID"));
+ assertEquals(VISIT_CODE, result.get("visitCode"));
+ }
+
+ @Test
+ @DisplayName("saveBenVisitDetails should return nothing when the visit was already recorded")
+ void saveBenVisitDetails_shouldReturnNothingForAlreadyRecordedVisit() throws Exception {
+ when(commonNurseServiceImpl.getMaxCurrentdate(anyLong(), anyString(), anyString())).thenReturn(1);
+
+ assertTrue(service.saveBenVisitDetails(nurseRequest().getAsJsonObject("visitDetails"), utility())
+ .isEmpty());
+ }
+
+ @Test
+ @DisplayName("saveBenPNCDetails should store the captured PNC care details")
+ void savePncDetails_shouldStoreCapturedCareDetails() throws Exception {
+ assertEquals(1L, service.saveBenPNCDetails(json("{\"pNCDeatils\":{}}"), VISIT_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("saveBenPNCDetails should succeed when no PNC care details were captured")
+ void savePncDetails_shouldSucceedWithoutCareDetails() throws Exception {
+ assertEquals(1L, service.saveBenPNCDetails(json("{}"), VISIT_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("saveBenPNCHistoryDetails should store every captured history section")
+ void saveHistory_shouldStoreCapturedSections() throws Exception {
+ assertEquals(1L, service.saveBenPNCHistoryDetails(json(FULL_HISTORY), VISIT_ID, VISIT_CODE));
+ verify(commonNurseServiceImpl).saveBenPastHistory(any());
+ }
+
+ @Test
+ @DisplayName("saveBenPNCVitalDetails should store the anthropometry and the physical vitals")
+ void saveVitals_shouldStoreAnthropometryAndPhysicalVitals() throws Exception {
+ assertEquals(1L, service.saveBenPNCVitalDetails(json("{\"height_cm\":170}"), VISIT_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("saveBenPNCVitalDetails should report a failure when the physical vitals were not stored")
+ void saveVitals_shouldReportFailureWhenPhysicalVitalsNotStored() throws Exception {
+ when(commonNurseServiceImpl.saveBeneficiaryPhysicalVitalDetails(any())).thenReturn(null);
+
+ assertNull(service.saveBenPNCVitalDetails(json("{}"), VISIT_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("saveBenExaminationDetails should succeed when no examination section was captured")
+ void saveExamination_shouldSucceedWithoutCapturedSections() throws Exception {
+ assertEquals(1L, service.saveBenExaminationDetails(json("{}"), VISIT_ID, VISIT_CODE));
+ }
+
+ @Test
+ @DisplayName("saveBenExaminationDetails should store every captured examination section")
+ void saveExamination_shouldStoreCapturedSections() throws Exception {
+ assertEquals(1L, service.saveBenExaminationDetails(json(FULL_EXAMINATION), VISIT_ID, VISIT_CODE));
+ verify(commonNurseServiceImpl).savePhyHeadToToeExamination(any());
+ }
+ }
+
+ @Nested
+ @DisplayName("read endpoints")
+ class ReadTests {
+
+ @Test
+ @DisplayName("getBenVisitDetailsFrmNursePNC should assemble the visit and the chief complaints")
+ void getVisitDetails_shouldAssembleVisitSections() {
+ when(commonNurseServiceImpl.getBenChiefComplaints(BEN_REG_ID, VISIT_CODE)).thenReturn("[]");
+
+ String result = service.getBenVisitDetailsFrmNursePNC(BEN_REG_ID, VISIT_CODE);
+
+ assertTrue(result.contains("PNCNurseVisitDetail"));
+ assertTrue(result.contains("BenChiefComplaints"));
+ }
+
+ @Test
+ @DisplayName("getBenPNCDetailsFrmNursePNC should assemble the PNC care details")
+ void getPncDetails_shouldAssemblePncSections() {
+ when(pncNurseServiceImpl.getPNCCareDetails(BEN_REG_ID, VISIT_CODE)).thenReturn("{}");
+
+ assertTrue(service.getBenPNCDetailsFrmNursePNC(BEN_REG_ID, VISIT_CODE).contains("PNCCareDetail"));
+ }
+
+ @Test
+ @DisplayName("getBenHistoryDetails should assemble every stored history section")
+ void getHistoryDetails_shouldAssembleStoredSections() {
+ when(commonNurseServiceImpl.getPastHistoryData(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(new com.iemr.tm.data.anc.BenMedHistory());
+
+ assertTrue(service.getBenHistoryDetails(BEN_REG_ID, VISIT_CODE).contains("PastHistory"));
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryVitalDetails should assemble the anthropometry and the physical vitals")
+ void getVitalDetails_shouldAssembleVitalSections() {
+ when(commonNurseServiceImpl.getBeneficiaryPhysicalAnthropometryDetails(BEN_REG_ID, VISIT_CODE))
+ .thenReturn("{}");
+ when(commonNurseServiceImpl.getBeneficiaryPhysicalVitalDetails(BEN_REG_ID, VISIT_CODE)).thenReturn("{}");
+
+ assertTrue(service.getBeneficiaryVitalDetails(BEN_REG_ID, VISIT_CODE).contains("benAnthropometryDetail"));
+ }
+
+ @Test
+ @DisplayName("getPNCExaminationDetailsData should assemble every stored examination section")
+ void getExaminationDetails_shouldAssembleStoredSections() {
+ when(commonNurseServiceImpl.getGeneralExaminationData(BEN_REG_ID, VISIT_CODE))
+ .thenReturn(new com.iemr.tm.data.anc.PhyGeneralExamination());
+
+ assertTrue(service.getPNCExaminationDetailsData(BEN_REG_ID, VISIT_CODE).contains("generalExamination"));
+ }
+
+ @Test
+ @DisplayName("getBenPNCNurseData should assemble the nurse captured sections")
+ void getNurseData_shouldAssembleNurseSections() {
+ assertTrue(service.getBenPNCNurseData(BEN_REG_ID, VISIT_CODE).contains("history"));
+ }
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorPNC should assemble the whole doctor case record")
+ void getCaseRecord_shouldAssembleDoctorCaseRecord() throws Exception {
+ when(commonNurseServiceImpl.getGraphicalTrendData(anyLong(), anyString())).thenReturn(new HashMap<>());
+
+ String result = service.getBenCaseRecordFromDoctorPNC(BEN_REG_ID, VISIT_CODE);
+
+ assertTrue(result.contains("findings"));
+ assertTrue(result.contains("LabReport"));
+ }
+ }
+
+ @Nested
+ @DisplayName("savePNCDoctorData")
+ class SaveDoctorDataTests {
+
+ private JsonObject doctorRequest() {
+ return json("{" + "\"beneficiaryRegID\":11,\"benVisitID\":3,\"visitCode\":22,\"providerServiceMapID\":9,"
+ + "\"createdBy\":\"doctor1\",\"doctorSignatureFlag\":true,\"findings\":{},"
+ + "\"diagnosis\":{\"specialistDiagnosis\":\"PNC follow up\"},"
+ + "\"investigation\":{\"laboratoryList\":[{\"testID\":1}]},"
+ + "\"prescription\":[{\"drugID\":1,\"formName\":\"Tablet\"}],"
+ + "\"refer\":{\"referredToInstituteID\":1}" + "}");
+ }
+
+ @BeforeEach
+ void stubDoctorCollaborators() throws Exception {
+ when(commonDoctorServiceImpl.saveDocFindings(any())).thenReturn(1);
+ when(commonNurseServiceImpl.savePrescriptionDetailsAndGetPrescriptionID(any(), any(), any(), any(), any(),
+ any(), any(), any(), any(), any())).thenReturn(4L);
+ when(pncDoctorServiceImpl.saveBenPNCDiagnosis(any(), any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenInvestigation(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenPrescribedDrugsList(any())).thenReturn(1);
+ when(commonDoctorServiceImpl.saveBenReferDetails(any())).thenReturn(1L);
+ when(commonDoctorServiceImpl.updateBenFlowtableAfterDocDataSave(any(), anyBoolean(), anyBoolean(), any(),
+ anyBoolean())).thenReturn(1);
+ }
+
+ @Test
+ @DisplayName("savePNCDoctorData should save the findings, diagnosis, tests, drugs and referral")
+ void saveDoctorData_shouldSaveWholeCaseRecord() throws Exception {
+ assertEquals(1L, service.savePNCDoctorData(doctorRequest(), AUTHORIZATION));
+
+ verify(commonDoctorServiceImpl).saveDocFindings(any());
+ verify(pncDoctorServiceImpl).saveBenPNCDiagnosis(any(), any());
+ }
+
+ @Test
+ @DisplayName("savePNCDoctorData should succeed for a case record with only findings and an investigation")
+ void saveDoctorData_shouldSucceedForMinimalCaseRecord() throws Exception {
+ assertEquals(1L, service.savePNCDoctorData(
+ json("{\"beneficiaryRegID\":11,\"findings\":{},\"investigation\":{}}"), AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("savePNCDoctorData should fail when the findings section is absent")
+ void saveDoctorData_shouldFailWithoutFindings() throws Exception {
+ assertThrows(RuntimeException.class,
+ () -> service.savePNCDoctorData(json("{\"beneficiaryRegID\":11,\"investigation\":{}}"),
+ AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("savePNCDoctorData should fail when the beneficiary flow could not be advanced")
+ void saveDoctorData_shouldFailWhenFlowNotAdvanced() throws Exception {
+ when(commonDoctorServiceImpl.updateBenFlowtableAfterDocDataSave(any(), anyBoolean(), anyBoolean(), any(),
+ anyBoolean())).thenReturn(0);
+
+ assertThrows(RuntimeException.class, () -> service.savePNCDoctorData(doctorRequest(), AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("savePNCDoctorData should notify a scheduled teleconsultation by SMS")
+ void saveDoctorData_shouldNotifyScheduledTeleconsultation() throws Exception {
+ when(commonServiceImpl.createTcRequest(any(), any(), anyString()))
+ .thenReturn(teleconsultationRequest(false));
+
+ service.savePNCDoctorData(doctorRequest(), AUTHORIZATION);
+
+ verify(sMSGatewayServiceImpl).smsSenderGateway(eq("schedule"), anyLong(), anyInt(), anyLong(), any(), any(),
+ anyString(), any(), eq(AUTHORIZATION));
+ }
+ }
+
+ @Nested
+ @DisplayName("update endpoints")
+ class UpdateTests {
+
+ @Test
+ @DisplayName("updateBenPNCDetails should succeed when no PNC section was captured")
+ void updatePncDetails_shouldSucceedWithoutCapturedSections() throws Exception {
+ assertEquals(1, service.updateBenPNCDetails(json("{}")));
+ }
+
+ @Test
+ @DisplayName("updateBenPNCDetails should update the captured PNC care details")
+ void updatePncDetails_shouldUpdateCapturedCareDetails() throws Exception {
+ when(pncNurseServiceImpl.updateBenPNCCareDetails(any())).thenReturn(1);
+
+ assertEquals(1, service.updateBenPNCDetails(json("{\"PNCDetails\":{}}")));
+ }
+
+ @Test
+ @DisplayName("updateBenHistoryDetails should succeed when no history section was captured")
+ void updateHistory_shouldSucceedWithoutCapturedSections() throws Exception {
+ assertEquals(1, service.updateBenHistoryDetails(json("{}")));
+ }
+
+ @Test
+ @DisplayName("updateBenVitalDetails should confirm the update when both sections changed")
+ void updateVitals_shouldConfirmUpdate() throws Exception {
+ when(commonNurseServiceImpl.updateANCAnthropometryDetails(any())).thenReturn(1);
+ when(commonNurseServiceImpl.updateANCPhysicalVitalDetails(any())).thenReturn(1);
+
+ assertEquals(1, service.updateBenVitalDetails(json("{\"height_cm\":170}")));
+ }
+
+ @Test
+ @DisplayName("updateBenExaminationDetails should succeed when no examination section was captured")
+ void updateExamination_shouldSucceedWithoutCapturedSections() throws Exception {
+ assertEquals(1, service.updateBenExaminationDetails(json("{}")));
+ }
+
+ @Test
+ @DisplayName("updatePNCDoctorData should return nothing for a null request")
+ void updateDoctorData_shouldReturnNothingForNullRequest() throws Exception {
+ assertNull(service.updatePNCDoctorData(null, AUTHORIZATION));
+ }
+
+ @Test
+ @DisplayName("updatePNCDoctorData should update the whole case record")
+ void updateDoctorData_shouldUpdateWholeCaseRecord() throws Exception {
+ when(commonDoctorServiceImpl.updateDocFindings(any())).thenReturn(1);
+ when(commonNurseServiceImpl.updatePrescription(any())).thenReturn(1);
+ when(pncDoctorServiceImpl.updateBenPNCDiagnosis(any())).thenReturn(1);
+ when(commonNurseServiceImpl.saveBenInvestigation(any())).thenReturn(1L);
+ when(commonNurseServiceImpl.saveBenPrescribedDrugsList(any())).thenReturn(1);
+ when(commonDoctorServiceImpl.updateBenReferDetails(any())).thenReturn(1L);
+ when(commonDoctorServiceImpl.updateBenFlowtableAfterDocDataUpdate(any(), anyBoolean(), anyBoolean(), any(),
+ anyBoolean())).thenReturn(1);
+
+ JsonObject request = json("{" + "\"beneficiaryRegID\":11,\"benVisitID\":3,\"visitCode\":22,"
+ + "\"findings\":{},\"diagnosis\":{\"prescriptionID\":4},"
+ + "\"investigation\":{\"laboratoryList\":[{\"testID\":1}]},"
+ + "\"prescription\":[{\"drugID\":1,\"formName\":\"Tablet\"}],"
+ + "\"refer\":{\"referredToInstituteID\":1}" + "}");
+
+ assertEquals(1L, service.updatePNCDoctorData(request, AUTHORIZATION));
+ }
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("PNC captured-section updates")
+ class CapturedSectionUpdateTests {
+
+ @Test
+ @DisplayName("updateBenHistoryDetails should update every captured history section")
+ void updateBenHistoryDetails_shouldUpdateEveryCapturedSection() throws Exception {
+ org.junit.jupiter.api.Assertions.assertDoesNotThrow(() -> service.updateBenHistoryDetails(
+ com.google.gson.JsonParser.parseString("{\"pastHistory\":{},\"comorbidConditions\":{},\"medicationHistory\":{},\"personalHistory\":{},\"familyHistory\":{},\"menstrualHistory\":{},\"femaleObstetricHistory\":{},\"immunizationHistory\":{},\"childVaccineDetails\":{},\"developmentHistory\":{},\"feedingHistory\":{},\"perinatalHistroy\":{},\"allergyHistory\":{}}").getAsJsonObject()));
+ }
+
+ @Test
+ @DisplayName("updateBenExaminationDetails should update every captured examination section")
+ void updateBenExaminationDetails_shouldUpdateEveryCapturedSection() throws Exception {
+ org.junit.jupiter.api.Assertions.assertDoesNotThrow(() -> service.updateBenExaminationDetails(
+ com.google.gson.JsonParser.parseString("{\"generalExamination\":{},\"headToToeExamination\":{},\"gastroIntestinalExamination\":{},\"cardioVascularExamination\":{},\"respiratorySystemExamination\":{},\"centralNervousSystemExamination\":{},\"musculoskeletalSystemExamination\":{},\"genitoUrinarySystemExamination\":{},\"obstetricExamination\":{}}").getAsJsonObject()));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/quickBlox/QuickbloxServiceImplTest.java b/src/test/java/com/iemr/tm/service/quickBlox/QuickbloxServiceImplTest.java
new file mode 100644
index 00000000..4a725e68
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/quickBlox/QuickbloxServiceImplTest.java
@@ -0,0 +1,54 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.quickBlox;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.quickBlox.QuickBloxRepo;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("QuickbloxServiceImpl Test Suite")
+class QuickbloxServiceImplTest {
+
+ @Mock
+ private QuickBloxRepo quickBloxRepo;
+
+ @InjectMocks
+ private QuickbloxServiceImpl service;
+
+ @Test
+ @DisplayName("getQuickbloxIds should reject a request that carries no beneficiary details")
+ void getQuickbloxIds_shouldRejectRequestWithoutBeneficiaryDetails() {
+ assertThrows(NullPointerException.class, () -> service.getQuickbloxIds("{}"));
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/quickConsultation/QuickConsultationServiceImplTest.java b/src/test/java/com/iemr/tm/service/quickConsultation/QuickConsultationServiceImplTest.java
new file mode 100644
index 00000000..193791d4
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/quickConsultation/QuickConsultationServiceImplTest.java
@@ -0,0 +1,519 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.quickConsultation;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.nurse.BenPhysicalVitalRepo;
+import com.iemr.tm.repo.nurse.BenVisitDetailRepo;
+import com.iemr.tm.repo.nurse.anc.BenAdherenceRepo;
+import com.iemr.tm.repo.quickConsultation.BenChiefComplaintRepo;
+import com.iemr.tm.repo.quickConsultation.BenClinicalObservationsRepo;
+import com.iemr.tm.repo.quickConsultation.ExternalTestOrderRepo;
+import com.iemr.tm.repo.quickConsultation.PrescriptionDetailRepo;
+import com.iemr.tm.service.benFlowStatus.CommonBenStatusFlowServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonDoctorServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonNurseServiceImpl;
+import com.iemr.tm.service.common.transaction.CommonServiceImpl;
+import com.iemr.tm.service.generalOPD.GeneralOPDDoctorServiceImpl;
+import com.iemr.tm.service.labtechnician.LabTechnicianServiceImpl;
+import com.iemr.tm.service.tele_consultation.SMSGatewayServiceImpl;
+import com.iemr.tm.service.tele_consultation.TeleConsultationServiceImpl;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("QuickConsultationServiceImpl Test Suite")
+class QuickConsultationServiceImplTest {
+
+ @Mock
+ private BenChiefComplaintRepo benChiefComplaintRepo;
+ @Mock
+ private BenClinicalObservationsRepo benClinicalObservationsRepo;
+ @Mock
+ private PrescriptionDetailRepo prescriptionDetailRepo;
+ @Mock
+ private ExternalTestOrderRepo externalTestOrderRepo;
+ @Mock
+ private CommonNurseServiceImpl commonNurseServiceImpl;
+ @Mock
+ private CommonBenStatusFlowServiceImpl commonBenStatusFlowServiceImpl;
+ @Mock
+ private LabTechnicianServiceImpl labTechnicianServiceImpl;
+ @Mock
+ private CommonDoctorServiceImpl commonDoctorServiceImpl;
+ @Mock
+ private GeneralOPDDoctorServiceImpl generalOPDDoctorServiceImpl;
+ @Mock
+ private CommonServiceImpl commonServiceImpl;
+ @Mock
+ private TeleConsultationServiceImpl teleConsultationServiceImpl;
+ @Mock
+ private SMSGatewayServiceImpl sMSGatewayServiceImpl;
+ @Mock
+ private BenPhysicalVitalRepo benPhysicalVitalRepo;
+ @Mock
+ private BenVisitDetailRepo benVisitDetailRepo;
+ @Mock
+ private BenAdherenceRepo benAdherenceRepo;
+
+ @InjectMocks
+ private QuickConsultationServiceImpl service;
+
+ @Test
+ @DisplayName("saveBeneficiaryChiefComplaint should answer for a well formed request")
+ void saveBeneficiaryChiefComplaint_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.saveBeneficiaryChiefComplaint(new com.google.gson.JsonObject()));
+ }
+
+ @Test
+ @DisplayName("saveBeneficiaryClinicalObservations should answer for a well formed request")
+ void saveBeneficiaryClinicalObservations_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.saveBeneficiaryClinicalObservations(new com.google.gson.JsonObject()));
+ }
+
+ @Test
+ @DisplayName("saveBenPrescriptionForANC should answer for a well formed request")
+ void saveBenPrescriptionForANC_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.saveBenPrescriptionForANC(new com.iemr.tm.data.quickConsultation.PrescriptionDetail()));
+ }
+
+ @Test
+ @DisplayName("saveBeneficiaryExternalLabTestOrderDetails should answer for a well formed request")
+ void saveBeneficiaryExternalLabTestOrderDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.saveBeneficiaryExternalLabTestOrderDetails(new com.google.gson.JsonObject()));
+ }
+
+ @Test
+ @DisplayName("quickConsultNurseDataInsert should reject a request it cannot act on")
+ void quickConsultNurseDataInsert_shouldRejectRequestItCannotActOn() {
+ assertThrows(Exception.class, () -> service.quickConsultNurseDataInsert(new com.google.gson.JsonObject(), "{}"));
+ }
+
+ @Test
+ @DisplayName("deleteVisitDetails should answer for a well formed request")
+ void deleteVisitDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.deleteVisitDetails(new com.google.gson.JsonObject()));
+ }
+
+ @Test
+ @DisplayName("quickConsultDoctorDataInsert should reject a request it cannot act on")
+ void quickConsultDoctorDataInsert_shouldRejectRequestItCannotActOn() {
+ assertThrows(RuntimeException.class, () -> service.quickConsultDoctorDataInsert(new com.google.gson.JsonObject(), "{}"));
+ }
+
+ @Test
+ @DisplayName("getBenDataFrmNurseToDocVisitDetailsScreen should answer for a well formed request")
+ void getBenDataFrmNurseToDocVisitDetailsScreen_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenDataFrmNurseToDocVisitDetailsScreen(11L, 11L));
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryVitalDetails should answer for a well formed request")
+ void getBeneficiaryVitalDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBeneficiaryVitalDetails(11L, 11L));
+ }
+
+ @Test
+ @DisplayName("getBenQuickConsultNurseData should answer for a well formed request")
+ void getBenQuickConsultNurseData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenQuickConsultNurseData(11L, 11L));
+ }
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorQuickConsult should answer for a well formed request")
+ void getBenCaseRecordFromDoctorQuickConsult_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenCaseRecordFromDoctorQuickConsult(11L, 11L));
+ }
+
+ @Test
+ @DisplayName("updateGeneralOPDQCDoctorData should reject a request it cannot act on")
+ void updateGeneralOPDQCDoctorData_shouldRejectRequestItCannotActOn() {
+ assertThrows(RuntimeException.class, () -> service.updateGeneralOPDQCDoctorData(new com.google.gson.JsonObject(), "{}"));
+ }
+
+ @Test
+ @DisplayName("updateBeneficiaryClinicalObservations should answer for a well formed request")
+ void updateBeneficiaryClinicalObservations_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateBeneficiaryClinicalObservations(new com.google.gson.JsonObject()));
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("quick consultation capture")
+ class QuickConsultationCaptureTests {
+
+ private com.google.gson.JsonObject nurseRequest() {
+ return com.google.gson.JsonParser.parseString("{"
+ + "\"beneficiaryRegID\":11,\"providerServiceMapID\":9,\"vanID\":7,\"sessionID\":1,"
+ + "\"benFlowID\":5,\"createdBy\":\"nurse1\","
+ + "\"visitDetails\":{\"beneficiaryRegID\":11,\"visitReason\":\"New Chief Complaint\","
+ + " \"visitCategory\":\"Quick Consultation\"},"
+ + "\"vitalsDetails\":{\"height_cm\":170}}").getAsJsonObject();
+ }
+
+ @org.junit.jupiter.api.BeforeEach
+ void stubNurseCollaborators() throws Exception {
+ org.mockito.Mockito.when(commonNurseServiceImpl.getMaxCurrentdate(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyString(), org.mockito.ArgumentMatchers.anyString())).thenReturn(0);
+ org.mockito.Mockito.when(commonNurseServiceImpl
+ .saveBeneficiaryVisitDetails(org.mockito.ArgumentMatchers.any())).thenReturn(3L);
+ org.mockito.Mockito.when(commonNurseServiceImpl.generateVisitCode(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any())).thenReturn(22L);
+ org.mockito.Mockito.when(commonNurseServiceImpl
+ .saveBeneficiaryPhysicalAnthropometryDetails(org.mockito.ArgumentMatchers.any())).thenReturn(1L);
+ org.mockito.Mockito.when(commonNurseServiceImpl
+ .saveBeneficiaryPhysicalVitalDetails(org.mockito.ArgumentMatchers.any())).thenReturn(1L);
+ org.mockito.Mockito.when(commonBenStatusFlowServiceImpl.updateBenFlowNurseAfterNurseActivity(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyString(),
+ org.mockito.ArgumentMatchers.anyString(), org.mockito.ArgumentMatchers.anyShort(),
+ org.mockito.ArgumentMatchers.anyShort(), org.mockito.ArgumentMatchers.anyShort(),
+ org.mockito.ArgumentMatchers.anyShort(), org.mockito.ArgumentMatchers.anyShort(),
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.anyShort(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any())).thenReturn(1);
+ }
+
+ @Test
+ @DisplayName("quickConsultNurseDataInsert should save the visit and the vitals")
+ void nurseDataInsert_shouldSaveVisitAndVitals() throws Exception {
+ String result = service.quickConsultNurseDataInsert(nurseRequest(), "Bearer session-token");
+
+ org.junit.jupiter.api.Assertions.assertTrue(result.contains("Data saved successfully"));
+ org.junit.jupiter.api.Assertions.assertTrue(result.contains("\"visitCode\":\"22\""));
+ }
+
+ @Test
+ @DisplayName("quickConsultNurseDataInsert should report an already saved visit")
+ void nurseDataInsert_shouldReportAlreadySavedVisit() throws Exception {
+ org.mockito.Mockito.when(commonNurseServiceImpl.getMaxCurrentdate(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyString(), org.mockito.ArgumentMatchers.anyString())).thenReturn(1);
+
+ org.junit.jupiter.api.Assertions.assertTrue(service
+ .quickConsultNurseDataInsert(nurseRequest(), "Bearer session-token")
+ .contains("Data already saved"));
+ }
+
+ @Test
+ @DisplayName("quickConsultNurseDataInsert should fail when the vitals could not be stored")
+ void nurseDataInsert_shouldFailWhenVitalsNotStored() throws Exception {
+ org.mockito.Mockito.when(commonNurseServiceImpl
+ .saveBeneficiaryPhysicalVitalDetails(org.mockito.ArgumentMatchers.any())).thenReturn(null);
+
+ org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class,
+ () -> service.quickConsultNurseDataInsert(nurseRequest(), "Bearer session-token"));
+ }
+
+ @Test
+ @DisplayName("deleteVisitDetails should remove the visit rows for a created visit")
+ void deleteVisitDetails_shouldRemoveVisitRows() throws Exception {
+ org.mockito.Mockito.when(benVisitDetailRepo.getVisitCode(11L, 9)).thenReturn(22L);
+
+ service.deleteVisitDetails(nurseRequest());
+
+ org.mockito.Mockito.verify(benVisitDetailRepo).deleteVisitDetails(22L);
+ }
+
+ @Test
+ @DisplayName("saveBeneficiaryClinicalObservations should return the stored observation id")
+ void saveClinicalObservations_shouldReturnStoredId() throws Exception {
+ com.iemr.tm.data.quickConsultation.BenClinicalObservations stored =
+ new com.iemr.tm.data.quickConsultation.BenClinicalObservations();
+ stored.setClinicalObservationID(4L);
+ org.mockito.Mockito.when(benClinicalObservationsRepo.save(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(stored);
+
+ org.junit.jupiter.api.Assertions.assertEquals(4L, service.saveBeneficiaryClinicalObservations(
+ com.google.gson.JsonParser.parseString("{\"beneficiaryRegID\":11}").getAsJsonObject()));
+ }
+
+ @Test
+ @DisplayName("saveBenPrescriptionForANC should return the stored prescription id")
+ void savePrescription_shouldReturnStoredId() {
+ com.iemr.tm.data.quickConsultation.PrescriptionDetail stored =
+ new com.iemr.tm.data.quickConsultation.PrescriptionDetail();
+ stored.setPrescriptionID(4L);
+ org.mockito.Mockito.when(prescriptionDetailRepo.save(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(stored);
+
+ org.junit.jupiter.api.Assertions.assertEquals(4L, service.saveBenPrescriptionForANC(
+ new com.iemr.tm.data.quickConsultation.PrescriptionDetail()));
+ }
+
+ @Test
+ @DisplayName("getBenDataFrmNurseToDocVisitDetailsScreen should assemble the visit and the complaints")
+ void getVisitDetailsScreen_shouldAssembleVisitSections() {
+ org.mockito.Mockito.when(commonNurseServiceImpl.getBenChiefComplaints(11L, 22L)).thenReturn("[]");
+
+ org.junit.jupiter.api.Assertions.assertNotNull(
+ service.getBenDataFrmNurseToDocVisitDetailsScreen(11L, 22L));
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryVitalDetails should assemble the anthropometry and the physical vitals")
+ void getVitalDetails_shouldAssembleVitalSections() {
+ org.mockito.Mockito.when(commonNurseServiceImpl
+ .getBeneficiaryPhysicalAnthropometryDetails(11L, 22L)).thenReturn("{}");
+ org.mockito.Mockito.when(commonNurseServiceImpl
+ .getBeneficiaryPhysicalVitalDetails(11L, 22L)).thenReturn("{}");
+
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getBeneficiaryVitalDetails(11L, 22L));
+ }
+
+ @Test
+ @DisplayName("getBenQuickConsultNurseData should assemble the nurse captured sections")
+ void getNurseData_shouldAssembleNurseSections() {
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getBenQuickConsultNurseData(11L, 22L));
+ }
+
+ @Test
+ @DisplayName("getBenCaseRecordFromDoctorQuickConsult should assemble the doctor case record")
+ void getCaseRecord_shouldAssembleDoctorCaseRecord() throws Exception {
+ org.mockito.Mockito.when(commonNurseServiceImpl.getGraphicalTrendData(
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyString()))
+ .thenReturn(new java.util.HashMap<>());
+
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getBenCaseRecordFromDoctorQuickConsult(11L, 22L));
+ }
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("quick consultation doctor data")
+ class DoctorDataTests {
+
+ private static final String DOCTOR_REQUEST = "{\"beneficiaryRegID\":11,\"beneficiaryID\":9,\"benVisitID\":3,"
+ + "\"visitCode\":22,\"benFlowID\":5,\"providerServiceMapID\":9,\"createdBy\":\"doctor1\","
+ + "\"prescriptionID\":31,\"doctorSignatureFlag\":true,\"isSpecialist\":false,"
+ + "\"clinicalObservations\":{\"otherSymptoms\":\"fever\"},"
+ + "\"chiefComplaints\":[{\"chiefComplaint\":\"fever\",\"duration\":2,"
+ + " \"unitOfDuration\":\"days\"}],"
+ + "\"prescription\":[{\"drugID\":4,\"drugName\":\"Paracetamol\",\"dose\":\"1\","
+ + " \"frequency\":\"TDS\",\"duration\":\"3\",\"unitOfDuration\":\"days\"}],"
+ + "\"labTestOrders\":[{\"testID\":7,\"testName\":\"CBC\"}],"
+ + "\"rbsTestResult\":\"110\",\"rbsTestRemarks\":\"normal\","
+ + "\"refer\":{\"beneficiaryRegID\":11,\"visitCode\":22,\"referralReason\":\"follow up\"}}";
+
+ private com.google.gson.JsonObject doctorRequest() {
+ return com.google.gson.JsonParser.parseString(DOCTOR_REQUEST).getAsJsonObject();
+ }
+
+ private com.iemr.tm.data.tele_consultation.TeleconsultationRequestOBJ tcRequest(boolean walkIn) {
+ com.iemr.tm.data.tele_consultation.TeleconsultationRequestOBJ tcRequest =
+ new com.iemr.tm.data.tele_consultation.TeleconsultationRequestOBJ();
+ tcRequest.setUserID(41);
+ tcRequest.setSpecializationID(3);
+ tcRequest.setTmRequestID(77L);
+ tcRequest.setWalkIn(walkIn);
+ tcRequest.setAllocationDate(new java.sql.Timestamp(System.currentTimeMillis()));
+ return tcRequest;
+ }
+
+ @org.junit.jupiter.api.BeforeEach
+ void stubDoctorCollaborators() throws Exception {
+ com.iemr.tm.data.quickConsultation.BenClinicalObservations observations =
+ new com.iemr.tm.data.quickConsultation.BenClinicalObservations();
+ observations.setClinicalObservationID(4L);
+ org.mockito.Mockito.when(benClinicalObservationsRepo.save(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(observations);
+ org.mockito.Mockito.when(benChiefComplaintRepo.saveAll(org.mockito.ArgumentMatchers.any()))
+ .thenAnswer(invocation -> invocation.getArgument(0));
+ org.mockito.Mockito.when(commonNurseServiceImpl
+ .saveBeneficiaryPrescription(org.mockito.ArgumentMatchers.any())).thenReturn(31L);
+ org.mockito.Mockito.when(commonNurseServiceImpl
+ .saveBenPrescribedDrugsList(org.mockito.ArgumentMatchers.any())).thenReturn(1);
+ org.mockito.Mockito.when(commonNurseServiceImpl.saveBeneficiaryLabTestOrderDetails(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any())).thenReturn(1L);
+ org.mockito.Mockito.when(commonNurseServiceImpl
+ .updatePrescription(org.mockito.ArgumentMatchers.any())).thenReturn(1);
+ org.mockito.Mockito.when(benPhysicalVitalRepo.updatePhysicalVitalDetailsQCDoctor(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any())).thenReturn(1);
+ org.mockito.Mockito.when(commonDoctorServiceImpl
+ .saveBenReferDetails(org.mockito.ArgumentMatchers.any())).thenReturn(1L);
+ org.mockito.Mockito.when(commonDoctorServiceImpl
+ .updateBenReferDetails(org.mockito.ArgumentMatchers.any())).thenReturn(1L);
+ org.mockito.Mockito.when(commonDoctorServiceImpl
+ .updateBenClinicalObservations(org.mockito.ArgumentMatchers.any())).thenReturn(1);
+ org.mockito.Mockito.when(commonDoctorServiceImpl.updateBenFlowtableAfterDocDataSave(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any())).thenReturn(1);
+ org.mockito.Mockito.when(commonDoctorServiceImpl.updateBenFlowtableAfterDocDataUpdate(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any())).thenReturn(1);
+ }
+
+ @Test
+ @DisplayName("quickConsultDoctorDataInsert should save every doctor section for a walk in visit")
+ void doctorDataInsert_shouldSaveEverySection() throws Exception {
+ org.junit.jupiter.api.Assertions.assertEquals(1,
+ service.quickConsultDoctorDataInsert(doctorRequest(), "Bearer session-token"));
+
+ org.mockito.Mockito.verify(commonNurseServiceImpl)
+ .saveBenPrescribedDrugsList(org.mockito.ArgumentMatchers.any());
+ org.mockito.Mockito.verify(commonNurseServiceImpl).saveBeneficiaryLabTestOrderDetails(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.eq(31L));
+ org.mockito.Mockito.verify(benPhysicalVitalRepo).updatePhysicalVitalDetailsQCDoctor("110", "normal", 11L,
+ 22L);
+ }
+
+ @Test
+ @DisplayName("quickConsultDoctorDataInsert should text the beneficiary about a scheduled teleconsultation")
+ void doctorDataInsert_shouldTextBeneficiaryAboutSchedule() throws Exception {
+ org.mockito.Mockito.when(commonServiceImpl.createTcRequest(org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.anyString()))
+ .thenReturn(tcRequest(false));
+
+ org.junit.jupiter.api.Assertions.assertEquals(1,
+ service.quickConsultDoctorDataInsert(doctorRequest(), "Bearer session-token"));
+
+ org.mockito.Mockito.verify(sMSGatewayServiceImpl).smsSenderGateway(
+ org.mockito.ArgumentMatchers.eq("schedule"), org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyInt(), org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.anyString(),
+ org.mockito.ArgumentMatchers.anyString(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.anyString());
+ }
+
+ @Test
+ @DisplayName("quickConsultDoctorDataInsert should save a visit without a prescription or a test")
+ void doctorDataInsert_shouldSaveVisitWithoutPrescriptionOrTest() throws Exception {
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.quickConsultDoctorDataInsert(
+ com.google.gson.JsonParser.parseString("{\"beneficiaryRegID\":11,\"visitCode\":22,"
+ + "\"clinicalObservations\":{},\"chiefComplaints\":[{\"chiefComplaint\":\"fever\"}]}")
+ .getAsJsonObject(),
+ "Bearer session-token"));
+ }
+
+ @Test
+ @DisplayName("quickConsultDoctorDataInsert should fail when the beneficiary flow could not be advanced")
+ void doctorDataInsert_shouldFailWhenFlowNotAdvanced() throws Exception {
+ org.mockito.Mockito.when(commonDoctorServiceImpl.updateBenFlowtableAfterDocDataSave(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any())).thenReturn(0);
+
+ org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class,
+ () -> service.quickConsultDoctorDataInsert(doctorRequest(), "Bearer session-token"));
+ }
+
+ @Test
+ @DisplayName("quickConsultDoctorDataInsert should fail when the prescription could not be created")
+ void doctorDataInsert_shouldFailWhenPrescriptionNotCreated() throws Exception {
+ org.mockito.Mockito.when(commonNurseServiceImpl
+ .saveBeneficiaryPrescription(org.mockito.ArgumentMatchers.any())).thenReturn(0L);
+
+ org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class,
+ () -> service.quickConsultDoctorDataInsert(doctorRequest(), "Bearer session-token"));
+ }
+
+ @Test
+ @DisplayName("updateGeneralOPDQCDoctorData should update every doctor section")
+ void doctorDataUpdate_shouldUpdateEverySection() throws Exception {
+ org.junit.jupiter.api.Assertions.assertNotNull(
+ service.updateGeneralOPDQCDoctorData(doctorRequest(), "Bearer session-token"));
+
+ org.mockito.Mockito.verify(commonNurseServiceImpl)
+ .updatePrescription(org.mockito.ArgumentMatchers.any());
+ org.mockito.Mockito.verify(commonDoctorServiceImpl)
+ .updateBenReferDetails(org.mockito.ArgumentMatchers.any());
+ }
+
+ @Test
+ @DisplayName("updateGeneralOPDQCDoctorData should text the beneficiary about a scheduled teleconsultation")
+ void doctorDataUpdate_shouldTextBeneficiaryAboutSchedule() throws Exception {
+ org.mockito.Mockito.when(commonServiceImpl.createTcRequest(org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.anyString()))
+ .thenReturn(tcRequest(false));
+
+ org.junit.jupiter.api.Assertions.assertNotNull(
+ service.updateGeneralOPDQCDoctorData(doctorRequest(), "Bearer session-token"));
+
+ org.mockito.Mockito.verify(sMSGatewayServiceImpl).smsSenderGateway(
+ org.mockito.ArgumentMatchers.eq("schedule"), org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyInt(), org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.anyString(),
+ org.mockito.ArgumentMatchers.anyString(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.anyString());
+ }
+
+ @Test
+ @DisplayName("updateGeneralOPDQCDoctorData should update a visit without a prescription or a test")
+ void doctorDataUpdate_shouldUpdateVisitWithoutPrescriptionOrTest() throws Exception {
+ org.junit.jupiter.api.Assertions.assertNotNull(service.updateGeneralOPDQCDoctorData(
+ com.google.gson.JsonParser.parseString("{\"beneficiaryRegID\":11,\"visitCode\":22,"
+ + "\"prescriptionID\":31,\"clinicalObservations\":{},"
+ + "\"chiefComplaints\":[{\"chiefComplaint\":\"fever\"}]}").getAsJsonObject(),
+ "Bearer session-token"));
+ }
+
+ @Test
+ @DisplayName("updateGeneralOPDQCDoctorData should fail when the beneficiary flow could not be advanced")
+ void doctorDataUpdate_shouldFailWhenFlowNotAdvanced() throws Exception {
+ org.mockito.Mockito.when(commonDoctorServiceImpl.updateBenFlowtableAfterDocDataUpdate(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any())).thenReturn(0);
+
+ org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class,
+ () -> service.updateGeneralOPDQCDoctorData(doctorRequest(), "Bearer session-token"));
+ }
+
+ @Test
+ @DisplayName("updateGeneralOPDQCDoctorData should fail when the observations could not be updated")
+ void doctorDataUpdate_shouldFailWhenObservationsNotUpdated() throws Exception {
+ org.mockito.Mockito.when(commonDoctorServiceImpl
+ .updateBenClinicalObservations(org.mockito.ArgumentMatchers.any())).thenReturn(0);
+
+ org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class,
+ () -> service.updateGeneralOPDQCDoctorData(doctorRequest(), "Bearer session-token"));
+ }
+
+ @Test
+ @DisplayName("updateBeneficiaryClinicalObservations should attach the SNOMED code for the entered symptoms")
+ void updateObservations_shouldAttachSnomedCode() throws Exception {
+ org.mockito.Mockito.when(commonDoctorServiceImpl.getSnomedCTcode("fever"))
+ .thenReturn(new String[] { "386661006", "Fever" });
+ org.mockito.Mockito.when(commonDoctorServiceImpl
+ .updateBenClinicalObservations(org.mockito.ArgumentMatchers.any())).thenReturn(1);
+
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.updateBeneficiaryClinicalObservations(
+ com.google.gson.JsonParser.parseString("{\"otherSymptoms\":\"fever\"}").getAsJsonObject()));
+
+ org.mockito.ArgumentCaptor captor =
+ org.mockito.ArgumentCaptor.forClass(
+ com.iemr.tm.data.quickConsultation.BenClinicalObservations.class);
+ org.mockito.Mockito.verify(commonDoctorServiceImpl).updateBenClinicalObservations(captor.capture());
+ org.junit.jupiter.api.Assertions.assertEquals("386661006", captor.getValue().getOtherSymptomsSCTCode());
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/registrar/RegistrarServiceImplTest.java b/src/test/java/com/iemr/tm/service/registrar/RegistrarServiceImplTest.java
new file mode 100644
index 00000000..18081d5e
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/registrar/RegistrarServiceImplTest.java
@@ -0,0 +1,837 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.registrar;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.registrar.BeneficiaryDemographicAdditionalRepo;
+import com.iemr.tm.repo.registrar.BeneficiaryImageRepo;
+import com.iemr.tm.repo.registrar.RegistrarRepoBenData;
+import com.iemr.tm.repo.registrar.RegistrarRepoBenDemoData;
+import com.iemr.tm.repo.registrar.RegistrarRepoBenGovIdMapping;
+import com.iemr.tm.repo.registrar.RegistrarRepoBenPhoneMapData;
+import com.iemr.tm.repo.registrar.RegistrarRepoBeneficiaryDetails;
+import com.iemr.tm.repo.registrar.ReistrarRepoBenSearch;
+import com.iemr.tm.service.benFlowStatus.CommonBenStatusFlowServiceImpl;
+import com.iemr.tm.utils.CookieUtil;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("RegistrarServiceImpl Test Suite")
+class RegistrarServiceImplTest {
+
+ @Mock
+ private RegistrarRepoBenData registrarRepoBenData;
+ @Mock
+ private RegistrarRepoBenDemoData registrarRepoBenDemoData;
+ @Mock
+ private RegistrarRepoBenPhoneMapData registrarRepoBenPhoneMapData;
+ @Mock
+ private RegistrarRepoBenGovIdMapping registrarRepoBenGovIdMapping;
+ @Mock
+ private ReistrarRepoBenSearch reistrarRepoBenSearch;
+ @Mock
+ private BeneficiaryDemographicAdditionalRepo beneficiaryDemographicAdditionalRepo;
+ @Mock
+ private RegistrarRepoBeneficiaryDetails registrarRepoBeneficiaryDetails;
+ @Mock
+ private BeneficiaryImageRepo beneficiaryImageRepo;
+ @Mock
+ private CommonBenStatusFlowServiceImpl commonBenStatusFlowServiceImpl;
+ @Mock
+ private CookieUtil cookieUtil;
+
+ @InjectMocks
+ private RegistrarServiceImpl service;
+
+ @Test
+ @DisplayName("createBeneficiary should answer for a well formed request")
+ void createBeneficiary_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.createBeneficiary(new com.google.gson.JsonObject()));
+ }
+
+ @Test
+ @DisplayName("createBeneficiaryDemographic should answer for a well formed request")
+ void createBeneficiaryDemographic_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.createBeneficiaryDemographic(new com.google.gson.JsonObject(), 11L));
+ }
+
+ @Test
+ @DisplayName("createBeneficiaryDemographicAdditional should answer for a well formed request")
+ void createBeneficiaryDemographicAdditional_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.createBeneficiaryDemographicAdditional(new com.google.gson.JsonObject(), 11L));
+ }
+
+ @Test
+ @DisplayName("createBeneficiaryImage should reject a request it cannot act on")
+ void createBeneficiaryImage_shouldRejectRequestItCannotActOn() {
+ assertThrows(NullPointerException.class, () -> service.createBeneficiaryImage(new com.google.gson.JsonObject(), 11L));
+ }
+
+ @Test
+ @DisplayName("createBeneficiaryPhoneMapping should answer for a well formed request")
+ void createBeneficiaryPhoneMapping_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.createBeneficiaryPhoneMapping(new com.google.gson.JsonObject(), 11L));
+ }
+
+ @Test
+ @DisplayName("createBenGovIdMapping should reject a request it cannot act on")
+ void createBenGovIdMapping_shouldRejectRequestItCannotActOn() {
+ assertThrows(NullPointerException.class, () -> service.createBenGovIdMapping(new com.google.gson.JsonObject(), 11L));
+ }
+
+ @Test
+ @DisplayName("getRegWorkList should answer for a well formed request")
+ void getRegWorkList_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getRegWorkList(9));
+ }
+
+ @Test
+ @DisplayName("getQuickSearchBenData should answer for a well formed request")
+ void getQuickSearchBenData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getQuickSearchBenData("{}"));
+ }
+
+ @Test
+ @DisplayName("getAdvanceSearchBenData should answer for a well formed request")
+ void getAdvanceSearchBenData_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getAdvanceSearchBenData(new com.iemr.tm.data.registrar.V_BenAdvanceSearch()));
+ }
+
+ @Test
+ @DisplayName("getBenOBJ should answer for a well formed request")
+ void getBenOBJ_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenOBJ(new com.google.gson.JsonObject()));
+ }
+
+ @Test
+ @DisplayName("getBenDemoOBJ should answer for a well formed request")
+ void getBenDemoOBJ_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenDemoOBJ(new com.google.gson.JsonObject(), 11L));
+ }
+
+ @Test
+ @DisplayName("getBenPhoneOBJ should answer for a well formed request")
+ void getBenPhoneOBJ_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenPhoneOBJ(new com.google.gson.JsonObject(), 11L));
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryDetails should answer for a well formed request")
+ void getBeneficiaryDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBeneficiaryDetails(11L));
+ }
+
+ @Test
+ @DisplayName("getBenImage should answer for a well formed request")
+ void getBenImage_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBenImage(11L));
+ }
+
+ @Test
+ @DisplayName("updateBeneficiary should answer for a well formed request")
+ void updateBeneficiary_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateBeneficiary(new com.google.gson.JsonObject()));
+ }
+
+ @Test
+ @DisplayName("updateBeneficiaryDemographic should answer for a well formed request")
+ void updateBeneficiaryDemographic_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateBeneficiaryDemographic(new com.google.gson.JsonObject(), 11L));
+ }
+
+ @Test
+ @DisplayName("updateBeneficiaryPhoneMapping should answer for a well formed request")
+ void updateBeneficiaryPhoneMapping_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateBeneficiaryPhoneMapping(new com.google.gson.JsonObject(), 11L));
+ }
+
+ @Test
+ @DisplayName("updateBenGovIdMapping should reject a request it cannot act on")
+ void updateBenGovIdMapping_shouldRejectRequestItCannotActOn() {
+ assertThrows(NullPointerException.class, () -> service.updateBenGovIdMapping(new com.google.gson.JsonObject(), 11L));
+ }
+
+ @Test
+ @DisplayName("updateBeneficiaryDemographicAdditional should reject a request it cannot act on")
+ void updateBeneficiaryDemographicAdditional_shouldRejectRequestItCannotActOn() {
+ assertThrows(NullPointerException.class, () -> service.updateBeneficiaryDemographicAdditional(new com.google.gson.JsonObject(), 11L));
+ }
+
+ @Test
+ @DisplayName("updateBeneficiaryImage should answer for a well formed request")
+ void updateBeneficiaryImage_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.updateBeneficiaryImage(new com.google.gson.JsonObject(), 11L));
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryPersonalDetails should answer for a well formed request")
+ void getBeneficiaryPersonalDetails_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.getBeneficiaryPersonalDetails(11L));
+ }
+
+ @Test
+ @DisplayName("registerBeneficiary should reject a request it cannot act on")
+ void registerBeneficiary_shouldRejectRequestItCannotActOn() {
+ assertThrows(IllegalArgumentException.class, () -> service.registerBeneficiary("{}", "{}"));
+ }
+
+ @Test
+ @DisplayName("updateBeneficiary should reject a request it cannot act on (identity overload)")
+ void updateBeneficiary_identityOverload_shouldRejectRequestItCannotActOn() {
+ assertThrows(IllegalArgumentException.class, () -> service.updateBeneficiary("{}", "{}"));
+ }
+
+ @Test
+ @DisplayName("beneficiaryQuickSearch should answer for a well formed request")
+ void beneficiaryQuickSearch_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.beneficiaryQuickSearch("{}", "{}"));
+ }
+
+ @Test
+ @DisplayName("beneficiaryAdvanceSearch should reject a request it cannot act on")
+ void beneficiaryAdvanceSearch_shouldRejectRequestItCannotActOn() {
+ assertThrows(IllegalArgumentException.class, () -> service.beneficiaryAdvanceSearch("{}", "{}"));
+ }
+
+ @Test
+ @DisplayName("searchAndSubmitBeneficiaryToNurse should answer for a well formed request")
+ void searchAndSubmitBeneficiaryToNurse_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.searchAndSubmitBeneficiaryToNurse("{}"));
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("beneficiary payload mapping")
+ class PayloadMappingTests {
+
+ /** A registration payload with every optional field the registrar screen can send. */
+ private com.google.gson.JsonObject fullPayload() {
+ return com.google.gson.JsonParser.parseString("{"
+ + "\"firstName\":\"Asha\",\"lastName\":\"Devi\",\"gender\":2,\"dob\":\"1995-04-12T00:00:00.000\","
+ + "\"maritalStatus\":1,\"createdBy\":\"registrar1\",\"fatherName\":\"Ram\","
+ + "\"husbandName\":\"Shyam\",\"aadharNo\":\"1234\",\"beneficiaryRegID\":11,"
+ + "\"modifiedBy\":\"registrar1\",\"countryID\":1,\"stateID\":2,\"districtID\":3,\"blockID\":4,"
+ + "\"servicePointID\":5,\"villageID\":6,\"community\":7,\"religion\":8,\"income\":9,"
+ + "\"literacyStatus\":\"Literate\",\"educationQualification\":10,\"occupation\":11,"
+ + "\"phoneNo\":\"9999999999\",\"emailID\":\"asha@example.org\",\"bankName\":\"SBI\","
+ + "\"branchName\":\"Main\",\"IFSCCode\":\"SBIN0001\",\"accountNumber\":\"123456\","
+ + "\"habitation\":\"Colony\",\"ageAtMarriage\":21,\"image\":\"base64\","
+ + "\"govID\":[{\"type\":1,\"value\":\"1234\"}]}").getAsJsonObject();
+ }
+
+ @Test
+ @DisplayName("getBenOBJ should map every captured personal field")
+ void getBenOBJ_shouldMapEveryCapturedField() {
+ com.iemr.tm.data.registrar.BeneficiaryData result = service.getBenOBJ(fullPayload());
+
+ org.junit.jupiter.api.Assertions.assertEquals("Asha", result.getFirstName());
+ org.junit.jupiter.api.Assertions.assertEquals("Devi", result.getLastName());
+ org.junit.jupiter.api.Assertions.assertEquals("Ram", result.getFatherName());
+ org.junit.jupiter.api.Assertions.assertEquals(11L, result.getBeneficiaryRegID());
+ }
+
+ @Test
+ @DisplayName("getBenOBJ should map a payload that carries only the mandatory fields")
+ void getBenOBJ_shouldMapMinimalPayload() {
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getBenOBJ(
+ com.google.gson.JsonParser.parseString("{\"firstName\":\"Asha\"}").getAsJsonObject()));
+ }
+
+ @Test
+ @DisplayName("getBenDemoOBJ should map every captured demographic field")
+ void getBenDemoOBJ_shouldMapEveryCapturedField() {
+ com.iemr.tm.data.registrar.BeneficiaryDemographicData result = service.getBenDemoOBJ(fullPayload(), 11L);
+
+ org.junit.jupiter.api.Assertions.assertEquals(11L, result.getBeneficiaryRegID());
+ org.junit.jupiter.api.Assertions.assertEquals(2, result.getStateID());
+ }
+
+ @Test
+ @DisplayName("getBenDemoOBJ should map a payload that carries no demographic field")
+ void getBenDemoOBJ_shouldMapEmptyDemographics() {
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getBenDemoOBJ(
+ com.google.gson.JsonParser.parseString("{}").getAsJsonObject(), 11L));
+ }
+
+ @Test
+ @DisplayName("getBenPhoneOBJ should map the captured phone number")
+ void getBenPhoneOBJ_shouldMapCapturedPhoneNumber() {
+ com.iemr.tm.data.registrar.BeneficiaryPhoneMapping result = service.getBenPhoneOBJ(fullPayload(), 11L);
+
+ org.junit.jupiter.api.Assertions.assertEquals("9999999999", result.getPhoneNo());
+ }
+
+ @Test
+ @DisplayName("getBenPhoneOBJ should map a payload that carries no phone number")
+ void getBenPhoneOBJ_shouldMapEmptyPhoneMapping() {
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getBenPhoneOBJ(
+ com.google.gson.JsonParser.parseString("{}").getAsJsonObject(), 11L));
+ }
+
+ @Test
+ @DisplayName("createBeneficiary should store the mapped beneficiary")
+ void createBeneficiary_shouldStoreMappedBeneficiary() {
+ com.iemr.tm.data.registrar.BeneficiaryData stored = new com.iemr.tm.data.registrar.BeneficiaryData();
+ stored.setBeneficiaryRegID(11L);
+ org.mockito.Mockito.when(registrarRepoBenData.save(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(stored);
+
+ org.junit.jupiter.api.Assertions.assertEquals(11L,
+ service.createBeneficiary(fullPayload()).getBeneficiaryRegID());
+ }
+
+ @Test
+ @DisplayName("createBeneficiaryDemographic should store the mapped demographics")
+ void createBeneficiaryDemographic_shouldStoreMappedDemographics() {
+ com.iemr.tm.data.registrar.BeneficiaryDemographicData stored =
+ new com.iemr.tm.data.registrar.BeneficiaryDemographicData();
+ stored.setBenDemographicsID(4L);
+ org.mockito.Mockito.when(registrarRepoBenDemoData.save(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(stored);
+
+ org.junit.jupiter.api.Assertions.assertEquals(4L,
+ service.createBeneficiaryDemographic(fullPayload(), 11L));
+ }
+
+ @Test
+ @DisplayName("createBeneficiaryPhoneMapping should store the mapped phone number")
+ void createBeneficiaryPhoneMapping_shouldStoreMappedPhoneNumber() {
+ com.iemr.tm.data.registrar.BeneficiaryPhoneMapping stored =
+ new com.iemr.tm.data.registrar.BeneficiaryPhoneMapping();
+ stored.setBenPhMapID(4L);
+ org.mockito.Mockito.when(registrarRepoBenPhoneMapData.save(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(stored);
+
+ org.junit.jupiter.api.Assertions.assertEquals(4L,
+ service.createBeneficiaryPhoneMapping(fullPayload(), 11L));
+ }
+
+ @Test
+ @DisplayName("createBenGovIdMapping should store every captured government id")
+ void createBenGovIdMapping_shouldStoreCapturedGovernmentIds() {
+ org.mockito.Mockito.when(registrarRepoBenGovIdMapping.saveAll(org.mockito.ArgumentMatchers.any()))
+ .thenAnswer(invocation -> invocation.getArgument(0));
+
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.createBenGovIdMapping(fullPayload(), 11L));
+ }
+
+ @Test
+ @DisplayName("updateBeneficiary should update the mapped beneficiary")
+ void updateBeneficiary_shouldUpdateMappedBeneficiary() {
+ org.mockito.Mockito.when(registrarRepoBenData.updateBeneficiaryData(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any())).thenReturn(1);
+
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.updateBeneficiary(fullPayload()));
+ }
+
+ @Test
+ @DisplayName("getRegWorkList should render the registrar worklist")
+ void getRegWorkList_shouldRenderWorklist() {
+ org.mockito.Mockito.when(registrarRepoBenData.getRegistrarWorkList(9))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getRegWorkList(9));
+ }
+
+ @Test
+ @DisplayName("getQuickSearchBenData should render the matched beneficiaries")
+ void getQuickSearchBenData_shouldRenderMatches() {
+ org.mockito.Mockito.when(reistrarRepoBenSearch.getQuickSearch("BEN1"))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getQuickSearchBenData("BEN1"));
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryDetails should render the stored beneficiary")
+ void getBeneficiaryDetails_shouldRenderStoredBeneficiary() {
+ org.mockito.Mockito.when(registrarRepoBeneficiaryDetails.getBeneficiaryDetails(11L))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertNull(service.getBeneficiaryDetails(11L));
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryPersonalDetails should render the stored personal details")
+ void getBeneficiaryPersonalDetails_shouldRenderStoredDetails() {
+ org.mockito.Mockito.when(registrarRepoBenDemoData.getBeneficiaryDemographicData(11L))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertNull(service.getBeneficiaryPersonalDetails(11L));
+ }
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("common API integration")
+ class CommonApiIntegrationTests {
+
+ private static final String REGISTERED = "{\"data\":{\"beneficiaryRegID\":11,\"beneficiaryID\":9}}";
+
+ @org.junit.jupiter.api.BeforeEach
+ void stubConfiguredUrls() {
+ org.springframework.test.util.ReflectionTestUtils.setField(service, "registrationUrl",
+ "http://common/registrar/registerBeneficiary");
+ org.springframework.test.util.ReflectionTestUtils.setField(service, "beneficiaryEditUrl",
+ "http://common/registrar/editBeneficiary");
+ org.springframework.test.util.ReflectionTestUtils.setField(service, "registrarQuickSearchByIdUrl",
+ "http://common/registrar/quickSearchById");
+ org.springframework.test.util.ReflectionTestUtils.setField(service, "registrarQuickSearchByPhoneNoUrl",
+ "http://common/registrar/quickSearchByPhoneNo");
+ org.springframework.test.util.ReflectionTestUtils.setField(service, "registrarAdvanceSearchUrl",
+ "http://common/registrar/advanceSearch");
+ }
+
+ /** Stands in for the Common-API call the service makes through its own RestTemplate. */
+ private org.mockito.MockedConstruction respondWith(
+ org.springframework.http.ResponseEntity reply) {
+ return org.mockito.Mockito.mockConstruction(org.springframework.web.client.RestTemplate.class,
+ (restTemplate, context) -> org.mockito.Mockito.when(restTemplate.exchange(
+ org.mockito.ArgumentMatchers.anyString(),
+ org.mockito.ArgumentMatchers.any(org.springframework.http.HttpMethod.class),
+ org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.>any())).thenReturn(reply));
+ }
+
+ private org.springframework.http.ResponseEntity ok(String body) {
+ return new org.springframework.http.ResponseEntity<>(body, org.springframework.http.HttpStatus.OK);
+ }
+
+ @Test
+ @DisplayName("registerBeneficiary should create the beneficiary flow record for a van registration")
+ void registerBeneficiary_shouldCreateFlowRecord() throws Exception {
+ org.mockito.Mockito.when(commonBenStatusFlowServiceImpl.createBenFlowRecord(
+ org.mockito.ArgumentMatchers.anyString(), org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong())).thenReturn(1);
+
+ try (org.mockito.MockedConstruction ignored =
+ respondWith(ok(REGISTERED))) {
+ String result = service.registerBeneficiary("{\"firstName\":\"Asha\"}", "Bearer session-token");
+
+ org.junit.jupiter.api.Assertions.assertTrue(result.contains("Beneficiary successfully registered"));
+ org.junit.jupiter.api.Assertions.assertTrue(result.contains("benGenId"));
+ }
+ }
+
+ @Test
+ @DisplayName("registerBeneficiary should skip the flow record for a mobile registration")
+ void registerBeneficiary_shouldSkipFlowRecordForMobile() throws Exception {
+ try (org.mockito.MockedConstruction ignored =
+ respondWith(ok(REGISTERED))) {
+ org.junit.jupiter.api.Assertions.assertTrue(service
+ .registerBeneficiary("{\"isMobile\":true}", "Bearer session-token")
+ .contains("Beneficiary successfully registered"));
+ }
+
+ org.mockito.Mockito.verify(commonBenStatusFlowServiceImpl, org.mockito.Mockito.never())
+ .createBenFlowRecord(org.mockito.ArgumentMatchers.anyString(),
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyLong());
+ }
+
+ @Test
+ @DisplayName("registerBeneficiary should report an error when the flow record could not be created")
+ void registerBeneficiary_shouldReportFlowRecordFailure() throws Exception {
+ org.mockito.Mockito.when(commonBenStatusFlowServiceImpl.createBenFlowRecord(
+ org.mockito.ArgumentMatchers.anyString(), org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong())).thenReturn(0);
+
+ try (org.mockito.MockedConstruction ignored =
+ respondWith(ok(REGISTERED))) {
+ org.junit.jupiter.api.Assertions.assertTrue(service
+ .registerBeneficiary("{\"firstName\":\"Asha\"}", "Bearer session-token")
+ .contains("please contact administrator"));
+ }
+ }
+
+ @Test
+ @DisplayName("registerBeneficiary should answer with an empty response when the common API rejects the request")
+ void registerBeneficiary_shouldAnswerEmptyWhenCommonApiRejects() throws Exception {
+ try (org.mockito.MockedConstruction ignored = respondWith(
+ new org.springframework.http.ResponseEntity<>(org.springframework.http.HttpStatus.BAD_REQUEST))) {
+ org.junit.jupiter.api.Assertions.assertNotNull(
+ service.registerBeneficiary("{\"firstName\":\"Asha\"}", "Bearer session-token"));
+ }
+ }
+
+ @Test
+ @DisplayName("updateBeneficiary should pass the beneficiary to the nurse when asked")
+ void updateBeneficiary_shouldPassToNurse() throws Exception {
+ org.mockito.Mockito.when(commonBenStatusFlowServiceImpl.createBenFlowRecord(
+ org.mockito.ArgumentMatchers.anyString(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any())).thenReturn(3);
+
+ try (org.mockito.MockedConstruction ignored =
+ respondWith(ok("{}"))) {
+ org.junit.jupiter.api.Assertions.assertEquals(3, service
+ .updateBeneficiary("{\"passToNurse\":true}", "Bearer session-token"));
+ }
+ }
+
+ @Test
+ @DisplayName("updateBeneficiary should only confirm the edit when the beneficiary stays with the registrar")
+ void updateBeneficiary_shouldOnlyConfirmEdit() throws Exception {
+ try (org.mockito.MockedConstruction ignored =
+ respondWith(ok("{}"))) {
+ org.junit.jupiter.api.Assertions.assertEquals(1, service
+ .updateBeneficiary("{\"passToNurse\":false}", "Bearer session-token"));
+ }
+ }
+
+ @Test
+ @DisplayName("updateBeneficiary should answer with nothing when the common API rejects the edit")
+ void updateBeneficiary_shouldAnswerNothingWhenRejected() throws Exception {
+ try (org.mockito.MockedConstruction ignored = respondWith(
+ new org.springframework.http.ResponseEntity<>(org.springframework.http.HttpStatus.BAD_REQUEST))) {
+ org.junit.jupiter.api.Assertions.assertNull(
+ service.updateBeneficiary("{\"passToNurse\":false}", "Bearer session-token"));
+ }
+ }
+
+ @Test
+ @DisplayName("beneficiaryQuickSearch should search by beneficiary id when one is supplied")
+ void quickSearch_shouldSearchByBeneficiaryId() throws Exception {
+ try (org.mockito.MockedConstruction ignored =
+ respondWith(ok("{\"data\":[]}"))) {
+ org.junit.jupiter.api.Assertions.assertEquals("{\"data\":[]}",
+ service.beneficiaryQuickSearch("{\"beneficiaryID\":\"9\"}", "Bearer session-token"));
+ }
+ }
+
+ @Test
+ @DisplayName("beneficiaryQuickSearch should search by ABHA number when one is supplied")
+ void quickSearch_shouldSearchByHealthIdNumber() throws Exception {
+ try (org.mockito.MockedConstruction ignored =
+ respondWith(ok("{\"data\":[]}"))) {
+ org.junit.jupiter.api.Assertions.assertNotNull(
+ service.beneficiaryQuickSearch("{\"HealthIDNumber\":\"12-34\"}", "Bearer session-token"));
+ }
+ }
+
+ @Test
+ @DisplayName("beneficiaryQuickSearch should search by phone number when no identifier is supplied")
+ void quickSearch_shouldSearchByPhoneNumber() throws Exception {
+ try (org.mockito.MockedConstruction ignored =
+ respondWith(ok("{\"data\":[]}"))) {
+ org.junit.jupiter.api.Assertions.assertNotNull(
+ service.beneficiaryQuickSearch("{\"phoneNo\":\"9999999999\"}", "Bearer session-token"));
+ }
+ }
+
+ @Test
+ @DisplayName("beneficiaryQuickSearch should answer with nothing when the request has no search key")
+ void quickSearch_shouldAnswerNothingWithoutSearchKey() throws Exception {
+ try (org.mockito.MockedConstruction ignored =
+ respondWith(ok("{\"data\":[]}"))) {
+ org.junit.jupiter.api.Assertions.assertNull(
+ service.beneficiaryQuickSearch("{}", "Bearer session-token"));
+ }
+ }
+
+ @Test
+ @DisplayName("beneficiaryAdvanceSearch should return the common API response")
+ void advanceSearch_shouldReturnCommonApiResponse() throws Exception {
+ try (org.mockito.MockedConstruction ignored =
+ respondWith(ok("{\"data\":[]}"))) {
+ org.junit.jupiter.api.Assertions.assertEquals("{\"data\":[]}",
+ service.beneficiaryAdvanceSearch("{\"firstName\":\"Asha\"}", "Bearer session-token"));
+ }
+ }
+
+ @Test
+ @DisplayName("searchAndSubmitBeneficiaryToNurse should create the beneficiary flow record")
+ void searchAndSubmit_shouldCreateFlowRecord() throws Exception {
+ org.mockito.Mockito.when(commonBenStatusFlowServiceImpl.createBenFlowRecord(
+ org.mockito.ArgumentMatchers.anyString(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any())).thenReturn(1);
+
+ org.junit.jupiter.api.Assertions.assertEquals(1,
+ service.searchAndSubmitBeneficiaryToNurse("{\"beneficiaryRegID\":11}"));
+ }
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("beneficiary record maintenance")
+ class BeneficiaryRecordTests {
+
+ private static final String DEMOGRAPHIC_ADDITIONAL = "{\"literacyStatus\":\"Literate\","
+ + "\"motherName\":\"Sita\",\"emailID\":\"asha@example.org\",\"bankName\":\"SBI\","
+ + "\"branchName\":\"Kamptee\",\"IFSCCode\":\"SBIN0001\",\"accountNumber\":\"12345\","
+ + "\"createdBy\":\"registrar1\",\"modifiedBy\":\"registrar1\",\"benDemoAdditionalID\":4,"
+ + "\"ageAtMarriage\":22,\"age\":31}";
+
+ private com.google.gson.JsonObject json(String raw) {
+ return com.google.gson.JsonParser.parseString(raw).getAsJsonObject();
+ }
+
+ @Test
+ @DisplayName("createBeneficiaryDemographicAdditional should map every additional detail before storing")
+ void createDemographicAdditional_shouldMapEveryDetail() {
+ com.iemr.tm.data.registrar.BeneficiaryDemographicAdditional stored =
+ new com.iemr.tm.data.registrar.BeneficiaryDemographicAdditional();
+ stored.setBenDemoAdditionalID(4L);
+ org.mockito.Mockito.when(beneficiaryDemographicAdditionalRepo.save(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(stored);
+
+ org.junit.jupiter.api.Assertions.assertEquals(4L,
+ service.createBeneficiaryDemographicAdditional(json(DEMOGRAPHIC_ADDITIONAL), 11L));
+
+ org.mockito.ArgumentCaptor captor =
+ org.mockito.ArgumentCaptor.forClass(
+ com.iemr.tm.data.registrar.BeneficiaryDemographicAdditional.class);
+ org.mockito.Mockito.verify(beneficiaryDemographicAdditionalRepo).save(captor.capture());
+ com.iemr.tm.data.registrar.BeneficiaryDemographicAdditional saved = captor.getValue();
+ org.junit.jupiter.api.Assertions.assertEquals("Literate", saved.getLiteracyStatus());
+ org.junit.jupiter.api.Assertions.assertEquals("Sita", saved.getMotherName());
+ org.junit.jupiter.api.Assertions.assertEquals("asha@example.org", saved.getEmailID());
+ org.junit.jupiter.api.Assertions.assertEquals("SBI", saved.getBankName());
+ org.junit.jupiter.api.Assertions.assertEquals("Kamptee", saved.getBranchName());
+ org.junit.jupiter.api.Assertions.assertEquals("SBIN0001", saved.getiFSCCode());
+ org.junit.jupiter.api.Assertions.assertEquals("12345", saved.getAccountNo());
+ org.junit.jupiter.api.Assertions.assertNotNull(saved.getMarrigeDate());
+ }
+
+ @Test
+ @DisplayName("createBeneficiaryImage should store the captured photograph")
+ void createBeneficiaryImage_shouldStoreCapturedPhotograph() {
+ com.iemr.tm.data.registrar.BeneficiaryImage stored =
+ new com.iemr.tm.data.registrar.BeneficiaryImage();
+ stored.setBeneficiaryRegID(11L);
+ org.mockito.Mockito.when(beneficiaryImageRepo.save(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(stored);
+
+ org.junit.jupiter.api.Assertions.assertEquals(11L, service.createBeneficiaryImage(
+ json("{\"image\":\"base64-photo\",\"createdBy\":\"registrar1\"}"), 11L));
+ }
+
+ @Test
+ @DisplayName("createBeneficiaryImage should report a photograph it could not store")
+ void createBeneficiaryImage_shouldReportUnstoredPhotograph() {
+ org.mockito.Mockito.when(beneficiaryImageRepo.save(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(null);
+
+ org.junit.jupiter.api.Assertions.assertNull(service.createBeneficiaryImage(
+ json("{\"image\":\"base64-photo\",\"createdBy\":\"registrar1\"}"), 11L));
+ }
+
+ @Test
+ @DisplayName("updateBeneficiaryDemographicAdditional should update the stored additional details")
+ void updateDemographicAdditional_shouldUpdateStoredDetails() {
+ org.mockito.Mockito.when(beneficiaryDemographicAdditionalRepo
+ .getBeneficiaryDemographicAdditional(11L))
+ .thenReturn(new com.iemr.tm.data.registrar.BeneficiaryDemographicAdditional());
+ org.mockito.Mockito.when(beneficiaryDemographicAdditionalRepo
+ .updateBeneficiaryDemographicAdditional(org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any()))
+ .thenReturn(1);
+
+ org.junit.jupiter.api.Assertions.assertEquals(1,
+ service.updateBeneficiaryDemographicAdditional(json(DEMOGRAPHIC_ADDITIONAL), 11L));
+ }
+
+ @Test
+ @DisplayName("updateBeneficiaryDemographicAdditional should store the details when none were recorded before")
+ void updateDemographicAdditional_shouldStoreWhenNoneRecorded() {
+ com.iemr.tm.data.registrar.BeneficiaryDemographicAdditional stored =
+ new com.iemr.tm.data.registrar.BeneficiaryDemographicAdditional();
+ stored.setBenDemoAdditionalID(4L);
+ org.mockito.Mockito.when(beneficiaryDemographicAdditionalRepo
+ .getBeneficiaryDemographicAdditional(11L)).thenReturn(null);
+ org.mockito.Mockito.when(beneficiaryDemographicAdditionalRepo.save(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(stored);
+
+ org.junit.jupiter.api.Assertions.assertEquals(1,
+ service.updateBeneficiaryDemographicAdditional(json(DEMOGRAPHIC_ADDITIONAL), 11L));
+ }
+
+ @Test
+ @DisplayName("updateBeneficiaryImage should update the stored photograph")
+ void updateBeneficiaryImage_shouldUpdateStoredPhotograph() {
+ org.mockito.Mockito.when(beneficiaryImageRepo.findBenImage(11L)).thenReturn(11L);
+ org.mockito.Mockito.when(beneficiaryImageRepo.updateBeneficiaryImage(
+ org.mockito.ArgumentMatchers.anyString(), org.mockito.ArgumentMatchers.anyString(),
+ org.mockito.ArgumentMatchers.anyLong())).thenReturn(1);
+
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.updateBeneficiaryImage(
+ json("{\"image\":\"base64-photo\",\"createdBy\":\"registrar1\",\"benImageID\":4,"
+ + "\"modifiedBy\":\"registrar1\"}"), 11L));
+ }
+
+ @Test
+ @DisplayName("updateBeneficiaryImage should store the photograph when none was recorded before")
+ void updateBeneficiaryImage_shouldStoreWhenNoneRecorded() {
+ com.iemr.tm.data.registrar.BeneficiaryImage stored =
+ new com.iemr.tm.data.registrar.BeneficiaryImage();
+ stored.setBenImageID(4L);
+ org.mockito.Mockito.when(beneficiaryImageRepo.findBenImage(11L)).thenReturn(null);
+ org.mockito.Mockito.when(beneficiaryImageRepo.save(org.mockito.ArgumentMatchers.any()))
+ .thenReturn(stored);
+
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.updateBeneficiaryImage(
+ json("{\"image\":\"base64-photo\",\"createdBy\":\"registrar1\"}"), 11L));
+ }
+
+ @Test
+ @DisplayName("updateBeneficiaryImage should succeed when the request carries no photograph")
+ void updateBeneficiaryImage_shouldSucceedWithoutPhotograph() {
+ org.junit.jupiter.api.Assertions.assertEquals(1,
+ service.updateBeneficiaryImage(json("{\"createdBy\":\"registrar1\"}"), 11L));
+ }
+
+ /** One beneficiary details row as the details view returns it. */
+ private Object[] detailsRow(Boolean isGovType) {
+ Object[] values = new Object[35];
+ values[0] = 11L;
+ for (int i = 1; i < 35; i++) {
+ values[i] = "value";
+ }
+ values[4] = (short) 2;
+ values[5] = java.sql.Date.valueOf(java.time.LocalDate.now().minusYears(31));
+ values[6] = (short) 1;
+ values[8] = (short) 1;
+ values[9] = (short) 1;
+ values[10] = (short) 1;
+ values[11] = 21;
+ values[13] = 31;
+ values[15] = 41;
+ values[16] = (short) 1;
+ values[19] = 51;
+ values[21] = 61;
+ values[24] = (short) 1;
+ values[26] = isGovType;
+ values[27] = java.sql.Date.valueOf(java.time.LocalDate.now().minusYears(9));
+ return values;
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryDetails should split the government and other identity documents")
+ void getBeneficiaryDetails_shouldSplitIdentityDocuments() {
+ org.mockito.Mockito.when(registrarRepoBeneficiaryDetails.getBeneficiaryDetails(11L))
+ .thenReturn(new java.util.ArrayList<>(java.util.Arrays.asList(
+ detailsRow(Boolean.TRUE), detailsRow(Boolean.FALSE), detailsRow(null))));
+ org.mockito.Mockito.when(beneficiaryImageRepo.getBenImage(11L)).thenReturn("base64-photo");
+
+ String result = service.getBeneficiaryDetails(11L);
+
+ org.junit.jupiter.api.Assertions.assertNotNull(result);
+ org.junit.jupiter.api.Assertions.assertTrue(result.contains("base64-photo"));
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryDetails should answer with nothing for an unknown beneficiary")
+ void getBeneficiaryDetails_shouldAnswerWithNothingForUnknownBeneficiary() {
+ org.mockito.Mockito.when(registrarRepoBeneficiaryDetails.getBeneficiaryDetails(11L))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertNull(service.getBeneficiaryDetails(11L));
+ }
+
+ @org.junit.jupiter.params.ParameterizedTest
+ @org.junit.jupiter.params.provider.CsvSource({ "1,Male", "2,Female", "3,Transgender" })
+ @DisplayName("getBeneficiaryPersonalDetails should name the gender recorded against the beneficiary")
+ void getBeneficiaryPersonalDetails_shouldNameGender(short genderID, String genderName) {
+ java.util.List benRows = new java.util.ArrayList<>();
+ benRows.add(new Object[] { 11L, "Asha", "Devi",
+ java.sql.Date.valueOf(java.time.LocalDate.now().minusYears(31)), genderID,
+ new java.sql.Timestamp(System.currentTimeMillis()) });
+ org.mockito.Mockito.when(registrarRepoBenData.getBenDetailsByRegID(11L)).thenReturn(benRows);
+ java.util.List demoRows = new java.util.ArrayList<>();
+ demoRows.add(new Object[] { 11L, 41, "PHC Kamptee" });
+ org.mockito.Mockito.when(registrarRepoBenDemoData.getBeneficiaryDemographicData(11L))
+ .thenReturn(demoRows);
+
+ com.iemr.tm.data.registrar.BeneficiaryData details = service.getBeneficiaryPersonalDetails(11L);
+
+ org.junit.jupiter.api.Assertions.assertEquals(genderName, details.getGenderName());
+ org.junit.jupiter.api.Assertions.assertEquals("PHC Kamptee", details.getServicePointName());
+ }
+
+ @Test
+ @DisplayName("getBeneficiaryPersonalDetails should answer with nothing for an unknown beneficiary")
+ void getBeneficiaryPersonalDetails_shouldAnswerWithNothingForUnknownBeneficiary() {
+ org.mockito.Mockito.when(registrarRepoBenData.getBenDetailsByRegID(11L))
+ .thenReturn(new java.util.ArrayList<>());
+ org.mockito.Mockito.when(registrarRepoBenDemoData.getBeneficiaryDemographicData(11L))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertNull(service.getBeneficiaryPersonalDetails(11L));
+ }
+
+ @Test
+ @DisplayName("getQuickSearchBenData should render the matched beneficiaries")
+ void getQuickSearchBenData_shouldRenderMatchedBeneficiaries() {
+ org.mockito.Mockito.when(reistrarRepoBenSearch.getQuickSearch("7"))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertEquals("[]", service.getQuickSearchBenData("7"));
+ }
+
+ @Test
+ @DisplayName("getAdvanceSearchBenData should search with every supplied criterion")
+ void getAdvanceSearchBenData_shouldSearchWithEveryCriterion() {
+ com.iemr.tm.data.registrar.V_BenAdvanceSearch search =
+ new com.iemr.tm.data.registrar.V_BenAdvanceSearch();
+ search.setBeneficiaryID("7");
+ search.setFirstName("Asha");
+ search.setLastName("Devi");
+ search.setFatherName("Ram");
+ search.setPhoneNo("9999999999");
+ search.setAadharNo("1234");
+ search.setGovtIdentityNo("PAN-1");
+ search.setStateID(21);
+ search.setDistrictID(31);
+ org.mockito.Mockito.when(reistrarRepoBenSearch.getAdvanceBenSearchList("7", "Asha", "Devi",
+ "9999999999", "1234", "PAN-1", "21", "31")).thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertEquals("[]", service.getAdvanceSearchBenData(search));
+ }
+
+ @Test
+ @DisplayName("getAdvanceSearchBenData should search with wildcards when no criterion was supplied")
+ void getAdvanceSearchBenData_shouldSearchWithWildcards() {
+ org.mockito.Mockito.when(reistrarRepoBenSearch.getAdvanceBenSearchList(
+ org.mockito.ArgumentMatchers.anyString(), org.mockito.ArgumentMatchers.anyString(),
+ org.mockito.ArgumentMatchers.anyString(), org.mockito.ArgumentMatchers.anyString(),
+ org.mockito.ArgumentMatchers.anyString(), org.mockito.ArgumentMatchers.anyString(),
+ org.mockito.ArgumentMatchers.anyString(), org.mockito.ArgumentMatchers.anyString()))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertEquals("[]", service.getAdvanceSearchBenData(
+ new com.iemr.tm.data.registrar.V_BenAdvanceSearch()));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/report/CRMReportServiceImplTest.java b/src/test/java/com/iemr/tm/service/report/CRMReportServiceImplTest.java
new file mode 100644
index 00000000..3abdb125
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/report/CRMReportServiceImplTest.java
@@ -0,0 +1,185 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.report;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.login.UserParkingplaceMappingRepo;
+import com.iemr.tm.repo.report.BenChiefComplaintReportRepo;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("CRMReportServiceImpl Test Suite")
+class CRMReportServiceImplTest {
+
+ @Mock
+ private BenChiefComplaintReportRepo benChiefComplaintReportRepo;
+ @Mock
+ private UserParkingplaceMappingRepo userParkingplaceMappingRepo;
+
+ @InjectMocks
+ private CRMReportServiceImpl service;
+
+ @Test
+ @DisplayName("getParkingplaceID should reject a request that carries no beneficiary details")
+ void getParkingplaceID_shouldRejectRequestWithoutBeneficiaryDetails() {
+ assertThrows(Exception.class, () -> service.getParkingplaceID(9, 9));
+ }
+
+ @Test
+ @DisplayName("calculateTime should answer for a well formed request")
+ void calculateTime_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.calculateTime(new java.sql.Timestamp(1_700_000_000_000L), new java.sql.Timestamp(1_700_000_000_000L)));
+ }
+
+ @Test
+ @DisplayName("getChiefcomplaintreport should reject a request that carries no beneficiary details")
+ void getChiefcomplaintreport_shouldRejectRequestWithoutBeneficiaryDetails() {
+ assertThrows(Exception.class, () -> service.getChiefcomplaintreport(org.mockito.Mockito.mock(com.iemr.tm.data.report.ReportInput.class)));
+ }
+
+ @Test
+ @DisplayName("getConsultationReport should reject a request that carries no beneficiary details")
+ void getConsultationReport_shouldRejectRequestWithoutBeneficiaryDetails() {
+ assertThrows(Exception.class, () -> service.getConsultationReport(org.mockito.Mockito.mock(com.iemr.tm.data.report.ReportInput.class)));
+ }
+
+ @Test
+ @DisplayName("getTotalConsultationReport should reject a request that carries no beneficiary details")
+ void getTotalConsultationReport_shouldRejectRequestWithoutBeneficiaryDetails() {
+ assertThrows(Exception.class, () -> service.getTotalConsultationReport(org.mockito.Mockito.mock(com.iemr.tm.data.report.ReportInput.class)));
+ }
+
+ @Test
+ @DisplayName("getMonthlyReport should reject a request that carries no beneficiary details")
+ void getMonthlyReport_shouldRejectRequestWithoutBeneficiaryDetails() {
+ assertThrows(Exception.class, () -> service.getMonthlyReport(org.mockito.Mockito.mock(com.iemr.tm.data.report.ReportInput.class)));
+ }
+
+ @Test
+ @DisplayName("getDailyReport should reject a request that carries no beneficiary details")
+ void getDailyReport_shouldRejectRequestWithoutBeneficiaryDetails() {
+ assertThrows(Exception.class, () -> service.getDailyReport(org.mockito.Mockito.mock(com.iemr.tm.data.report.ReportInput.class)));
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("reports for a mapped user")
+ class MappedUserReportTests {
+
+ private com.iemr.tm.data.report.ReportInput input() {
+ com.iemr.tm.data.report.ReportInput input = new com.iemr.tm.data.report.ReportInput();
+ input.setUserID(42);
+ input.setProviderServiceMapID(9);
+ input.setVanID(7);
+ input.setFromDate(new java.sql.Date(1_700_000_000_000L));
+ input.setToDate(new java.sql.Date(1_700_600_000_000L));
+ return input;
+ }
+
+ @org.junit.jupiter.api.BeforeEach
+ void mapUserToParkingPlace() {
+ com.iemr.tm.data.login.UserParkingplaceMapping mapping =
+ new com.iemr.tm.data.login.UserParkingplaceMapping();
+ mapping.setParkingPlaceID(3);
+ org.mockito.Mockito.when(userParkingplaceMappingRepo
+ .findOneByUserIDAndProviderServiceMapIdAndDeleted(42, 9, 0)).thenReturn(mapping);
+ }
+
+ @Test
+ @DisplayName("getParkingplaceID should return the parking place the user is mapped to")
+ void getParkingplaceID_shouldReturnMappedParkingPlace() throws Exception {
+ org.junit.jupiter.api.Assertions.assertEquals(3, service.getParkingplaceID(42, 9));
+ }
+
+ @Test
+ @DisplayName("getChiefcomplaintreport should group the chief complaints by spoke")
+ void getChiefcomplaintreport_shouldGroupBySpoke() throws Exception {
+ java.util.List rows = new java.util.ArrayList<>();
+ rows.add(new Object[] { 1, "Fever", 7, "Van 7", 0, 0, 5L, 2L, 3L, 0L });
+ org.mockito.Mockito.when(benChiefComplaintReportRepo.getcmreport(org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.eq(3))).thenReturn(rows);
+
+ org.junit.jupiter.api.Assertions.assertFalse(service.getChiefcomplaintreport(input()).isEmpty());
+ }
+
+ @Test
+ @DisplayName("getChiefcomplaintreport should return nothing when no complaint was recorded")
+ void getChiefcomplaintreport_shouldReturnNothingWithoutComplaints() throws Exception {
+ org.mockito.Mockito.when(benChiefComplaintReportRepo.getcmreport(org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.eq(3)))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertTrue(service.getChiefcomplaintreport(input()).isEmpty());
+ }
+
+ @Test
+ @DisplayName("getConsultationReport should return the consultations for the window")
+ void getConsultationReport_shouldReturnConsultations() throws Exception {
+ org.mockito.Mockito.when(benChiefComplaintReportRepo.getConsultationReport(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.eq(3))).thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getConsultationReport(input()));
+ }
+
+ @Test
+ @DisplayName("getTotalConsultationReport should return the totals for the window")
+ void getTotalConsultationReport_shouldReturnTotals() throws Exception {
+ org.mockito.Mockito.when(benChiefComplaintReportRepo.getTotalConsultationReport(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.eq(3))).thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getTotalConsultationReport(input()));
+ }
+
+ @Test
+ @DisplayName("getMonthlyReport should return a column per month in the window")
+ void getMonthlyReport_shouldReturnColumnPerMonth() throws Exception {
+ java.util.List rows = new java.util.ArrayList<>();
+ rows.add(new Object[] { "Total Consultations", "Nov-23", 4 });
+ org.mockito.Mockito.when(benChiefComplaintReportRepo.getMonthlyReport(org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.eq(3),
+ org.mockito.ArgumentMatchers.any())).thenReturn(rows);
+
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getMonthlyReport(input()));
+ }
+
+ @Test
+ @DisplayName("getDailyReport should return the visits for the day")
+ void getDailyReport_shouldReturnVisitsForTheDay() throws Exception {
+ org.mockito.Mockito.when(benChiefComplaintReportRepo.getDailyReport(org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.eq(3))).thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertNotNull(service.getDailyReport(input()));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/snomedct/SnomedServiceImplTest.java b/src/test/java/com/iemr/tm/service/snomedct/SnomedServiceImplTest.java
new file mode 100644
index 00000000..f218312c
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/snomedct/SnomedServiceImplTest.java
@@ -0,0 +1,60 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.snomedct;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.snomedct.SnomedRepository;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("SnomedServiceImpl Test Suite")
+class SnomedServiceImplTest {
+
+ @Mock
+ private SnomedRepository snomedRepository;
+
+ @InjectMocks
+ private SnomedServiceImpl service;
+
+ @Test
+ @DisplayName("findSnomedCTRecordFromTerm should answer for a well formed request")
+ void findSnomedCTRecordFromTerm_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.findSnomedCTRecordFromTerm("{}"));
+ }
+
+ @Test
+ @DisplayName("findSnomedCTRecordList should reject a request that carries no beneficiary details")
+ void findSnomedCTRecordList_shouldRejectRequestWithoutBeneficiaryDetails() {
+ assertThrows(Exception.class, () -> service.findSnomedCTRecordList(new com.iemr.tm.data.snomedct.SCTDescription()));
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/tele_consultation/SMSGatewayServiceImplTest.java b/src/test/java/com/iemr/tm/service/tele_consultation/SMSGatewayServiceImplTest.java
new file mode 100644
index 00000000..b4293b88
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/tele_consultation/SMSGatewayServiceImplTest.java
@@ -0,0 +1,75 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.tele_consultation;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.tc_consultation.TCRequestModelRepo;
+import com.iemr.tm.utils.CookieUtil;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("SMSGatewayServiceImpl Test Suite")
+class SMSGatewayServiceImplTest {
+
+ @Mock
+ private TCRequestModelRepo tCRequestModelRepo;
+ @Mock
+ private CookieUtil cookieUtil;
+
+ @InjectMocks
+ private SMSGatewayServiceImpl service;
+
+ @Test
+ @DisplayName("smsSenderGateway should answer for a well formed request")
+ void smsSenderGateway_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.smsSenderGateway("{}", 11L, 9, 11L, 11L, "{}", "{}", "{}", "{}"));
+ }
+
+ @Test
+ @DisplayName("smsSenderGateway2 should answer for a well formed request")
+ void smsSenderGateway2_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.smsSenderGateway2("{}", new java.util.ArrayList<>(), "{}", 11L, "{}", new java.util.ArrayList<>()));
+ }
+
+ @Test
+ @DisplayName("createSMSRequest should answer for a well formed request")
+ void createSMSRequest_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.createSMSRequest("{}", 11L, 9, 11L, 11L, "{}", "{}", "{}"));
+ }
+
+ @Test
+ @DisplayName("sendSMS should reject a request it cannot act on")
+ void sendSMS_shouldRejectRequestItCannotActOn() {
+ assertThrows(NullPointerException.class, () -> service.sendSMS("{}", "{}"));
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/tele_consultation/TeleConsultationServiceImplTest.java b/src/test/java/com/iemr/tm/service/tele_consultation/TeleConsultationServiceImplTest.java
new file mode 100644
index 00000000..46f11767
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/tele_consultation/TeleConsultationServiceImplTest.java
@@ -0,0 +1,423 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.tele_consultation;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.benFlowStatus.BeneficiaryFlowStatusRepo;
+import com.iemr.tm.repo.tc_consultation.TCRequestModelRepo;
+import com.iemr.tm.repo.tc_consultation.TeleconsultationStatsRepo;
+import com.iemr.tm.service.common.transaction.CommonServiceImpl;
+import com.iemr.tm.utils.CookieUtil;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("TeleConsultationServiceImpl Test Suite")
+class TeleConsultationServiceImplTest {
+
+ @Mock
+ private TCRequestModelRepo tCRequestModelRepo;
+ @Mock
+ private BeneficiaryFlowStatusRepo beneficiaryFlowStatusRepo;
+ @Mock
+ private CommonServiceImpl commonServiceImpl;
+ @Mock
+ private SMSGatewayServiceImpl sMSGatewayServiceImpl;
+ @Mock
+ private TeleconsultationStatsRepo teleconsultationStatsRepo;
+ @Mock
+ private CookieUtil cookieUtil;
+
+ @InjectMocks
+ private TeleConsultationServiceImpl service;
+
+ @Test
+ @DisplayName("createTCRequest should answer for a well formed request")
+ void createTCRequest_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.createTCRequest(org.mockito.Mockito.mock(com.iemr.tm.data.tele_consultation.TCRequestModel.class)));
+ }
+
+ @Test
+ @DisplayName("updateBeneficiaryArrivalStatus should reject a request it cannot act on")
+ void updateBeneficiaryArrivalStatus_shouldRejectRequestItCannotActOn() {
+ assertThrows(RuntimeException.class, () -> service.updateBeneficiaryArrivalStatus("{}"));
+ }
+
+ @Test
+ @DisplayName("updateBeneficiaryStatusToCancelTCRequest should reject a request it cannot act on")
+ void updateBeneficiaryStatusToCancelTCRequest_shouldRejectRequestItCannotActOn() {
+ assertThrows(RuntimeException.class, () -> service.updateBeneficiaryStatusToCancelTCRequest("{}", "{}"));
+ }
+
+ @Test
+ @DisplayName("cancelSlotForTCCancel should answer for a well formed request")
+ void cancelSlotForTCCancel_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.cancelSlotForTCCancel(9, 11L, 11L, "{}"));
+ }
+
+ @Test
+ @DisplayName("checkBeneficiaryStatusForSpecialistTransaction should reject a request it cannot act on")
+ void checkBeneficiaryStatusForSpecialistTransaction_shouldRejectRequestItCannotActOn() {
+ assertThrows(RuntimeException.class, () -> service.checkBeneficiaryStatusForSpecialistTransaction("{}"));
+ }
+
+ @Test
+ @DisplayName("createTCRequestFromWorkList should reject a request it cannot act on")
+ void createTCRequestFromWorkList_shouldRejectRequestItCannotActOn() {
+ assertThrows(RuntimeException.class, () -> service.createTCRequestFromWorkList(new com.google.gson.JsonObject(), "{}"));
+ }
+
+ @Test
+ @DisplayName("getTCRequestListBySpecialistIdAndDate should reject a request it cannot act on")
+ void getTCRequestListBySpecialistIdAndDate_shouldRejectRequestItCannotActOn() {
+ assertThrows(java.time.format.DateTimeParseException.class, () -> service.getTCRequestListBySpecialistIdAndDate(9, 9, "{}"));
+ }
+
+ @Test
+ @DisplayName("startconsultation should answer for a well formed request")
+ void startconsultation_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.startconsultation(11L, 11L));
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("teleconsultation session handling")
+ class SessionHandlingTests {
+
+ private static final String REQUEST = "{\"benflowID\":5,\"benRegID\":11,\"visitCode\":22,\"userID\":42,"
+ + "\"benArrivedFlag\":true,\"tmRequestID\":8,\"status\":true,\"modifiedBy\":\"nurse1\"}";
+
+ @Test
+ @DisplayName("createTCRequest should return the stored request id")
+ void createTCRequest_shouldReturnStoredRequestId() {
+ com.iemr.tm.data.tele_consultation.TCRequestModel stored =
+ new com.iemr.tm.data.tele_consultation.TCRequestModel();
+ stored.settMRequestID(8L);
+ org.mockito.Mockito.when(tCRequestModelRepo.save(org.mockito.ArgumentMatchers.any())).thenReturn(stored);
+
+ org.junit.jupiter.api.Assertions.assertEquals(8L, service.createTCRequest(
+ new com.iemr.tm.data.tele_consultation.TCRequestModel()));
+ }
+
+ @Test
+ @DisplayName("updateBeneficiaryArrivalStatus should confirm the arrival for a complete request")
+ void updateArrivalStatus_shouldConfirmArrival() throws Exception {
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.updateBeneficiaryArrivalStatus(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any())).thenReturn(1);
+ org.mockito.Mockito.when(tCRequestModelRepo.updateBeneficiaryStatus(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any())).thenReturn(1);
+
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.updateBeneficiaryArrivalStatus(REQUEST));
+ }
+
+ @Test
+ @DisplayName("updateBeneficiaryArrivalStatus should fail when the arrival could not be recorded")
+ void updateArrivalStatus_shouldFailWhenArrivalNotRecorded() {
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.updateBeneficiaryArrivalStatus(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any())).thenReturn(0);
+
+ org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class,
+ () -> service.updateBeneficiaryArrivalStatus(REQUEST));
+ }
+
+ @Test
+ @DisplayName("checkBeneficiaryStatusForSpecialistTransaction should allow an arrived beneficiary with a session")
+ void checkStatus_shouldAllowArrivedBeneficiaryWithSession() throws Exception {
+ com.iemr.tm.data.benFlowStatus.BeneficiaryFlowStatus flow =
+ new com.iemr.tm.data.benFlowStatus.BeneficiaryFlowStatus();
+ flow.setBenArrivedFlag(true);
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.checkBeneficiaryArrivalStatus(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any()))
+ .thenReturn(new java.util.ArrayList<>(java.util.Collections.singletonList(flow)));
+ com.iemr.tm.data.tele_consultation.TCRequestModel request =
+ new com.iemr.tm.data.tele_consultation.TCRequestModel();
+ org.mockito.Mockito.when(tCRequestModelRepo.checkBenTcStatus(org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any()))
+ .thenReturn(new java.util.ArrayList<>(java.util.Collections.singletonList(request)));
+
+ org.junit.jupiter.api.Assertions.assertEquals(1,
+ service.checkBeneficiaryStatusForSpecialistTransaction(REQUEST));
+ }
+
+ @Test
+ @DisplayName("checkBeneficiaryStatusForSpecialistTransaction should reject a beneficiary who has not arrived")
+ void checkStatus_shouldRejectBeneficiaryWhoHasNotArrived() {
+ com.iemr.tm.data.benFlowStatus.BeneficiaryFlowStatus flow =
+ new com.iemr.tm.data.benFlowStatus.BeneficiaryFlowStatus();
+ flow.setBenArrivedFlag(false);
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.checkBeneficiaryArrivalStatus(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any()))
+ .thenReturn(new java.util.ArrayList<>(java.util.Collections.singletonList(flow)));
+
+ org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class,
+ () -> service.checkBeneficiaryStatusForSpecialistTransaction(REQUEST));
+ }
+
+ @Test
+ @DisplayName("checkBeneficiaryStatusForSpecialistTransaction should reject an unknown visit")
+ void checkStatus_shouldRejectUnknownVisit() {
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.checkBeneficiaryArrivalStatus(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any())).thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class,
+ () -> service.checkBeneficiaryStatusForSpecialistTransaction(REQUEST));
+ }
+
+ @Test
+ @DisplayName("getTCRequestListBySpecialistIdAndDate should render the specialist request list")
+ void getRequestList_shouldRenderRequestList() throws Exception {
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.getTCRequestList(org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any()))
+ .thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertNotNull(
+ service.getTCRequestListBySpecialistIdAndDate(9, 42, "2024-01-15"));
+ }
+
+ @Test
+ @DisplayName("startconsultation should record the start time and return the updated row count")
+ void startConsultation_shouldRecordStartTime() {
+ org.mockito.Mockito.when(tCRequestModelRepo.updateStartConsultationTime(11L, 22L)).thenReturn(1);
+
+ org.junit.jupiter.api.Assertions.assertEquals(1, service.startconsultation(11L, 22L));
+ org.mockito.Mockito.verify(teleconsultationStatsRepo).save(org.mockito.ArgumentMatchers.any());
+ }
+ }
+
+ @org.junit.jupiter.api.Nested
+ @DisplayName("teleconsultation cancellation and worklist requests")
+ class CancellationTests {
+
+ private static final String CANCEL_REQUEST = "{\"benflowID\":5,\"benRegID\":11,\"visitCode\":22,"
+ + "\"modifiedBy\":\"doctor1\",\"userID\":41}";
+
+ private com.iemr.tm.data.tele_consultation.TCRequestModel storedRequest() {
+ com.iemr.tm.data.tele_consultation.TCRequestModel request =
+ new com.iemr.tm.data.tele_consultation.TCRequestModel();
+ request.setUserID(41);
+ request.setSpecializationID(3);
+ request.setRequestDate(java.sql.Timestamp.valueOf("2026-08-26 10:00:00"));
+ request.setDuration_minute(30L);
+ return request;
+ }
+
+ private void stubCancelChain(int flowUpdate, int requestUpdate) {
+ org.mockito.Mockito.when(tCRequestModelRepo.getSpecializationID(11L, 22L, 41))
+ .thenReturn(storedRequest());
+ org.mockito.Mockito.when(tCRequestModelRepo.getTcDetailsList(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyInt(),
+ org.mockito.ArgumentMatchers.any())).thenReturn(new java.util.ArrayList<>());
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.updateBeneficiaryStatusToCancelRequest(
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyString(),
+ org.mockito.ArgumentMatchers.anyInt())).thenReturn(flowUpdate);
+ org.mockito.Mockito.when(tCRequestModelRepo.updateBeneficiaryStatusCancel(
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyString(), org.mockito.ArgumentMatchers.anyString(),
+ org.mockito.ArgumentMatchers.anyInt(), org.mockito.ArgumentMatchers.anyBoolean()))
+ .thenReturn(requestUpdate);
+ }
+
+ @Test
+ @DisplayName("updateBeneficiaryStatusToCancelTCRequest should cancel the session and text the beneficiary")
+ void cancelRequest_shouldCancelSessionAndTextBeneficiary() throws Exception {
+ stubCancelChain(1, 1);
+
+ org.junit.jupiter.api.Assertions.assertEquals(1,
+ service.updateBeneficiaryStatusToCancelTCRequest(CANCEL_REQUEST, "Bearer session-token"));
+
+ org.mockito.Mockito.verify(sMSGatewayServiceImpl).smsSenderGateway(
+ org.mockito.ArgumentMatchers.eq("cancel"), org.mockito.ArgumentMatchers.eq(11L),
+ org.mockito.ArgumentMatchers.eq(3), org.mockito.ArgumentMatchers.isNull(),
+ org.mockito.ArgumentMatchers.isNull(), org.mockito.ArgumentMatchers.eq("doctor1"),
+ org.mockito.ArgumentMatchers.isNull(), org.mockito.ArgumentMatchers.anyString(),
+ org.mockito.ArgumentMatchers.anyString());
+ }
+
+ @Test
+ @DisplayName("updateBeneficiaryStatusToCancelTCRequest should fail when there is no active session")
+ void cancelRequest_shouldFailWithoutActiveSession() {
+ stubCancelChain(0, 0);
+
+ org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class,
+ () -> service.updateBeneficiaryStatusToCancelTCRequest(CANCEL_REQUEST, "Bearer session-token"));
+ }
+
+ @Test
+ @DisplayName("cancelSlotForTCCancel should release the booked slot with the scheduler")
+ void cancelSlot_shouldReleaseBookedSlot() throws Exception {
+ new com.iemr.tm.utils.mapper.OutputMapper();
+ org.springframework.test.util.ReflectionTestUtils.setField(service, "tcSpecialistSlotCancel",
+ "http://common/tc/specialistSlotCancel");
+ org.mockito.Mockito.when(tCRequestModelRepo.getTcDetailsList(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyInt(),
+ org.mockito.ArgumentMatchers.any()))
+ .thenReturn(new java.util.ArrayList<>(java.util.Collections.singletonList(storedRequest())));
+
+ try (org.mockito.MockedConstruction ignored =
+ org.mockito.Mockito.mockConstruction(org.springframework.web.client.RestTemplate.class,
+ (restTemplate, context) -> org.mockito.Mockito.when(restTemplate.exchange(
+ org.mockito.ArgumentMatchers.anyString(),
+ org.mockito.ArgumentMatchers.any(org.springframework.http.HttpMethod.class),
+ org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.>any()))
+ .thenReturn(new org.springframework.http.ResponseEntity<>(
+ "{\"statusCode\":200}", org.springframework.http.HttpStatus.OK)))) {
+ org.junit.jupiter.api.Assertions.assertEquals(1,
+ service.cancelSlotForTCCancel(41, 11L, 22L, "Bearer session-token"));
+ }
+ }
+
+ @Test
+ @DisplayName("cancelSlotForTCCancel should report a slot the scheduler would not release")
+ void cancelSlot_shouldReportUnreleasedSlot() throws Exception {
+ new com.iemr.tm.utils.mapper.OutputMapper();
+ org.springframework.test.util.ReflectionTestUtils.setField(service, "tcSpecialistSlotCancel",
+ "http://common/tc/specialistSlotCancel");
+ org.mockito.Mockito.when(tCRequestModelRepo.getTcDetailsList(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyInt(),
+ org.mockito.ArgumentMatchers.any()))
+ .thenReturn(new java.util.ArrayList<>(java.util.Collections.singletonList(storedRequest())));
+
+ try (org.mockito.MockedConstruction ignored =
+ org.mockito.Mockito.mockConstruction(org.springframework.web.client.RestTemplate.class,
+ (restTemplate, context) -> org.mockito.Mockito.when(restTemplate.exchange(
+ org.mockito.ArgumentMatchers.anyString(),
+ org.mockito.ArgumentMatchers.any(org.springframework.http.HttpMethod.class),
+ org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.>any()))
+ .thenReturn(new org.springframework.http.ResponseEntity<>(
+ "{\"statusCode\":5000}", org.springframework.http.HttpStatus.OK)))) {
+ org.junit.jupiter.api.Assertions.assertEquals(0,
+ service.cancelSlotForTCCancel(41, 11L, 22L, "Bearer session-token"));
+ }
+ }
+
+ @Test
+ @DisplayName("cancelSlotForTCCancel should succeed when the beneficiary holds no slot")
+ void cancelSlot_shouldSucceedWithoutHeldSlot() throws Exception {
+ org.mockito.Mockito.when(tCRequestModelRepo.getTcDetailsList(org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyInt(),
+ org.mockito.ArgumentMatchers.any())).thenReturn(new java.util.ArrayList<>());
+
+ org.junit.jupiter.api.Assertions.assertEquals(1,
+ service.cancelSlotForTCCancel(41, 11L, 22L, "Bearer session-token"));
+ }
+
+ private com.google.gson.JsonObject worklistRequest() {
+ return com.google.gson.JsonParser.parseString("{\"benFlowID\":5,\"beneficiaryRegID\":11,"
+ + "\"visitCode\":22,\"createdBy\":\"doctor1\",\"providerServiceMapID\":9}").getAsJsonObject();
+ }
+
+ private com.iemr.tm.data.tele_consultation.TeleconsultationRequestOBJ tcRequest(boolean walkIn) {
+ com.iemr.tm.data.tele_consultation.TeleconsultationRequestOBJ tcRequest =
+ new com.iemr.tm.data.tele_consultation.TeleconsultationRequestOBJ();
+ tcRequest.setUserID(41);
+ tcRequest.setSpecializationID(3);
+ tcRequest.setWalkIn(walkIn);
+ tcRequest.setAllocationDate(java.sql.Timestamp.valueOf("2026-08-26 10:00:00"));
+ return tcRequest;
+ }
+
+ @Test
+ @DisplayName("createTCRequestFromWorkList should raise the request and text the beneficiary")
+ void createRequestFromWorklist_shouldRaiseRequestAndTextBeneficiary() throws Exception {
+ org.mockito.Mockito.when(commonServiceImpl.createTcRequest(org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.anyString()))
+ .thenReturn(tcRequest(false));
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.updateFlagAfterTcRequestCreatedFromWorklist(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any())).thenReturn(1);
+
+ org.junit.jupiter.api.Assertions.assertEquals(1,
+ service.createTCRequestFromWorkList(worklistRequest(), "Bearer session-token"));
+
+ org.mockito.Mockito.verify(sMSGatewayServiceImpl).smsSenderGateway(
+ org.mockito.ArgumentMatchers.eq("schedule"), org.mockito.ArgumentMatchers.anyLong(),
+ org.mockito.ArgumentMatchers.anyInt(), org.mockito.ArgumentMatchers.isNull(),
+ org.mockito.ArgumentMatchers.isNull(), org.mockito.ArgumentMatchers.anyString(),
+ org.mockito.ArgumentMatchers.anyString(), org.mockito.ArgumentMatchers.isNull(),
+ org.mockito.ArgumentMatchers.anyString());
+ }
+
+ @Test
+ @DisplayName("createTCRequestFromWorkList should skip the text for a walk in request")
+ void createRequestFromWorklist_shouldSkipTextForWalkIn() throws Exception {
+ org.mockito.Mockito.when(commonServiceImpl.createTcRequest(org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.anyString()))
+ .thenReturn(tcRequest(true));
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.updateFlagAfterTcRequestCreatedFromWorklist(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any())).thenReturn(1);
+
+ org.junit.jupiter.api.Assertions.assertEquals(1,
+ service.createTCRequestFromWorkList(worklistRequest(), "Bearer session-token"));
+
+ org.mockito.Mockito.verifyNoInteractions(sMSGatewayServiceImpl);
+ }
+
+ @Test
+ @DisplayName("createTCRequestFromWorkList should fail when the flow status could not be updated")
+ void createRequestFromWorklist_shouldFailWhenFlowStatusNotUpdated() throws Exception {
+ org.mockito.Mockito.when(commonServiceImpl.createTcRequest(org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.anyString()))
+ .thenReturn(tcRequest(false));
+ org.mockito.Mockito.when(beneficiaryFlowStatusRepo.updateFlagAfterTcRequestCreatedFromWorklist(
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any())).thenReturn(0);
+
+ org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class,
+ () -> service.createTCRequestFromWorkList(worklistRequest(), "Bearer session-token"));
+ }
+
+ @Test
+ @DisplayName("createTCRequestFromWorkList should fail when no slot could be allocated")
+ void createRequestFromWorklist_shouldFailWithoutAllocatedSlot() throws Exception {
+ org.mockito.Mockito.when(commonServiceImpl.createTcRequest(org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.anyString())).thenReturn(null);
+
+ org.junit.jupiter.api.Assertions.assertThrows(RuntimeException.class,
+ () -> service.createTCRequestFromWorkList(worklistRequest(), "Bearer session-token"));
+ }
+ }
+}
diff --git a/src/test/java/com/iemr/tm/service/videoconsultation/VideoConsultationServiceImplTest.java b/src/test/java/com/iemr/tm/service/videoconsultation/VideoConsultationServiceImplTest.java
new file mode 100644
index 00000000..20e81999
--- /dev/null
+++ b/src/test/java/com/iemr/tm/service/videoconsultation/VideoConsultationServiceImplTest.java
@@ -0,0 +1,90 @@
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.service.videoconsultation;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import com.iemr.tm.repo.login.MasterVanRepo;
+import com.iemr.tm.repo.videoconsultation.UserJitsiRepo;
+import com.iemr.tm.repo.videoconsultation.VideoConsultationUserRepo;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+@DisplayName("VideoConsultationServiceImpl Test Suite")
+class VideoConsultationServiceImplTest {
+
+ @Mock
+ private VideoConsultationUserRepo userRepo;
+ @Mock
+ private UserJitsiRepo userJitsiRepo;
+ @Mock
+ private MasterVanRepo masterVanRepo;
+
+ @InjectMocks
+ private VideoConsultationServiceImpl service;
+
+ @Test
+ @DisplayName("login should reject a request it cannot act on")
+ void login_shouldRejectRequestItCannotActOn() {
+ assertThrows(com.iemr.tm.utils.exception.VideoConsultationException.class, () -> service.login(11L));
+ }
+
+ @Test
+ @DisplayName("callUser should reject a request it cannot act on")
+ void callUser_shouldRejectRequestItCannotActOn() {
+ assertThrows(com.iemr.tm.utils.exception.VideoConsultationException.class, () -> service.callUser(11L, 11L));
+ }
+
+ @Test
+ @DisplayName("callUserjitsi should reject a request it cannot act on")
+ void callUserjitsi_shouldRejectRequestItCannotActOn() {
+ assertThrows(com.iemr.tm.utils.exception.VideoConsultationException.class, () -> service.callUserjitsi(11L, 11L));
+ }
+
+ @Test
+ @DisplayName("callVan should reject a request it cannot act on")
+ void callVan_shouldRejectRequestItCannotActOn() {
+ assertThrows(com.iemr.tm.utils.exception.VideoConsultationException.class, () -> service.callVan(11L, 9));
+ }
+
+ @Test
+ @DisplayName("callVanJitsi should reject a request it cannot act on")
+ void callVanJitsi_shouldRejectRequestItCannotActOn() {
+ assertThrows(com.iemr.tm.utils.exception.VideoConsultationException.class, () -> service.callVanJitsi(11L, 9));
+ }
+
+ @Test
+ @DisplayName("logout should answer for a well formed request")
+ void logout_shouldAnswerForWellFormedRequest() throws Exception {
+ assertDoesNotThrow(() -> service.logout());
+ }
+}
diff --git a/src/test/java/com/iemr/tm/utils/CommonMainTest.java b/src/test/java/com/iemr/tm/utils/CommonMainTest.java
new file mode 100644
index 00000000..7023593a
--- /dev/null
+++ b/src/test/java/com/iemr/tm/utils/CommonMainTest.java
@@ -0,0 +1,60 @@
+/*
+* AMRIT - Accessible Medical Records via Integrated Technologies
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.utils;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNotSame;
+
+@DisplayName("CommonMain Test Suite")
+class CommonMainTest {
+
+ private CommonMain commonMain;
+
+ @BeforeEach
+ @DisplayName("Create the bean configuration before each test")
+ void setUp() {
+ commonMain = new CommonMain();
+ }
+
+ @Test
+ @DisplayName("configProperties should supply a fresh properties holder on each call")
+ void configProperties_shouldSupplyFreshHolder() {
+ assertNotNull(commonMain.configProperties());
+ assertNotSame(commonMain.configProperties(), commonMain.configProperties());
+ }
+
+ @Test
+ @DisplayName("redisSession should supply a Spring Session Redis configuration")
+ void redisSession_shouldSupplySessionConfiguration() {
+ assertNotNull(commonMain.redisSession());
+ }
+
+ @Test
+ @DisplayName("redisStorage should supply a Redis store bean")
+ void redisStorage_shouldSupplyRedisStore() {
+ assertNotNull(commonMain.redisStorage());
+ }
+}
diff --git a/src/test/java/com/iemr/tm/utils/CookieUtilTest.java b/src/test/java/com/iemr/tm/utils/CookieUtilTest.java
new file mode 100644
index 00000000..2b4751c7
--- /dev/null
+++ b/src/test/java/com/iemr/tm/utils/CookieUtilTest.java
@@ -0,0 +1,115 @@
+/*
+* AMRIT - Accessible Medical Records via Integrated Technologies
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.utils;
+
+import jakarta.servlet.http.Cookie;
+import jakarta.servlet.http.HttpServletRequest;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.Optional;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+
+@ExtendWith(MockitoExtension.class)
+@DisplayName("CookieUtil Test Suite")
+class CookieUtilTest {
+
+ @Mock
+ HttpServletRequest request;
+
+ @InjectMocks
+ CookieUtil cookieUtil;
+
+ @Test
+ @DisplayName("Should return cookie value when cookie exists")
+ void getCookieValue_cookieExists() {
+ Cookie cookie = mock(Cookie.class);
+ doReturn("myCookieName").when(cookie).getName();
+ doReturn("myCookieValue").when(cookie).getValue();
+ doReturn(new Cookie[]{cookie}).when(request).getCookies();
+
+ Optional result = cookieUtil.getCookieValue(request, "myCookieName");
+
+ assertTrue(result.isPresent());
+ assertEquals("myCookieValue", result.get());
+ }
+
+ @Test
+ @DisplayName("Should return empty Optional when cookie does not exist")
+ void getCookieValue_cookieDoesNotExist() {
+ doReturn(new Cookie[0]).when(request).getCookies();
+ Optional result = cookieUtil.getCookieValue(request, "myCookieName");
+ assertFalse(result.isPresent());
+ }
+
+ @Test
+ @DisplayName("Should return empty Optional when cookies array is null")
+ void getCookieValue_cookiesIsNull() {
+ doReturn(null).when(request).getCookies();
+ Optional result = cookieUtil.getCookieValue(request, "myCookieName");
+ assertFalse(result.isPresent());
+ }
+
+
+ @Test
+ @DisplayName("Should return JWT token when JWT cookie exists")
+ void getJwtTokenFromCookie_jwtCookieExists() {
+ Cookie jwtCookie = mock(Cookie.class);
+ doReturn("Jwttoken").when(jwtCookie).getName();
+ doReturn("myJwtToken").when(jwtCookie).getValue();
+ doReturn(new Cookie[]{jwtCookie}).when(request).getCookies();
+
+ String jwtToken = CookieUtil.getJwtTokenFromCookie(request);
+
+ assertEquals("myJwtToken", jwtToken);
+ }
+
+ @Test
+ @DisplayName("Should return null when JWT cookie does not exist")
+ void getJwtTokenFromCookie_jwtCookieDoesNotExist() {
+ Cookie otherCookie = mock(Cookie.class);
+ doReturn("otherCookie").when(otherCookie).getName();
+ // doReturn("otherValue").when(otherCookie).getValue();
+ doReturn(new Cookie[]{otherCookie}).when(request).getCookies();
+
+ String jwtToken = CookieUtil.getJwtTokenFromCookie(request);
+
+ assertNull(jwtToken);
+ }
+
+ @Test
+ @DisplayName("Should return null when cookies array is null for JWT token lookup")
+ void getJwtTokenFromCookie_cookiesIsNull() {
+ doReturn(null).when(request).getCookies();
+ String jwtToken = CookieUtil.getJwtTokenFromCookie(request);
+ assertNull(jwtToken);
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/com/iemr/tm/utils/FilterConfigTest.java b/src/test/java/com/iemr/tm/utils/FilterConfigTest.java
new file mode 100644
index 00000000..93e67dd3
--- /dev/null
+++ b/src/test/java/com/iemr/tm/utils/FilterConfigTest.java
@@ -0,0 +1,84 @@
+/*
+* AMRIT - Accessible Medical Records via Integrated Technologies
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.utils;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.core.Ordered;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+
+@ExtendWith(MockitoExtension.class)
+@DisplayName("FilterConfig Test Suite")
+class FilterConfigTest {
+
+ private static final String ALLOWED_ORIGINS = "https://amrit.example.org,http://localhost:*";
+
+ @Mock
+ private JwtAuthenticationUtil jwtAuthenticationUtil;
+
+ private FilterConfig filterConfig;
+
+ @BeforeEach
+ @DisplayName("Configure the allow-list before each test")
+ void setUp() {
+ filterConfig = new FilterConfig();
+ ReflectionTestUtils.setField(filterConfig, "allowedOrigins", ALLOWED_ORIGINS);
+ }
+
+ @Test
+ @DisplayName("jwtUserIdValidationFilter should register the JWT filter across every url pattern")
+ void jwtUserIdValidationFilter_shouldRegisterFilterForEveryUrlPattern() {
+ FilterRegistrationBean registration =
+ filterConfig.jwtUserIdValidationFilter(jwtAuthenticationUtil);
+
+ assertNotNull(registration.getFilter());
+ assertEquals(java.util.Set.of("/*"), registration.getUrlPatterns());
+ }
+
+ @Test
+ @DisplayName("jwtUserIdValidationFilter should run at the highest precedence so auth happens first")
+ void jwtUserIdValidationFilter_shouldRunAtHighestPrecedence() {
+ FilterRegistrationBean registration =
+ filterConfig.jwtUserIdValidationFilter(jwtAuthenticationUtil);
+
+ assertEquals(Ordered.HIGHEST_PRECEDENCE, registration.getOrder());
+ }
+
+ @Test
+ @DisplayName("jwtUserIdValidationFilter should hand the filter the configured origins and auth util")
+ void jwtUserIdValidationFilter_shouldPassOriginsAndAuthUtilToFilter() {
+ JwtUserIdValidationFilter filter =
+ filterConfig.jwtUserIdValidationFilter(jwtAuthenticationUtil).getFilter();
+
+ assertEquals(ALLOWED_ORIGINS, ReflectionTestUtils.getField(filter, "allowedOrigins"));
+ assertSame(jwtAuthenticationUtil, ReflectionTestUtils.getField(filter, "jwtAuthenticationUtil"));
+ }
+}
diff --git a/src/test/java/com/iemr/tm/utils/IEMRApplBeansTest.java b/src/test/java/com/iemr/tm/utils/IEMRApplBeansTest.java
new file mode 100644
index 00000000..54eee2ec
--- /dev/null
+++ b/src/test/java/com/iemr/tm/utils/IEMRApplBeansTest.java
@@ -0,0 +1,101 @@
+/*
+* AMRIT - Accessible Medical Records via Integrated Technologies
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.utils;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
+import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.mail.javamail.JavaMailSenderImpl;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import com.iemr.tm.utils.gateway.email.EmailService;
+import com.iemr.tm.utils.gateway.email.GenericEmailServiceImpl;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNotSame;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@DisplayName("IEMRApplBeans Test Suite")
+class IEMRApplBeansTest {
+
+ private IEMRApplBeans beans;
+
+ @BeforeEach
+ @DisplayName("Create the bean configuration with Redis coordinates before each test")
+ void setUp() {
+ beans = new IEMRApplBeans();
+ ReflectionTestUtils.setField(beans, "redisHost", "redis.example.org");
+ ReflectionTestUtils.setField(beans, "redisPort", 6379);
+ }
+
+ @Test
+ @DisplayName("getVaidator should supply a validator bean")
+ void getVaidator_shouldSupplyValidatorBean() {
+ assertNotNull(beans.getVaidator());
+ }
+
+ @Test
+ @DisplayName("getEmailService should supply the generic email implementation")
+ void getEmailService_shouldSupplyGenericImplementation() {
+ EmailService emailService = beans.getEmailService();
+
+ assertTrue(emailService instanceof GenericEmailServiceImpl);
+ }
+
+ @Test
+ @DisplayName("getJavaMailSender should supply a JavaMailSender implementation")
+ void getJavaMailSender_shouldSupplyMailSenderImplementation() {
+ JavaMailSender mailSender = beans.getJavaMailSender();
+
+ assertTrue(mailSender instanceof JavaMailSenderImpl);
+ }
+
+ @Test
+ @DisplayName("configProperties should supply a fresh properties holder on each call")
+ void configProperties_shouldSupplyFreshHolder() {
+ assertNotSame(beans.configProperties(), beans.configProperties());
+ }
+
+ @Test
+ @DisplayName("sessionObject should supply a session holder bean")
+ void sessionObject_shouldSupplySessionHolder() {
+ assertNotNull(beans.sessionObject());
+ }
+
+ @Test
+ @DisplayName("redisStorage should supply a Redis store bean")
+ void redisStorage_shouldSupplyRedisStore() {
+ assertNotNull(beans.redisStorage());
+ }
+
+ @Test
+ @DisplayName("connectionFactory should point Lettuce at the configured host and port")
+ void connectionFactory_shouldPointAtConfiguredHostAndPort() {
+ LettuceConnectionFactory factory = beans.connectionFactory();
+
+ assertEquals("redis.example.org", factory.getHostName());
+ assertEquals(6379, factory.getPort());
+ }
+}
diff --git a/src/test/java/com/iemr/tm/utils/JwtAuthenticationUtilTest.java b/src/test/java/com/iemr/tm/utils/JwtAuthenticationUtilTest.java
new file mode 100644
index 00000000..58733167
--- /dev/null
+++ b/src/test/java/com/iemr/tm/utils/JwtAuthenticationUtilTest.java
@@ -0,0 +1,300 @@
+/*
+* AMRIT - Accessible Medical Records via Integrated Technologies
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+package com.iemr.tm.utils;
+
+import java.util.concurrent.TimeUnit;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ValueOperations;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import com.iemr.tm.data.login.Users;
+import com.iemr.tm.repo.login.UserLoginRepo;
+
+import io.jsonwebtoken.Claims;
+import jakarta.servlet.http.Cookie;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.lenient;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(MockitoExtension.class)
+@DisplayName("JwtAuthenticationUtil Test Suite")
+class JwtAuthenticationUtilTest {
+
+ private static final String JWT_TOKEN = "a.jwt.token";
+ private static final String USER_ID = "42";
+ private static final String REDIS_KEY = "user_42";
+
+ private final CookieUtil cookieUtil = new CookieUtil();
+
+ @Mock
+ private JwtUtil jwtUtil;
+
+ @Mock
+ private RedisTemplate redisTemplate;
+
+ @Mock
+ private ValueOperations valueOperations;
+
+ @Mock
+ private UserLoginRepo userLoginRepo;
+
+ @Mock
+ private Claims claims;
+
+ private org.springframework.mock.web.MockHttpServletRequest request;
+
+ private JwtAuthenticationUtil jwtAuthenticationUtil;
+
+ @BeforeEach
+ @DisplayName("Wire the util with mocked cookie, JWT, Redis and repository collaborators")
+ void setUp() {
+ jwtAuthenticationUtil = new JwtAuthenticationUtil(cookieUtil, jwtUtil);
+ ReflectionTestUtils.setField(jwtAuthenticationUtil, "redisTemplate", redisTemplate);
+ ReflectionTestUtils.setField(jwtAuthenticationUtil, "userLoginRepo", userLoginRepo);
+ request = new org.springframework.mock.web.MockHttpServletRequest();
+ }
+
+ private Users user(long id, String name) {
+ Users user = new Users();
+ user.setUserID(id);
+ user.setUserName(name);
+ return user;
+ }
+
+ @Nested
+ @DisplayName("validateJwtToken from the request cookie")
+ class ValidateJwtTokenTests {
+
+ @Test
+ @DisplayName("validateJwtToken should return 401 when the Jwttoken cookie is absent")
+ void validateJwtToken_shouldReturnUnauthorizedWhenCookieMissing() {
+ // no Jwttoken cookie set on the request
+
+ ResponseEntity result = jwtAuthenticationUtil.validateJwtToken(request);
+
+ assertEquals(HttpStatus.UNAUTHORIZED, result.getStatusCode());
+ assertEquals("Error 401: Unauthorized - JWT Token is not set!", result.getBody());
+ verify(jwtUtil, never()).validateToken(anyString());
+ }
+
+ @Test
+ @DisplayName("validateJwtToken should return 401 when the token cannot be validated")
+ void validateJwtToken_shouldReturnUnauthorizedWhenTokenInvalid() {
+ request.setCookies(new Cookie("Jwttoken", JWT_TOKEN));
+ when(jwtUtil.validateToken(JWT_TOKEN)).thenReturn(null);
+
+ ResponseEntity result = jwtAuthenticationUtil.validateJwtToken(request);
+
+ assertEquals(HttpStatus.UNAUTHORIZED, result.getStatusCode());
+ assertEquals("Error 401: Unauthorized - Invalid JWT Token!", result.getBody());
+ }
+
+ @Test
+ @DisplayName("validateJwtToken should return 401 when the token carries no subject")
+ void validateJwtToken_shouldReturnUnauthorizedWhenSubjectMissing() {
+ request.setCookies(new Cookie("Jwttoken", JWT_TOKEN));
+ when(jwtUtil.validateToken(JWT_TOKEN)).thenReturn(claims);
+ when(claims.getSubject()).thenReturn(null);
+
+ ResponseEntity result = jwtAuthenticationUtil.validateJwtToken(request);
+
+ assertEquals(HttpStatus.UNAUTHORIZED, result.getStatusCode());
+ assertEquals("Error 401: Unauthorized - Username is missing!", result.getBody());
+ }
+
+ @Test
+ @DisplayName("validateJwtToken should return 401 when the subject is blank")
+ void validateJwtToken_shouldReturnUnauthorizedWhenSubjectIsBlank() {
+ request.setCookies(new Cookie("Jwttoken", JWT_TOKEN));
+ when(jwtUtil.validateToken(JWT_TOKEN)).thenReturn(claims);
+ when(claims.getSubject()).thenReturn("");
+
+ ResponseEntity