package org.robolectric.android.controller;
import static org.assertj.core.api.Assertions.assertThat;
import static org.robolectric.Shadows.shadowOf;
import static org.robolectric.util.TestUtil.assertStringsInclude;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.TestRunners;
import android.app.IntentService;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import org.robolectric.android.controller.IntentServiceController;
import org.robolectric.shadows.CoreShadowsAdapter;
import org.robolectric.shadows.ShadowLooper;
import org.robolectric.util.TestUtil;
import java.util.ArrayList;
import java.util.List;
@RunWith(TestRunners.SelfTest.class)
public class IntentServiceControllerTest {
private static final List<String> transcript = new ArrayList<>();
private final ComponentName componentName = new ComponentName("org.robolectric", MyService.class.getName());
private final IntentServiceController<MyService> controller = Robolectric.buildIntentService(MyService.class, new Intent());
@Before
public void setUp() throws Exception {
transcript.clear();
}
@Test
public void onBindShouldSetIntent() throws Exception {
MyService myService = controller.create().bind().get();
assertThat(myService.boundIntent).isNotNull();
assertThat(myService.boundIntent.getComponent()).isEqualTo(componentName);
}
@Test
public void onStartCommandShouldSetIntent() throws Exception {
MyService myService = controller.create().startCommand(3, 4).get();
assertThat(myService.startIntent).isNotNull();
assertThat(myService.startIntent.getComponent()).isEqualTo(componentName);
}
@Test
public void onBindShouldSetIntentComponentWithCustomIntentWithoutComponentSet() throws Exception {
MyService myService = Robolectric.buildIntentService(MyService.class, new Intent(Intent.ACTION_VIEW)).bind().get();
assertThat(myService.boundIntent.getAction()).isEqualTo(Intent.ACTION_VIEW);
assertThat(myService.boundIntent.getComponent()).isEqualTo(componentName);
}
@Test
public void shouldSetIntentForGivenServiceInstance() throws Exception {
IntentServiceController<MyService> intentServiceController = IntentServiceController.of(new CoreShadowsAdapter(), new MyService(""), null).bind();
assertThat(intentServiceController.get().boundIntent).isNotNull();
}
@Test
public void whenLooperIsNotPaused_shouldCreateWithMainLooperPaused() throws Exception {
ShadowLooper.unPauseMainLooper();
controller.create();
assertThat(shadowOf(Looper.getMainLooper()).isPaused()).isFalse();
assertStringsInclude(transcript, "finishedOnCreate", "onCreate");
}
@Test
public void whenLooperIsAlreadyPaused_shouldCreateWithMainLooperPaused() throws Exception {
ShadowLooper.pauseMainLooper();
controller.create();
assertThat(shadowOf(Looper.getMainLooper()).isPaused()).isTrue();
assertStringsInclude(transcript, "finishedOnCreate");
ShadowLooper.unPauseMainLooper();
assertStringsInclude(transcript, "onCreate");
}
@Test
public void unbind_callsUnbindWhilePaused() {
controller.create().bind().unbind();
assertStringsInclude(transcript, "finishedOnUnbind", "onUnbind");
}
@Test
public void rebind_callsRebindWhilePaused() {
controller.create().bind().unbind().bind().rebind();
assertStringsInclude(transcript, "finishedOnRebind", "onRebind");
}
@Test
public void destroy_callsOnDestroyWhilePaused() {
controller.create().destroy();
assertStringsInclude(transcript, "finishedOnDestroy", "onDestroy");
}
@Test
public void bind_callsOnBindWhilePaused() {
controller.create().bind();
assertStringsInclude(transcript, "finishedOnBind", "onBind");
}
@Test
public void startCommand_callsOnHandleIntentWhilePaused() {
controller.create().startCommand(1, 2);
assertStringsInclude(transcript, "finishedOnHandleIntent", "onHandleIntent");
}
public static class MyService extends IntentService {
private Handler handler = new Handler(Looper.getMainLooper());
public Intent boundIntent;
public Intent reboundIntent;
public Intent startIntent;
public Intent unboundIntent;
public MyService(String name) {
super(name);
}
@Override
public IBinder onBind(Intent intent) {
boundIntent = intent;
transcribeWhilePaused("onBind");
transcript.add("finishedOnBind");
return null;
}
@Override
protected void onHandleIntent(Intent intent) {
startIntent = intent;
transcribeWhilePaused("onHandleIntent");
transcript.add("finishedOnHandleIntent");
}
@Override
public void onCreate() {
super.onCreate();
transcribeWhilePaused("onCreate");
transcript.add("finishedOnCreate");
}
@Override
public void onDestroy() {
super.onDestroy();
transcribeWhilePaused("onDestroy");
transcript.add("finishedOnDestroy");
}
@Override
public void onRebind(Intent intent) {
reboundIntent = intent;
transcribeWhilePaused("onRebind");
transcript.add("finishedOnRebind");
}
@Override
public boolean onUnbind(Intent intent) {
unboundIntent = intent;
transcribeWhilePaused("onUnbind");
transcript.add("finishedOnUnbind");
return false;
}
private void transcribeWhilePaused(final String event) {
runOnUiThread(new Runnable() {
@Override public void run() {
transcript.add(event);
}
});
}
private void runOnUiThread(Runnable action) {
// This is meant to emulate the behavior of Activity.runOnUiThread();
shadowOf(handler.getLooper()).getScheduler().post(action);
}
}
}