From 43bee7c3edfd84f397ca924eb705ad68d50cd07c Mon Sep 17 00:00:00 2001 From: paul sandjong Date: Wed, 12 Nov 2025 00:10:59 +0100 Subject: [PATCH 1/8] fix officerCode is null on login --- .../main/java/org/openimis/imispolicies/usecase/Login.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/openimis/imispolicies/usecase/Login.java b/app/src/main/java/org/openimis/imispolicies/usecase/Login.java index a142fc34..7c960b5c 100644 --- a/app/src/main/java/org/openimis/imispolicies/usecase/Login.java +++ b/app/src/main/java/org/openimis/imispolicies/usecase/Login.java @@ -53,7 +53,10 @@ public Login( @WorkerThread public void execute(@NonNull String username, @NonNull String password) throws Exception { - String officerCode = Global.getGlobal().getOfficerCode(); + String officerCode = (Global.getGlobal().getOfficerCode() != null) + ? Global.getGlobal().getOfficerCode() + : username; + if (officerCode == null) { throw new IllegalStateException("OfficerCode should not be null on login"); } From e5cc26341422c449a64eeac6c317baa57dfe58fa Mon Sep 17 00:00:00 2001 From: paul sandjong Date: Wed, 12 Nov 2025 12:18:56 +0100 Subject: [PATCH 2/8] corrections --- .../java/org/openimis/imispolicies/usecase/Login.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/openimis/imispolicies/usecase/Login.java b/app/src/main/java/org/openimis/imispolicies/usecase/Login.java index 7c960b5c..260901b7 100644 --- a/app/src/main/java/org/openimis/imispolicies/usecase/Login.java +++ b/app/src/main/java/org/openimis/imispolicies/usecase/Login.java @@ -53,10 +53,10 @@ public Login( @WorkerThread public void execute(@NonNull String username, @NonNull String password) throws Exception { - String officerCode = (Global.getGlobal().getOfficerCode() != null) - ? Global.getGlobal().getOfficerCode() - : username; - + if (Global.getGlobal().getOfficerCode() == null) { + Global.getGlobal().setOfficerCode(username); + } + String officerCode = Global.getGlobal().getOfficerCode(); if (officerCode == null) { throw new IllegalStateException("OfficerCode should not be null on login"); } From c5d08136c677b064b820faf82f4c8092835efd37 Mon Sep 17 00:00:00 2001 From: paul sandjong Date: Sat, 29 Nov 2025 00:24:39 +0100 Subject: [PATCH 3/8] set test infra --- .../java/org/openimis/imispolicies/imis/ExampleUnitTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/test/java/org/openimis/imispolicies/imis/ExampleUnitTest.java b/app/src/test/java/org/openimis/imispolicies/imis/ExampleUnitTest.java index 42be9bcc..f662e8a8 100644 --- a/app/src/test/java/org/openimis/imispolicies/imis/ExampleUnitTest.java +++ b/app/src/test/java/org/openimis/imispolicies/imis/ExampleUnitTest.java @@ -38,5 +38,6 @@ public class ExampleUnitTest { @Test public void addition_isCorrect() throws Exception { assertEquals(4, 2 + 2); + assertEquals(5, 2 + 3); } } From 83be6812deff872e6787fc0aad7c60fa28e7df8c Mon Sep 17 00:00:00 2001 From: paul sandjong Date: Tue, 9 Dec 2025 16:58:31 +0100 Subject: [PATCH 4/8] testing the creation of a new insuree --- app/build.gradle | 6 +- .../imispolicies/ClientAndroidInterface.java | 24 ++-- .../ClientAndroidInterfaceTest.java | 114 ++++++++++++++++++ 3 files changed, 135 insertions(+), 9 deletions(-) create mode 100644 app/src/test/java/org/openimis/imispolicies/ClientAndroidInterfaceTest.java diff --git a/app/build.gradle b/app/build.gradle index 2135c835..ff8da71f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -233,7 +233,6 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'com.google.android.material:material:1.10.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' - //noinspection GradleDependency implementation 'com.squareup.picasso:picasso:2.8' implementation 'commons-io:commons-io:2.11.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0' @@ -244,5 +243,10 @@ dependencies { androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', { exclude group: 'com.android.support', module: 'support-annotations' }) + + // Tests unitaires testImplementation 'junit:junit:4.13.2' + testImplementation 'org.mockito:mockito-core:5.5.0' + testImplementation 'org.robolectric:robolectric:4.11.1' } + diff --git a/app/src/main/java/org/openimis/imispolicies/ClientAndroidInterface.java b/app/src/main/java/org/openimis/imispolicies/ClientAndroidInterface.java index e06e4dfb..858635f6 100644 --- a/app/src/main/java/org/openimis/imispolicies/ClientAndroidInterface.java +++ b/app/src/main/java/org/openimis/imispolicies/ClientAndroidInterface.java @@ -136,7 +136,7 @@ public class ClientAndroidInterface { @NonNull private final Activity activity; @NonNull - private final SQLHandler sqlHandler; + protected final SQLHandler sqlHandler; @NonNull private final HashMap controls = new HashMap<>(); @NonNull @@ -144,7 +144,7 @@ public class ClientAndroidInterface { @NonNull private final ArrayList enrolMessages = new ArrayList<>(); @NonNull - private final Global global; + protected final Global global; @NonNull private final StorageManager storageManager; @NonNull @@ -167,6 +167,14 @@ public class ClientAndroidInterface { .build(); } + public ClientAndroidInterface(Activity activity, SQLHandler sqlHandler, Global global, Picasso picasso, StorageManager storageManager) { + this.activity = activity; + this.sqlHandler = sqlHandler; + this.global = global; + this.storageManager = storageManager; + this.picassoInstance = picasso; + } + @JavascriptInterface @SuppressWarnings("unused") public void SetUrl(String Url) { @@ -666,7 +674,7 @@ public String getHF(int DistrictId, String HFLevel) { return HFs.toString(); } - private HashMap jsonToTable(String jsonString) { + protected HashMap jsonToTable(String jsonString) { HashMap data = new HashMap<>(); try { JSONArray array = new JSONArray(jsonString); @@ -849,7 +857,7 @@ public void addOrUpdateFamilySms(int familyId, Boolean approve, String language) } } - private int isValidInsureeData(HashMap data) { + protected int isValidInsureeData(HashMap data) { int Result; String InsuranceNumber = data.get("txtInsuranceNumber"); @@ -1044,7 +1052,7 @@ else if (ExceedThreshold == 0) return rtInsureeId; } - private String copyImageFromGalleryToApplication(String selectedPath, String InsuranceNumber) { + protected String copyImageFromGalleryToApplication(String selectedPath, String InsuranceNumber) { String result = ""; try { @@ -5021,7 +5029,7 @@ public int getFamilyStat(int FamilyId) { return status; } - private int getFamilyStatus(int FamilyId) throws JSONException { + protected int getFamilyStatus(int FamilyId) throws JSONException { if (FamilyId < 0) return 0; @Language("SQL") String Query = "SELECT isOffline FROM tblFamilies WHERE FamilyId = " + FamilyId; @@ -5034,7 +5042,7 @@ private int getFamilyStatus(int FamilyId) throws JSONException { else return 0; } - private int getInsureeStatus(int InsureeId) throws JSONException {//herman + protected int getInsureeStatus(int InsureeId) throws JSONException {//herman if (InsureeId == 0) return 1; @Language("SQL") String Query = "SELECT isOffline FROM tblInsuree WHERE InsureeId = " + InsureeId; @@ -5252,7 +5260,7 @@ private int getNextAvailablePolicyId() { return getMaxIdFromTable("PolicyId", "tblPolicy"); } - private int getNextAvailableInsureeId() { + protected int getNextAvailableInsureeId() { return getMaxIdFromTable("InsureeId", "tblInsuree"); } diff --git a/app/src/test/java/org/openimis/imispolicies/ClientAndroidInterfaceTest.java b/app/src/test/java/org/openimis/imispolicies/ClientAndroidInterfaceTest.java new file mode 100644 index 00000000..5ff85f95 --- /dev/null +++ b/app/src/test/java/org/openimis/imispolicies/ClientAndroidInterfaceTest.java @@ -0,0 +1,114 @@ +package org.openimis.imispolicies; + +import static org.junit.Assert.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.*; +import com.squareup.picasso.Picasso; +import org.openimis.imispolicies.tools.StorageManager; +import org.robolectric.RobolectricTestRunner; + +import android.app.Activity; +import android.content.res.Resources; + +import org.json.JSONArray; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.junit.MockitoJUnitRunner; + +import java.util.HashMap; + +@RunWith(RobolectricTestRunner.class) +public class ClientAndroidInterfaceTest { + + @Mock + SQLHandler sqlHandler; + + @Mock + Global global; + + @Mock + Activity activity; + + @Mock + Resources resources; + + @Mock + StorageManager storageManager; + + ClientAndroidInterface client; + + @Before + public void setup() { + MockitoAnnotations.openMocks(this); + + when(activity.getResources()).thenReturn(resources); + when(resources.getString(anyInt())).thenReturn("mockString"); + + client = new ClientAndroidInterface(activity, sqlHandler, global, null, storageManager); + + when(global.isNetworkAvailable()).thenReturn(true); + } + + @Test + public void testCreateNewInsuree_ShouldInsertInDatabase() throws Exception { + + String insureeJson = "{" + + "\"txtInsuranceNumber\":\"12345\"," + + "\"hfInsureeId\":\"0\"," + + "\"hfisHead\":\"1\"," + + "\"txtLastName\":\"Doe\"," + + "\"txtOtherNames\":\"John\"," + + "\"txtBirthDate\":\"1991-01-01\"," + + "\"ddlGender\":\"M\"," + + "\"txtPhoneNumber\":\"690000000\"" + + "\"hfNewPhotoPath\":\"\"" + + "\"hfImagePath\":\"/storage/emulated/0/DCIM/test.jpg\"" + + "}"; + + ClientAndroidInterface spyClient = spy(client); + + HashMap mockData = new HashMap<>(); + mockData.put("txtInsuranceNumber", "12345"); + mockData.put("hfInsureeId", "0"); + mockData.put("hfisHead", "1"); + mockData.put("txtLastName", "Doe"); + mockData.put("txtOtherNames", "John"); + mockData.put("txtBirthDate", "1991-01-01"); + mockData.put("ddlGender", "M"); + mockData.put("txtPhoneNumber", "690000000"); + mockData.put("hfNewPhotoPath", ""); + mockData.put("hfImagePath", "/storage/emulated/0/DCIM/test.jpg"); + + when(sqlHandler.getResult(anyString(), any(String[].class))).thenReturn(new JSONArray()); + doNothing().when(spyClient).SaveInsureePolicy(anyInt(), anyInt(), anyBoolean(), anyInt()); + doNothing().when(sqlHandler).insertData(anyString(), any()); + doNothing().when(sqlHandler).updateData(anyString(), any(), anyString(), any(String[].class)); + doReturn(mockData).when(spyClient).jsonToTable(anyString()); + doReturn(0).when(spyClient).isValidInsureeData(mockData); + doReturn(999).when(spyClient).getNextAvailableInsureeId(); + doReturn(0).when(spyClient).getFamilyStatus(anyInt()); + doReturn(0).when(spyClient).getInsureeStatus(anyInt()); + doNothing().when(spyClient).ShowDialog(anyString()); + doNothing().when(spyClient).ShowDialogYesNo(anyInt(), anyInt(), anyInt()); + doReturn("").when(spyClient).copyImageFromGalleryToApplication(anyString(), anyString()); + + doNothing().when(sqlHandler).insertData(anyString(), any()); + + int result = spyClient.SaveInsuree( + insureeJson, + 1, // FamilyId + 1, // isHead + 0, // ExceedThreshold + 0 // PolicyId + ); + + assertEquals(-999, result); + + verify(sqlHandler, times(1)).insertData(eq("tblInsuree"), any()); + } +} From cdfc36193bfff62fa9f5ea7bd7e1458563e1be18 Mon Sep 17 00:00:00 2001 From: paul sandjong Date: Wed, 10 Dec 2025 10:40:48 +0100 Subject: [PATCH 5/8] corrections --- app/build.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index ff8da71f..dc0cb43b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -233,6 +233,7 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'com.google.android.material:material:1.10.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' + //noinspection GradleDependency implementation 'com.squareup.picasso:picasso:2.8' implementation 'commons-io:commons-io:2.11.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0' @@ -244,7 +245,7 @@ dependencies { exclude group: 'com.android.support', module: 'support-annotations' }) - // Tests unitaires + // unit tests testImplementation 'junit:junit:4.13.2' testImplementation 'org.mockito:mockito-core:5.5.0' testImplementation 'org.robolectric:robolectric:4.11.1' From 481a713e0511399df3fad57861f6d2cba203379b Mon Sep 17 00:00:00 2001 From: Blue-B-code Date: Wed, 10 Dec 2025 13:19:30 +0100 Subject: [PATCH 6/8] Update ExampleUnitTest.java --- .../java/org/openimis/imispolicies/imis/ExampleUnitTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/test/java/org/openimis/imispolicies/imis/ExampleUnitTest.java b/app/src/test/java/org/openimis/imispolicies/imis/ExampleUnitTest.java index f662e8a8..42be9bcc 100644 --- a/app/src/test/java/org/openimis/imispolicies/imis/ExampleUnitTest.java +++ b/app/src/test/java/org/openimis/imispolicies/imis/ExampleUnitTest.java @@ -38,6 +38,5 @@ public class ExampleUnitTest { @Test public void addition_isCorrect() throws Exception { assertEquals(4, 2 + 2); - assertEquals(5, 2 + 3); } } From 08e491fd1bfb09dc670b42b91fa41592743e86eb Mon Sep 17 00:00:00 2001 From: paul sandjong Date: Wed, 10 Dec 2025 16:18:26 +0100 Subject: [PATCH 7/8] improve tests logging --- app/build.gradle | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/build.gradle b/app/build.gradle index dc0cb43b..f87e9e8f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -218,6 +218,14 @@ apollo { ] } +tasks.withType(Test).configureEach { + testLogging { + events "passed", "skipped", "failed" + exceptionFormat "full" + showStandardStreams = false + } +} + dependencies { implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs') implementation 'com.squareup.okhttp3:okhttp:4.11.0' From 348a3a36244d5670803775639a7ff0535ecdbd29 Mon Sep 17 00:00:00 2001 From: paul sandjong Date: Thu, 11 Dec 2025 10:17:24 +0100 Subject: [PATCH 8/8] add pull_request on workflow --- .github/workflows/main.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e29e38e5..0d4188c4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -6,6 +6,10 @@ on: - '*' # tags: # - '!v*' + pull_request: + branches: + - '*' + types: [opened, synchronize, reopened] jobs: build: