1package com.xtremelabs.robolectric.shadows;
2
3import android.app.Activity;
4import android.appwidget.AppWidgetProvider;
5import android.content.BroadcastReceiver;
6import android.content.Context;
7import android.content.ContextWrapper;
8import android.content.Intent;
9import android.content.IntentFilter;
10import com.xtremelabs.robolectric.Robolectric;
11import com.xtremelabs.robolectric.WithTestDefaultsRunner;
12import com.xtremelabs.robolectric.util.Transcript;
13import org.junit.Before;
14import org.junit.Test;
15import org.junit.runner.RunWith;
16
17import java.util.List;
18
19import static android.content.pm.PackageManager.PERMISSION_DENIED;
20import static android.content.pm.PackageManager.PERMISSION_GRANTED;
21import static com.xtremelabs.robolectric.Robolectric.shadowOf;
22import static junit.framework.Assert.assertEquals;
23import static org.hamcrest.CoreMatchers.notNullValue;
24import static org.hamcrest.CoreMatchers.nullValue;
25import static org.hamcrest.CoreMatchers.sameInstance;
26import static org.hamcrest.core.IsEqual.equalTo;
27import static org.junit.Assert.assertThat;
28import static org.junit.Assert.assertTrue;
29
30@RunWith(WithTestDefaultsRunner.class)
31public class ContextWrapperTest {
32    public Transcript transcript;
33    private ContextWrapper contextWrapper;
34
35    @Before public void setUp() throws Exception {
36        transcript = new Transcript();
37        contextWrapper = new ContextWrapper(new Activity());
38    }
39
40    @Test
41    public void registerReceiver_shouldRegisterForAllIntentFilterActions() throws Exception {
42        BroadcastReceiver receiver = broadcastReceiver("Larry");
43        contextWrapper.registerReceiver(receiver, intentFilter("foo", "baz"));
44
45        contextWrapper.sendBroadcast(new Intent("foo"));
46        transcript.assertEventsSoFar("Larry notified of foo");
47
48        contextWrapper.sendBroadcast(new Intent("womp"));
49        transcript.assertNoEventsSoFar();
50
51        contextWrapper.sendBroadcast(new Intent("baz"));
52        transcript.assertEventsSoFar("Larry notified of baz");
53    }
54
55    @Test
56    public void sendBroadcast_shouldSendIntentToEveryInterestedReceiver() throws Exception {
57        BroadcastReceiver larryReceiver = broadcastReceiver("Larry");
58        contextWrapper.registerReceiver(larryReceiver, intentFilter("foo", "baz"));
59
60        BroadcastReceiver bobReceiver = broadcastReceiver("Bob");
61        contextWrapper.registerReceiver(bobReceiver, intentFilter("foo"));
62
63        contextWrapper.sendBroadcast(new Intent("foo"));
64        transcript.assertEventsSoFar("Larry notified of foo", "Bob notified of foo");
65
66        contextWrapper.sendBroadcast(new Intent("womp"));
67        transcript.assertNoEventsSoFar();
68
69        contextWrapper.sendBroadcast(new Intent("baz"));
70        transcript.assertEventsSoFar("Larry notified of baz");
71    }
72
73    @Test
74    public void unregisterReceiver_shouldUnregisterReceiver() throws Exception {
75        BroadcastReceiver receiver = broadcastReceiver("Larry");
76
77        contextWrapper.registerReceiver(receiver, intentFilter("foo", "baz"));
78        contextWrapper.unregisterReceiver(receiver);
79
80        contextWrapper.sendBroadcast(new Intent("foo"));
81        transcript.assertNoEventsSoFar();
82    }
83
84    @Test(expected = IllegalArgumentException.class)
85    public void unregisterReceiver_shouldThrowExceptionWhenReceiverIsNotRegistered() throws Exception {
86        contextWrapper.unregisterReceiver(new AppWidgetProvider());
87    }
88
89    @Test
90    public void broadcastReceivers_shouldBeSharedAcrossContextsPerApplicationContext() throws Exception {
91        BroadcastReceiver receiver = broadcastReceiver("Larry");
92
93        new ContextWrapper(Robolectric.application).registerReceiver(receiver, intentFilter("foo", "baz"));
94        new ContextWrapper(Robolectric.application).sendBroadcast(new Intent("foo"));
95        Robolectric.application.sendBroadcast(new Intent("baz"));
96        transcript.assertEventsSoFar("Larry notified of foo", "Larry notified of baz");
97
98        new ContextWrapper(Robolectric.application).unregisterReceiver(receiver);
99    }
100
101	@Test
102	public void broadcasts_shouldBeLogged() {
103		Intent broadcastIntent = new Intent("foo");
104		contextWrapper.sendBroadcast(broadcastIntent);
105
106		List<Intent> broadcastIntents = shadowOf(contextWrapper).getBroadcastIntents();
107		assertTrue(broadcastIntents.size() == 1);
108		assertEquals(broadcastIntent, broadcastIntents.get(0));
109	}
110
111
112    @Test
113    public void shouldReturnSameApplicationEveryTime() throws Exception {
114        Activity activity = new Activity();
115        assertThat(activity.getApplication(), sameInstance(activity.getApplication()));
116
117        assertThat(activity.getApplication(), sameInstance(new Activity().getApplication()));
118    }
119
120    @Test
121    public void shouldReturnSameApplicationContextEveryTime() throws Exception {
122        Activity activity = new Activity();
123        assertThat(activity.getApplicationContext(), sameInstance(activity.getApplicationContext()));
124
125        assertThat(activity.getApplicationContext(), sameInstance(new Activity().getApplicationContext()));
126    }
127
128    @Test
129    public void shouldReturnSameContentResolverEveryTime() throws Exception {
130        Activity activity = new Activity();
131        assertThat(activity.getContentResolver(), sameInstance(activity.getContentResolver()));
132
133        assertThat(activity.getContentResolver(), sameInstance(new Activity().getContentResolver()));
134    }
135
136    @Test
137    public void shouldReturnSameLocationManagerEveryTime() throws Exception {
138        assertSameInstanceEveryTime(Context.LOCATION_SERVICE);
139    }
140
141    @Test
142    public void shouldReturnSameWifiManagerEveryTime() throws Exception {
143        assertSameInstanceEveryTime(Context.WIFI_SERVICE);
144    }
145
146    @Test
147    public void shouldReturnSameAlarmServiceEveryTime() throws Exception {
148        assertSameInstanceEveryTime(Context.ALARM_SERVICE);
149    }
150
151    @Test
152    public void checkPermissionsShouldReturnPermissionGrantedToAddedPermissions() throws Exception {
153        shadowOf(contextWrapper).grantPermissions("foo", "bar");
154        assertThat(contextWrapper.checkPermission("foo", 0, 0), equalTo(PERMISSION_GRANTED));
155        assertThat(contextWrapper.checkPermission("bar", 0, 0), equalTo(PERMISSION_GRANTED));
156        assertThat(contextWrapper.checkPermission("baz", 0, 0), equalTo(PERMISSION_DENIED));
157    }
158
159    @Test
160    public void shouldReturnAContext() {
161    	assertThat(contextWrapper.getBaseContext(), notNullValue());
162    	ShadowContextWrapper shContextWrapper = Robolectric.shadowOf(contextWrapper);
163    	shContextWrapper.attachBaseContext(null);
164    	assertThat(contextWrapper.getBaseContext(), nullValue());
165
166    	Activity baseContext = new Activity();
167    	shContextWrapper.attachBaseContext(baseContext);
168    	assertThat(contextWrapper.getBaseContext(), sameInstance((Context) baseContext));
169    }
170
171    private void assertSameInstanceEveryTime(String serviceName) {
172        Activity activity = new Activity();
173        assertThat(activity.getSystemService(serviceName), sameInstance(activity.getSystemService(serviceName)));
174
175        assertThat(activity.getSystemService(serviceName), sameInstance(new Activity().getSystemService(serviceName)));
176    }
177
178    @Test
179    public void bindServiceDelegatesToShadowApplication() {
180        contextWrapper.bindService(new Intent("foo"), new TestService(), Context.BIND_AUTO_CREATE);
181        assertEquals("foo", shadowOf(Robolectric.application).getNextStartedService().getAction());
182    }
183
184    private BroadcastReceiver broadcastReceiver(final String name) {
185        return new BroadcastReceiver() {
186            @Override public void onReceive(Context context, Intent intent) {
187                transcript.add(name + " notified of " + intent.getAction());
188            }
189        };
190    }
191
192    private IntentFilter intentFilter(String... actions) {
193        IntentFilter larryIntentFilter = new IntentFilter();
194        for (String action : actions) {
195            larryIntentFilter.addAction(action);
196        }
197        return larryIntentFilter;
198    }
199}
200