Bug 1322114 - Add test cases for MediaControlService draft
authorJulian_Chu <walkingice0204@gmail.com>
Thu, 12 Jan 2017 15:44:19 +0800
changeset 464154 89a7d459984d029c758d93360e7963a7015be2b8
parent 461202 58518a2fac51cc4228b5cb93c31d7df733d6cda2
child 542868 ccc8e79fdf32645f242da3e58b0e17c4f7b18d0a
push id42287
push userbmo:walkingice0204@gmail.com
push dateFri, 20 Jan 2017 13:58:06 +0000
bugs1322114
milestone53.0a1
Bug 1322114 - Add test cases for MediaControlService Also refactor MediaControlService to be test-friendly. MozReview-Commit-ID: 344cEEuVroG
mobile/android/base/java/org/mozilla/gecko/media/MediaControlService.java
mobile/android/tests/background/junit4/src/org/mozilla/gecko/media/TestMediaControlService.java
--- a/mobile/android/base/java/org/mozilla/gecko/media/MediaControlService.java
+++ b/mobile/android/base/java/org/mozilla/gecko/media/MediaControlService.java
@@ -14,16 +14,17 @@ import android.graphics.Paint;
 import android.graphics.Rect;
 import android.media.AudioManager;
 import android.media.session.MediaController;
 import android.media.session.MediaSession;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.support.annotation.CheckResult;
+import android.support.annotation.VisibleForTesting;
 import android.support.v4.app.NotificationManagerCompat;
 import android.util.Log;
 
 import org.mozilla.gecko.BrowserApp;
 import org.mozilla.gecko.GeckoApp;
 import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.PrefsHelper;
 import org.mozilla.gecko.R;
@@ -367,30 +368,41 @@ public class MediaControlService extends
         } else {
             stopForeground(false);
             NotificationManagerCompat.from(this)
                 .notify(MEDIA_CONTROL_ID, notification);
         }
     }
 
     private Notification.Action createNotificationAction() {
-        boolean isPlayAction = mMediaState.equals(State.PAUSED);
+        final Intent intent = createIntentUponState(mMediaState);
+        boolean isPlayAction = intent.getAction().equals(ACTION_RESUME);
 
         int icon = isPlayAction ? R.drawable.ic_media_play : R.drawable.ic_media_pause;
         String title = getString(isPlayAction ? R.string.media_play : R.string.media_pause);
-        String action = isPlayAction ? ACTION_RESUME : ACTION_PAUSE;
 
-        final Intent intent = new Intent(getApplicationContext(), MediaControlService.class);
-        intent.setAction(action);
         final PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 1, intent, 0);
 
         //noinspection deprecation - The new constructor is only for API > 23
         return new Notification.Action.Builder(icon, title, pendingIntent).build();
     }
 
+    /**
+     * This method encapsulated UI logic. For PLAYING state, UI should display a PAUSE icon.
+     * @param state The expected current state of MediaControlService
+     * @return corresponding Intent to be used for Notification
+     */
+    @VisibleForTesting
+    protected Intent createIntentUponState(State state) {
+        String action = state.equals(State.PLAYING) ? ACTION_PAUSE : ACTION_RESUME;
+        final Intent intent = new Intent(getApplicationContext(), MediaControlService.class);
+        intent.setAction(action);
+        return intent;
+    }
+
     private PendingIntent createContentIntent(int tabId) {
         Intent intent = new Intent(getApplicationContext(), BrowserApp.class);
         intent.setAction(GeckoApp.ACTION_SWITCH_TAB);
         intent.putExtra("TabId", tabId);
         return PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
     }
 
     private PendingIntent createDeleteIntent() {
new file mode 100644
--- /dev/null
+++ b/mobile/android/tests/background/junit4/src/org/mozilla/gecko/media/TestMediaControlService.java
@@ -0,0 +1,78 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+package org.mozilla.gecko.media;
+
+import android.content.Intent;
+
+import junit.framework.Assert;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.internal.util.reflection.Whitebox;
+import org.mozilla.gecko.Tab;
+import org.mozilla.gecko.Tabs;
+import org.mozilla.gecko.background.testhelpers.TestRunner;
+import org.mozilla.gecko.media.MediaControlService.State;
+import org.robolectric.Robolectric;
+
+import java.lang.ref.WeakReference;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+
+@RunWith(TestRunner.class)
+public class TestMediaControlService {
+
+    private MediaControlService mSpyService;
+    private Tab mMockTab;
+
+    @Before
+    public void setUp() {
+        MediaControlService service = Robolectric.buildService(MediaControlService.class).get();
+        mSpyService = spy(service);
+        mMockTab = mock(Tab.class);
+        // We should use White-box as less as possible. But this is not avoidable so far.
+        Whitebox.setInternalState(mSpyService, "mInitialize", true);
+    }
+
+    @Test
+    public void testTabPlayingMedia() throws Exception {
+        // If tab is playing media and got another MEDIA_PLAYING_CHANGE
+        // state should be PLAYING
+        Whitebox.setInternalState(mSpyService, "mTabReference", new WeakReference<>(mMockTab));
+        doReturn(true).when(mMockTab).isMediaPlaying();
+
+        mSpyService.onTabChanged(mMockTab, Tabs.TabEvents.MEDIA_PLAYING_CHANGE, "");
+        State state = (State) Whitebox.getInternalState(mSpyService, "mMediaState");
+        Assert.assertEquals(state, State.PLAYING);
+    }
+
+    @Test
+    public void testTabNotPlayingMedia() throws Exception {
+        // If tab is not playing media and got another MEDIA_PLAYING_CHANGE
+        // state should be STOPPED
+        Whitebox.setInternalState(mSpyService, "mTabReference", new WeakReference<>(mMockTab));
+        doReturn(false).when(mMockTab).isMediaPlaying();
+
+        mSpyService.onTabChanged(mMockTab, Tabs.TabEvents.MEDIA_PLAYING_CHANGE, "");
+        State state = (State) Whitebox.getInternalState(mSpyService, "mMediaState");
+        Assert.assertEquals(state, State.STOPPED);
+    }
+
+    @Test
+    public void testIntentForPlayingState() throws Exception {
+        // For PLAYING state, should create an PAUSE intent for notification
+        Intent intent = mSpyService.createIntentUponState(State.PLAYING);
+        Assert.assertEquals(intent.getAction(), MediaControlService.ACTION_PAUSE);
+    }
+
+    @Test
+    public void testIntentForPausedState() throws Exception {
+        // For PAUSED state, should create an RESUME intent for notification
+        Intent intent = mSpyService.createIntentUponState(State.PAUSED);
+        Assert.assertEquals(intent.getAction(), MediaControlService.ACTION_RESUME);
+    }
+}