15
15
*/
16
16
package com .optimizely .ab .android .sdk ;
17
17
18
- import android .app .Activity ;
19
18
import android .content .Context ;
20
19
import android .content .Intent ;
21
20
import android .support .test .espresso .core .deps .guava .util .concurrent .ListeningExecutorService ;
26
25
import com .optimizely .user_experiment_record .AndroidUserExperimentRecord ;
27
26
28
27
import org .junit .Before ;
29
- import org .junit .Ignore ;
30
28
import org .junit .Test ;
31
29
import org .junit .runner .RunWith ;
32
30
import org .mockito .ArgumentCaptor ;
42
40
import static org .mockito .Matchers .any ;
43
41
import static org .mockito .Matchers .eq ;
44
42
import static org .mockito .Mockito .mock ;
45
- import static org .mockito .Mockito .never ;
46
43
import static org .mockito .Mockito .verify ;
47
44
import static org .mockito .Mockito .when ;
48
45
49
46
/**
50
47
* Created by jdeffibaugh on 8/3/16 for Optimizely.
51
48
*
52
49
* Tests for {@link OptimizelyManager}
53
- *
54
- * *NOTE*
55
- * Some tests are ignored here because Activity#getApplication() is final and can't be mocked
56
- * Also, mockito fails when making {@link OptimizelyManager#stop(Activity, OptimizelyManager.OptlyActivityLifecycleCallbacks)}
57
- * private or package private.
58
- * // TODO Get these tests working via PowerMock https://github.com/jayway/powermock
59
50
*/
60
51
@ RunWith (AndroidJUnit4 .class )
61
52
public class OptimizelyManagerTest {
@@ -65,6 +56,18 @@ public class OptimizelyManagerTest {
65
56
Logger logger ;
66
57
OptimizelyManager optimizelyManager ;
67
58
59
+ String minDataFile = "{\n " +
60
+ "experiments: [ ],\n " +
61
+ "version: \" 2\" ,\n " +
62
+ "audiences: [ ],\n " +
63
+ "groups: [ ],\n " +
64
+ "attributes: [ ],\n " +
65
+ "projectId: \" 7595190003\" ,\n " +
66
+ "accountId: \" 6365361536\" ,\n " +
67
+ "events: [ ],\n " +
68
+ "revision: \" 1\" \n " +
69
+ "}" ;
70
+
68
71
@ Before
69
72
public void setup () {
70
73
logger = mock (Logger .class );
@@ -76,61 +79,58 @@ public void setup() {
76
79
77
80
@ SuppressWarnings ("WrongConstant" )
78
81
@ Test
79
- @ Ignore
80
82
public void start () {
81
83
OptimizelyStartListener startListener = mock (OptimizelyStartListener .class );
82
- Activity activity = mock (Activity .class );
83
84
Context context = mock (Context .class );
84
- when (context .getPackageName ()).thenReturn ("com.optly" );
85
+ Context appContext = mock (Context .class );
86
+ when (context .getApplicationContext ()).thenReturn (appContext );
87
+ when (appContext .getPackageName ()).thenReturn ("com.optly" );
85
88
ArgumentCaptor <Intent > captor = ArgumentCaptor .forClass (Intent .class );
86
89
87
- optimizelyManager .start (activity , startListener );
90
+ optimizelyManager .start (context , startListener );
88
91
89
92
assertNotNull (optimizelyManager .getOptimizelyStartListener ());
90
93
assertNotNull (optimizelyManager .getDataFileServiceConnection ());
91
94
92
- verify (context ).bindService (captor .capture (), any (OptimizelyManager .DataFileServiceConnection .class ), eq (Context .BIND_AUTO_CREATE ));
95
+ verify (appContext ).bindService (captor .capture (), any (OptimizelyManager .DataFileServiceConnection .class ), eq (Context .BIND_AUTO_CREATE ));
93
96
94
97
Intent intent = captor .getValue ();
95
98
assertTrue (intent .getComponent ().getShortClassName ().contains ("DataFileService" ));
96
99
}
97
100
98
101
@ Test
99
- @ Ignore
100
102
public void stop () {
101
103
Context context = mock (Context .class );
102
- Activity activity = mock (Activity .class );
103
- OptimizelyManager . OptlyActivityLifecycleCallbacks activityLifecycleCallbacks = mock ( OptimizelyManager . OptlyActivityLifecycleCallbacks . class );
104
+ Context appContext = mock (Context .class );
105
+ when ( context . getApplicationContext ()). thenReturn ( appContext );
104
106
105
107
OptimizelyManager .DataFileServiceConnection dataFileServiceConnection = mock (OptimizelyManager .DataFileServiceConnection .class );
106
108
optimizelyManager .setDataFileServiceConnection (dataFileServiceConnection );
107
109
when (dataFileServiceConnection .isBound ()).thenReturn (true );
108
110
109
- optimizelyManager .stop (activity , activityLifecycleCallbacks );
111
+ optimizelyManager .stop (context );
110
112
111
113
assertNull (optimizelyManager .getOptimizelyStartListener ());
112
- verify (context ).unbindService (dataFileServiceConnection );
114
+ verify (appContext ).unbindService (dataFileServiceConnection );
113
115
}
114
116
115
- // TODO add a data file fixture so parsing doesn't fail in SST core
116
117
@ Test
117
- @ Ignore
118
118
public void injectOptimizely () {
119
119
Context context = mock (Context .class );
120
120
AndroidUserExperimentRecord userExperimentRecord = mock (AndroidUserExperimentRecord .class );
121
121
ServiceScheduler serviceScheduler = mock (ServiceScheduler .class );
122
122
ArgumentCaptor <Intent > captor = ArgumentCaptor .forClass (Intent .class );
123
123
OptimizelyStartListener startListener = mock (OptimizelyStartListener .class );
124
124
optimizelyManager .setOptimizelyStartListener (startListener );
125
- optimizelyManager .injectOptimizely (context , userExperimentRecord , serviceScheduler , "" );
125
+ optimizelyManager .injectOptimizely (context , userExperimentRecord , serviceScheduler , minDataFile );
126
126
try {
127
127
executor .awaitTermination (5 , TimeUnit .SECONDS );
128
128
} catch (InterruptedException e ) {
129
129
fail ("Timed out" );
130
130
}
131
131
132
132
verify (userExperimentRecord ).start ();
133
- verify (serviceScheduler ).schedule (captor .capture (), TimeUnit .HOURS .toMillis (1L ));
133
+ verify (serviceScheduler ).schedule (captor .capture (), eq ( TimeUnit .HOURS .toMillis (1L ) ));
134
134
verify (logger ).info ("Sending Optimizely instance to listener" );
135
135
verify (startListener ).onStart (any (AndroidOptimizely .class ));
136
136
}
@@ -142,9 +142,8 @@ public void injectOptimizelyNullListener() {
142
142
AndroidUserExperimentRecord userExperimentRecord = mock (AndroidUserExperimentRecord .class );
143
143
ServiceScheduler serviceScheduler = mock (ServiceScheduler .class );
144
144
ArgumentCaptor <Intent > captor = ArgumentCaptor .forClass (Intent .class );
145
- OptimizelyStartListener startListener = mock (OptimizelyStartListener .class );
146
145
optimizelyManager .setOptimizelyStartListener (null );
147
- optimizelyManager .injectOptimizely (context , userExperimentRecord , serviceScheduler , "" );
146
+ optimizelyManager .injectOptimizely (context , userExperimentRecord , serviceScheduler , minDataFile );
148
147
try {
149
148
executor .awaitTermination (5 , TimeUnit .SECONDS );
150
149
} catch (InterruptedException e ) {
@@ -154,10 +153,65 @@ public void injectOptimizelyNullListener() {
154
153
verify (userExperimentRecord ).start ();
155
154
verify (serviceScheduler ).schedule (captor .capture (), eq (TimeUnit .HOURS .toMillis (1L )));
156
155
verify (logger ).info ("No listener to send Optimizely to" );
157
- verify (startListener , never ()).onStart (any (AndroidOptimizely .class ));
158
156
159
157
Intent intent = captor .getValue ();
160
158
assertTrue (intent .getComponent ().getShortClassName ().contains ("DataFileService" ));
161
159
assertEquals (optimizelyManager .getProjectId (), intent .getStringExtra (DataFileService .EXTRA_PROJECT_ID ));
162
160
}
161
+
162
+ @ Test
163
+ public void injectOptimizelyHandlesInvalidDataFile () {
164
+ Context context = mock (Context .class );
165
+ when (context .getPackageName ()).thenReturn ("com.optly" );
166
+ AndroidUserExperimentRecord userExperimentRecord = mock (AndroidUserExperimentRecord .class );
167
+ ServiceScheduler serviceScheduler = mock (ServiceScheduler .class );
168
+ ArgumentCaptor <Intent > captor = ArgumentCaptor .forClass (Intent .class );
169
+ optimizelyManager .setOptimizelyStartListener (null );
170
+ optimizelyManager .injectOptimizely (context , userExperimentRecord , serviceScheduler , "{}" );
171
+ try {
172
+ executor .awaitTermination (5 , TimeUnit .SECONDS );
173
+ } catch (InterruptedException e ) {
174
+ fail ("Timed out" );
175
+ }
176
+
177
+ verify (userExperimentRecord ).start ();
178
+ verify (serviceScheduler ).schedule (captor .capture (), eq (TimeUnit .HOURS .toMillis (1L )));
179
+ verify (logger ).error (eq ("Unable to build optimizely instance" ), any (Exception .class ));
180
+
181
+ Intent intent = captor .getValue ();
182
+ assertTrue (intent .getComponent ().getShortClassName ().contains ("DataFileService" ));
183
+ assertEquals (optimizelyManager .getProjectId (), intent .getStringExtra (DataFileService .EXTRA_PROJECT_ID ));
184
+ }
185
+
186
+ @ Test
187
+ public void injectOptimizelyDoesNotDuplicateCallback () {
188
+ Context context = mock (Context .class );
189
+ when (context .getPackageName ()).thenReturn ("com.optly" );
190
+ AndroidUserExperimentRecord userExperimentRecord = mock (AndroidUserExperimentRecord .class );
191
+ ServiceScheduler serviceScheduler = mock (ServiceScheduler .class );
192
+ ArgumentCaptor <Intent > captor = ArgumentCaptor .forClass (Intent .class );
193
+ OptimizelyStartListener startListener = mock (OptimizelyStartListener .class );
194
+ optimizelyManager .setOptimizelyStartListener (startListener );
195
+ optimizelyManager .injectOptimizely (context , userExperimentRecord , serviceScheduler , minDataFile );
196
+ try {
197
+ executor .awaitTermination (5 , TimeUnit .SECONDS );
198
+ } catch (InterruptedException e ) {
199
+ fail ("Timed out" );
200
+ }
201
+
202
+ verify (userExperimentRecord ).start ();
203
+ verify (serviceScheduler ).schedule (captor .capture (), eq (TimeUnit .HOURS .toMillis (1L )));
204
+
205
+ verify (logger ).info ("Sending Optimizely instance to listener" );
206
+ verify (startListener ).onStart (any (AndroidOptimizely .class ));
207
+
208
+ optimizelyManager .injectOptimizely (context , userExperimentRecord , serviceScheduler , minDataFile );
209
+ try {
210
+ executor .awaitTermination (5 , TimeUnit .SECONDS );
211
+ } catch (InterruptedException e ) {
212
+ fail ("Timed out" );
213
+ }
214
+
215
+ verify (logger ).info ("No listener to send Optimizely to" );
216
+ }
163
217
}
0 commit comments