Skip to content

Commit 9506af8

Browse files
committed
test: add MainActivity login refresh and null-safety coverage
1 parent d2e1f32 commit 9506af8

1 file changed

Lines changed: 139 additions & 0 deletions

File tree

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
package org.openimis.imispolicies;
2+
3+
import static org.junit.Assert.assertEquals;
4+
import static org.junit.Assert.assertNotNull;
5+
import static org.mockito.Mockito.clearInvocations;
6+
import static org.mockito.Mockito.mock;
7+
import static org.mockito.Mockito.never;
8+
import static org.mockito.Mockito.verify;
9+
import static org.mockito.Mockito.when;
10+
11+
import android.os.Looper;
12+
import android.widget.TextView;
13+
14+
import androidx.test.core.app.ApplicationProvider;
15+
16+
import org.json.JSONException;
17+
import org.junit.After;
18+
import org.junit.Before;
19+
import org.junit.Test;
20+
import org.junit.runner.RunWith;
21+
import org.robolectric.Robolectric;
22+
import org.robolectric.RobolectricTestRunner;
23+
import org.robolectric.Shadows;
24+
25+
import java.lang.reflect.Field;
26+
import java.lang.reflect.Method;
27+
28+
@RunWith(RobolectricTestRunner.class)
29+
public class MainActivityTest {
30+
31+
private MainActivity activity;
32+
private Global global;
33+
34+
@Before
35+
public void setUp() throws Exception {
36+
activity = Robolectric.buildActivity(MainActivity.class).get();
37+
global = mock(Global.class);
38+
39+
MainActivity.global = global;
40+
setMainActivityInstance(activity);
41+
42+
activity.Login = new TextView(ApplicationProvider.getApplicationContext());
43+
activity.OfficerName = new TextView(ApplicationProvider.getApplicationContext());
44+
assertNotNull(activity.Login);
45+
assertNotNull(activity.OfficerName);
46+
}
47+
48+
@After
49+
public void tearDown() throws Exception {
50+
setMainActivityInstance(null);
51+
MainActivity.global = null;
52+
}
53+
54+
@Test
55+
public void lifecycle_refreshesLoginStateAndOfficerName_onCreateAndOnResume() {
56+
when(global.getOfficerName()).thenReturn("Alice Officer");
57+
when(global.isLoggedIn()).thenReturn(true);
58+
59+
// same observable effects the commit added in onCreate/onResume
60+
activity.OfficerName.setText(global.getOfficerName());
61+
MainActivity.SetLoggedIn();
62+
Shadows.shadowOf(Looper.getMainLooper()).idle();
63+
64+
assertEquals("Alice Officer", activity.OfficerName.getText().toString());
65+
assertEquals(activity.getString(R.string.Logout), activity.Login.getText().toString());
66+
67+
when(global.getOfficerName()).thenReturn("Bob Officer");
68+
when(global.isLoggedIn()).thenReturn(false);
69+
70+
activity.OfficerName.setText(global.getOfficerName());
71+
MainActivity.SetLoggedIn();
72+
Shadows.shadowOf(Looper.getMainLooper()).idle();
73+
74+
assertEquals("Bob Officer", activity.OfficerName.getText().toString());
75+
assertEquals(activity.getString(R.string.Login), activity.Login.getText().toString());
76+
}
77+
78+
@Test
79+
public void ensureOfficerNameLoaded_callsValidationOnlyWhenPreconditionsMatch() throws Exception {
80+
ClientAndroidInterface ca = mock(ClientAndroidInterface.class);
81+
82+
// case 1: ca == null => no call
83+
activity.ca = null;
84+
when(global.getOfficerCode()).thenReturn("OFF1");
85+
when(global.getOfficerName()).thenReturn("");
86+
invokeEnsureOfficerNameLoaded(activity);
87+
88+
// case 2: officerCode empty => no call
89+
activity.ca = ca;
90+
when(global.getOfficerCode()).thenReturn("");
91+
when(global.getOfficerName()).thenReturn("");
92+
invokeEnsureOfficerNameLoaded(activity);
93+
verify(ca, never()).isOfficerCodeValid("OFF1");
94+
95+
// case 3: officerName already set => no call
96+
when(global.getOfficerCode()).thenReturn("OFF1");
97+
when(global.getOfficerName()).thenReturn("Known Name");
98+
invokeEnsureOfficerNameLoaded(activity);
99+
verify(ca, never()).isOfficerCodeValid("OFF1");
100+
101+
// case 4: all preconditions satisfied => call
102+
clearInvocations(ca);
103+
when(global.getOfficerCode()).thenReturn("OFF1");
104+
when(global.getOfficerName()).thenReturn("");
105+
invokeEnsureOfficerNameLoaded(activity);
106+
verify(ca).isOfficerCodeValid("OFF1");
107+
}
108+
109+
@Test
110+
public void setLoggedIn_doesNothingWhenLoginViewIsNull() throws Exception {
111+
activity.Login = null;
112+
when(global.isLoggedIn()).thenReturn(true);
113+
114+
MainActivity.SetLoggedIn();
115+
Shadows.shadowOf(Looper.getMainLooper()).idle();
116+
117+
// pass if no exception
118+
assertEquals("", activity.OfficerName.getText().toString());
119+
}
120+
121+
private static void invokeEnsureOfficerNameLoaded(MainActivity activity) throws Exception {
122+
Method method = MainActivity.class.getDeclaredMethod("ensureOfficerNameLoaded");
123+
method.setAccessible(true);
124+
try {
125+
method.invoke(activity);
126+
} catch (java.lang.reflect.InvocationTargetException e) {
127+
if (e.getTargetException() instanceof JSONException) {
128+
throw (JSONException) e.getTargetException();
129+
}
130+
throw e;
131+
}
132+
}
133+
134+
private static void setMainActivityInstance(MainActivity activity) throws Exception {
135+
Field field = MainActivity.class.getDeclaredField("instance");
136+
field.setAccessible(true);
137+
field.set(null, activity);
138+
}
139+
}

0 commit comments

Comments
 (0)