1515 */
1616package com .optimizely .ab .android .sdk ;
1717
18- import android .app .Activity ;
1918import android .content .Context ;
2019import android .content .Intent ;
2120import android .support .test .espresso .core .deps .guava .util .concurrent .ListeningExecutorService ;
2625import com .optimizely .user_experiment_record .AndroidUserExperimentRecord ;
2726
2827import org .junit .Before ;
29- import org .junit .Ignore ;
3028import org .junit .Test ;
3129import org .junit .runner .RunWith ;
3230import org .mockito .ArgumentCaptor ;
4240import static org .mockito .Matchers .any ;
4341import static org .mockito .Matchers .eq ;
4442import static org .mockito .Mockito .mock ;
45- import static org .mockito .Mockito .never ;
4643import static org .mockito .Mockito .verify ;
4744import static org .mockito .Mockito .when ;
4845
4946/**
5047 * Created by jdeffibaugh on 8/3/16 for Optimizely.
5148 *
5249 * 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
5950 */
6051@ RunWith (AndroidJUnit4 .class )
6152public class OptimizelyManagerTest {
@@ -65,6 +56,18 @@ public class OptimizelyManagerTest {
6556 Logger logger ;
6657 OptimizelyManager optimizelyManager ;
6758
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+
6871 @ Before
6972 public void setup () {
7073 logger = mock (Logger .class );
@@ -76,61 +79,58 @@ public void setup() {
7679
7780 @ SuppressWarnings ("WrongConstant" )
7881 @ Test
79- @ Ignore
8082 public void start () {
8183 OptimizelyStartListener startListener = mock (OptimizelyStartListener .class );
82- Activity activity = mock (Activity .class );
8384 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" );
8588 ArgumentCaptor <Intent > captor = ArgumentCaptor .forClass (Intent .class );
8689
87- optimizelyManager .start (activity , startListener );
90+ optimizelyManager .start (context , startListener );
8891
8992 assertNotNull (optimizelyManager .getOptimizelyStartListener ());
9093 assertNotNull (optimizelyManager .getDataFileServiceConnection ());
9194
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 ));
9396
9497 Intent intent = captor .getValue ();
9598 assertTrue (intent .getComponent ().getShortClassName ().contains ("DataFileService" ));
9699 }
97100
98101 @ Test
99- @ Ignore
100102 public void stop () {
101103 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 );
104106
105107 OptimizelyManager .DataFileServiceConnection dataFileServiceConnection = mock (OptimizelyManager .DataFileServiceConnection .class );
106108 optimizelyManager .setDataFileServiceConnection (dataFileServiceConnection );
107109 when (dataFileServiceConnection .isBound ()).thenReturn (true );
108110
109- optimizelyManager .stop (activity , activityLifecycleCallbacks );
111+ optimizelyManager .stop (context );
110112
111113 assertNull (optimizelyManager .getOptimizelyStartListener ());
112- verify (context ).unbindService (dataFileServiceConnection );
114+ verify (appContext ).unbindService (dataFileServiceConnection );
113115 }
114116
115- // TODO add a data file fixture so parsing doesn't fail in SST core
116117 @ Test
117- @ Ignore
118118 public void injectOptimizely () {
119119 Context context = mock (Context .class );
120120 AndroidUserExperimentRecord userExperimentRecord = mock (AndroidUserExperimentRecord .class );
121121 ServiceScheduler serviceScheduler = mock (ServiceScheduler .class );
122122 ArgumentCaptor <Intent > captor = ArgumentCaptor .forClass (Intent .class );
123123 OptimizelyStartListener startListener = mock (OptimizelyStartListener .class );
124124 optimizelyManager .setOptimizelyStartListener (startListener );
125- optimizelyManager .injectOptimizely (context , userExperimentRecord , serviceScheduler , "" );
125+ optimizelyManager .injectOptimizely (context , userExperimentRecord , serviceScheduler , minDataFile );
126126 try {
127127 executor .awaitTermination (5 , TimeUnit .SECONDS );
128128 } catch (InterruptedException e ) {
129129 fail ("Timed out" );
130130 }
131131
132132 verify (userExperimentRecord ).start ();
133- verify (serviceScheduler ).schedule (captor .capture (), TimeUnit .HOURS .toMillis (1L ));
133+ verify (serviceScheduler ).schedule (captor .capture (), eq ( TimeUnit .HOURS .toMillis (1L ) ));
134134 verify (logger ).info ("Sending Optimizely instance to listener" );
135135 verify (startListener ).onStart (any (AndroidOptimizely .class ));
136136 }
@@ -142,9 +142,8 @@ public void injectOptimizelyNullListener() {
142142 AndroidUserExperimentRecord userExperimentRecord = mock (AndroidUserExperimentRecord .class );
143143 ServiceScheduler serviceScheduler = mock (ServiceScheduler .class );
144144 ArgumentCaptor <Intent > captor = ArgumentCaptor .forClass (Intent .class );
145- OptimizelyStartListener startListener = mock (OptimizelyStartListener .class );
146145 optimizelyManager .setOptimizelyStartListener (null );
147- optimizelyManager .injectOptimizely (context , userExperimentRecord , serviceScheduler , "" );
146+ optimizelyManager .injectOptimizely (context , userExperimentRecord , serviceScheduler , minDataFile );
148147 try {
149148 executor .awaitTermination (5 , TimeUnit .SECONDS );
150149 } catch (InterruptedException e ) {
@@ -154,10 +153,65 @@ public void injectOptimizelyNullListener() {
154153 verify (userExperimentRecord ).start ();
155154 verify (serviceScheduler ).schedule (captor .capture (), eq (TimeUnit .HOURS .toMillis (1L )));
156155 verify (logger ).info ("No listener to send Optimizely to" );
157- verify (startListener , never ()).onStart (any (AndroidOptimizely .class ));
158156
159157 Intent intent = captor .getValue ();
160158 assertTrue (intent .getComponent ().getShortClassName ().contains ("DataFileService" ));
161159 assertEquals (optimizelyManager .getProjectId (), intent .getStringExtra (DataFileService .EXTRA_PROJECT_ID ));
162160 }
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+ }
163217}
0 commit comments