18
18
import static org .mockito .Mockito .never ;
19
19
import static org .mockito .Mockito .verify ;
20
20
import static org .mockito .Mockito .when ;
21
- import static org .robolectric .Shadows .shadowOf ;
22
21
23
22
import android .app .Application ;
24
23
import android .content .Context ;
25
24
import android .content .Intent ;
26
25
import android .os .Build .VERSION_CODES ;
27
26
import androidx .test .core .app .ApplicationProvider ;
28
27
import com .google .android .gms .tasks .Task ;
28
+ import com .google .android .gms .tasks .TaskCompletionSource ;
29
29
import com .google .firebase .messaging .testing .FakeScheduledExecutorService ;
30
30
import org .junit .After ;
31
31
import org .junit .Before ;
37
37
import org .mockito .junit .MockitoRule ;
38
38
import org .robolectric .RobolectricTestRunner ;
39
39
import org .robolectric .annotation .Config ;
40
+ import org .robolectric .shadows .ShadowLooper ;
40
41
import org .robolectric .shadows .ShadowPowerManager ;
41
42
42
43
/** Robolectric test for FcmBroadcastProcessor. */
@@ -51,13 +52,18 @@ public class FcmBroadcastProcessorRoboTest {
51
52
private FcmBroadcastProcessor processor ;
52
53
private FakeScheduledExecutorService fakeExecutorService ;
53
54
@ Mock private ServiceStarter serviceStarter ;
55
+ @ Mock private WithinAppServiceConnection mockConnection ;
56
+ private TaskCompletionSource <Void > sendIntentTask ;
54
57
55
58
@ Before
56
59
public void setUp () {
57
60
context = ApplicationProvider .getApplicationContext ();
58
61
ServiceStarter .setForTesting (serviceStarter );
59
62
fakeExecutorService = new FakeScheduledExecutorService ();
60
63
processor = new FcmBroadcastProcessor (context , fakeExecutorService );
64
+ FcmBroadcastProcessor .setServiceConnection (mockConnection );
65
+ sendIntentTask = new TaskCompletionSource <>();
66
+ when (mockConnection .sendIntent (any (Intent .class ))).thenReturn (sendIntentTask .getTask ());
61
67
}
62
68
63
69
@ After
@@ -70,37 +76,82 @@ public void resetStaticState() {
70
76
71
77
@ Test
72
78
@ Config (sdk = VERSION_CODES .O )
73
- public void testStartMessagingService_NormalPriorityBackgroundCheck () {
74
- // Subject to background check when run on Android O and targetSdkVersion set to O.
75
- context . getApplicationInfo (). targetSdkVersion = VERSION_CODES . O ;
76
- when ( serviceStarter . hasWakeLockPermission ( any ( Context . class ))). thenReturn ( true );
79
+ public void testStartMessagingService_Background () {
80
+ setSubjectToBackgroundCheck ();
81
+ setWakeLockPermission ( true ) ;
82
+ Intent intent = new Intent ( ACTION_FCM_MESSAGE );
77
83
78
- Task <Integer > startServiceTask =
79
- processor .startMessagingService (context , new Intent (ACTION_FCM_MESSAGE ));
84
+ Task <Integer > startServiceTask = processor .startMessagingService (context , intent );
80
85
81
- // Should return immediately with SUCCESS, bind to the Service, and acquire a WakeLock.
82
- assertThat (startServiceTask .getResult ()).isEqualTo ( ServiceStarter . SUCCESS );
86
+ // Should send the intent through the connection and not acquire a WakeLock.
87
+ assertThat (startServiceTask .isComplete ()).isFalse ( );
83
88
verify (serviceStarter , never ()).startMessagingService (any (), any ());
84
- assertThat (shadowOf (context ).getBoundServiceConnections ()).hasSize (1 );
89
+ verify (mockConnection ).sendIntent (intent );
90
+ assertThat (ShadowPowerManager .getLatestWakeLock ()).isNull ();
91
+
92
+ // After the message has been handled, the task should be completed successfully.
93
+ sendIntentTask .setResult (null );
94
+ ShadowLooper .idleMainLooper ();
95
+
96
+ assertThat (startServiceTask .getResult ()).isEqualTo (ServiceStarter .SUCCESS );
97
+ }
98
+
99
+ @ Test
100
+ @ Config (sdk = VERSION_CODES .O )
101
+ public void testStartMessagingService_ForegroundBindWithWakeLock () {
102
+ setWakeLockPermission (true );
103
+ setStartServiceFails ();
104
+ Intent intent = new Intent (ACTION_FCM_MESSAGE );
105
+ intent .addFlags (Intent .FLAG_RECEIVER_FOREGROUND );
106
+
107
+ Task <Integer > startServiceTask = processor .startMessagingService (context , intent );
108
+
109
+ // Should return immediately with SUCCESS, bind to the Service, and acquire a WakeLock.
110
+ fakeExecutorService .runAll ();
111
+ assertThat (startServiceTask .isComplete ()).isTrue ();
112
+ assertThat (startServiceTask .getResult ())
113
+ .isEqualTo (ServiceStarter .ERROR_ILLEGAL_STATE_EXCEPTION_FALLBACK_TO_BIND );
114
+ verify (mockConnection ).sendIntent (any (Intent .class ));
85
115
assertThat (ShadowPowerManager .getLatestWakeLock ()).isNotNull ();
86
116
assertThat (ShadowPowerManager .getLatestWakeLock ().isHeld ()).isTrue ();
117
+
118
+ // After the message has been handled, the WakeLock should be released.
119
+ sendIntentTask .setResult (null );
120
+ ShadowLooper .idleMainLooper ();
121
+
122
+ assertThat (ShadowPowerManager .getLatestWakeLock ().isHeld ()).isFalse ();
87
123
}
88
124
89
125
@ Test
90
126
@ Config (sdk = VERSION_CODES .O )
91
- public void testStartMessagingService_bindNoWakeLockPermission () {
127
+ public void testStartMessagingService_ForegroundBindNoWakeLock () {
128
+ setWakeLockPermission (false );
129
+ setStartServiceFails ();
130
+ Intent intent = new Intent (ACTION_FCM_MESSAGE );
131
+ intent .addFlags (Intent .FLAG_RECEIVER_FOREGROUND );
132
+
133
+ Task <Integer > startServiceTask = processor .startMessagingService (context , intent );
134
+
135
+ // Should return immediately with SUCCESS, bind to the Service, and not acquire a WakeLock.
136
+ fakeExecutorService .runAll ();
137
+ assertThat (startServiceTask .isComplete ()).isTrue ();
138
+ assertThat (startServiceTask .getResult ())
139
+ .isEqualTo (ServiceStarter .ERROR_ILLEGAL_STATE_EXCEPTION_FALLBACK_TO_BIND );
140
+ verify (mockConnection ).sendIntent (any (Intent .class ));
141
+ assertThat (ShadowPowerManager .getLatestWakeLock ()).isNull ();
142
+ }
143
+
144
+ private void setSubjectToBackgroundCheck () {
92
145
// Subject to background check when run on Android O and targetSdkVersion set to O.
93
146
context .getApplicationInfo ().targetSdkVersion = VERSION_CODES .O ;
94
- when ( serviceStarter . hasWakeLockPermission ( any ( Context . class ))). thenReturn ( false );
147
+ }
95
148
96
- Task <Integer > startServiceTask =
97
- processor .startMessagingService (context , new Intent (ACTION_FCM_MESSAGE ));
149
+ private void setWakeLockPermission (boolean permission ) {
150
+ when (serviceStarter .hasWakeLockPermission (any (Context .class ))).thenReturn (permission );
151
+ }
98
152
99
- // Should return immediately with SUCCESS and bind to the Service, but not try to acquire a
100
- // WakeLock since it doesn't hold the permission.
101
- assertThat (startServiceTask .getResult ()).isEqualTo (ServiceStarter .SUCCESS );
102
- verify (serviceStarter , never ()).startMessagingService (any (), any ());
103
- assertThat (shadowOf (context ).getBoundServiceConnections ()).hasSize (1 );
104
- assertThat (ShadowPowerManager .getLatestWakeLock ()).isNull ();
153
+ private void setStartServiceFails () {
154
+ when (serviceStarter .startMessagingService (any (Context .class ), any (Intent .class )))
155
+ .thenReturn (ServiceStarter .ERROR_ILLEGAL_STATE_EXCEPTION );
105
156
}
106
157
}
0 commit comments