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: diff --git a/app/build.gradle b/app/build.gradle index 2135c835..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' @@ -244,5 +252,10 @@ dependencies { androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', { exclude group: 'com.android.support', module: 'support-annotations' }) + + // unit tests 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/main/java/org/openimis/imispolicies/usecase/Login.java b/app/src/main/java/org/openimis/imispolicies/usecase/Login.java index a142fc34..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,6 +53,9 @@ public Login( @WorkerThread public void execute(@NonNull String username, @NonNull String password) throws Exception { + 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"); 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()); + } +}