1 // Copyright 2019 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.chrome.browser.notifications; 6 7 import static org.junit.Assert.assertEquals; 8 import static org.junit.Assert.assertFalse; 9 import static org.junit.Assert.assertTrue; 10 import static org.mockito.Mockito.any; 11 import static org.mockito.Mockito.anyBoolean; 12 import static org.mockito.Mockito.doReturn; 13 import static org.mockito.Mockito.eq; 14 import static org.mockito.Mockito.never; 15 import static org.mockito.Mockito.verify; 16 17 import android.os.Bundle; 18 19 import org.junit.After; 20 import org.junit.Before; 21 import org.junit.Test; 22 import org.junit.runner.RunWith; 23 import org.mockito.ArgumentCaptor; 24 import org.mockito.Mock; 25 import org.mockito.MockitoAnnotations; 26 import org.robolectric.RuntimeEnvironment; 27 import org.robolectric.annotation.Config; 28 29 import org.chromium.base.SysUtils; 30 import org.chromium.base.test.BaseRobolectricTestRunner; 31 import org.chromium.chrome.browser.background_task_scheduler.ChromeBackgroundTaskFactory; 32 import org.chromium.components.background_task_scheduler.BackgroundTask; 33 import org.chromium.components.background_task_scheduler.BackgroundTaskScheduler; 34 import org.chromium.components.background_task_scheduler.BackgroundTaskSchedulerFactory; 35 import org.chromium.components.background_task_scheduler.NativeBackgroundTask; 36 import org.chromium.components.background_task_scheduler.TaskIds; 37 import org.chromium.components.background_task_scheduler.TaskInfo; 38 import org.chromium.components.background_task_scheduler.TaskParameters; 39 40 /** 41 * Unit tests for NotificationTriggerBackgroundTask. 42 */ 43 @RunWith(BaseRobolectricTestRunner.class) 44 @Config(manifest = Config.NONE) 45 public class NotificationTriggerBackgroundTaskTest { 46 @Mock 47 private BackgroundTaskScheduler mTaskScheduler; 48 @Mock 49 private NotificationTriggerScheduler mTriggerScheduler; 50 @Mock 51 private BackgroundTask.TaskFinishedCallback mTaskFinishedCallback; 52 53 @Before setUp()54 public void setUp() { 55 MockitoAnnotations.initMocks(this); 56 BackgroundTaskSchedulerFactory.setSchedulerForTesting(mTaskScheduler); 57 ChromeBackgroundTaskFactory.setAsDefault(); 58 NotificationTriggerScheduler.setInstanceForTests(mTriggerScheduler); 59 } 60 61 @After tearDown()62 public void tearDown() { 63 SysUtils.resetForTesting(); 64 } 65 createTaskParameters(long timestamp)66 private static TaskParameters createTaskParameters(long timestamp) { 67 Bundle extras = new Bundle(); 68 extras.putLong(NotificationTriggerBackgroundTask.KEY_TIMESTAMP, timestamp); 69 return TaskParameters.create(TaskIds.NOTIFICATION_TRIGGER_JOB_ID).addExtras(extras).build(); 70 } 71 72 @Test testScheduleInitializesOneOffTask()73 public void testScheduleInitializesOneOffTask() { 74 long delay = 1000; 75 long timestamp = System.currentTimeMillis() + delay; 76 ArgumentCaptor<TaskInfo> taskInfoCaptor = ArgumentCaptor.forClass(TaskInfo.class); 77 NotificationTriggerBackgroundTask.schedule(timestamp, delay); 78 verify(mTaskScheduler).schedule(any(), taskInfoCaptor.capture()); 79 TaskInfo taskInfo = taskInfoCaptor.getValue(); 80 81 assertEquals(TaskIds.NOTIFICATION_TRIGGER_JOB_ID, taskInfo.getTaskId()); 82 assertTrue(taskInfo.isPersisted()); 83 assertTrue(taskInfo.shouldUpdateCurrent()); 84 assertEquals(TaskInfo.NetworkType.NONE, taskInfo.getRequiredNetworkType()); 85 assertEquals(timestamp, 86 taskInfo.getExtras().getLong(NotificationTriggerBackgroundTask.KEY_TIMESTAMP)); 87 TaskInfo.TimingInfo timingInfo = taskInfo.getTimingInfo(); 88 assertTrue(timingInfo instanceof TaskInfo.ExactInfo); 89 TaskInfo.ExactInfo exactTimingInfo = (TaskInfo.ExactInfo) timingInfo; 90 assertEquals(timestamp, exactTimingInfo.getTriggerAtMs()); 91 } 92 93 @Test testCancelCancelsTask()94 public void testCancelCancelsTask() { 95 NotificationTriggerBackgroundTask.cancel(); 96 verify(mTaskScheduler).cancel(any(), eq(TaskIds.NOTIFICATION_TRIGGER_JOB_ID)); 97 } 98 99 @Test testRescheduleCallsScheduler()100 public void testRescheduleCallsScheduler() { 101 new NotificationTriggerBackgroundTask().reschedule(RuntimeEnvironment.application); 102 verify(mTriggerScheduler).reschedule(); 103 } 104 105 @Test testStartBeforeNative_ValidTrigger()106 public void testStartBeforeNative_ValidTrigger() { 107 long timestamp = System.currentTimeMillis() + 1000; 108 doReturn(true).when(mTriggerScheduler).checkAndResetTrigger(eq(timestamp)); 109 110 int result = new NotificationTriggerBackgroundTask().onStartTaskBeforeNativeLoaded( 111 RuntimeEnvironment.application, createTaskParameters(timestamp), 112 mTaskFinishedCallback); 113 114 assertEquals(NativeBackgroundTask.StartBeforeNativeResult.LOAD_NATIVE, result); 115 verify(mTriggerScheduler).checkAndResetTrigger(eq(timestamp)); 116 verify(mTaskFinishedCallback, never()).taskFinished(anyBoolean()); 117 } 118 119 @Test testStartBeforeNative_InvalidTrigger()120 public void testStartBeforeNative_InvalidTrigger() { 121 long timestamp = System.currentTimeMillis() + 1000; 122 doReturn(false).when(mTriggerScheduler).checkAndResetTrigger(eq(timestamp)); 123 124 int result = new NotificationTriggerBackgroundTask().onStartTaskBeforeNativeLoaded( 125 RuntimeEnvironment.application, createTaskParameters(timestamp), 126 mTaskFinishedCallback); 127 128 assertEquals(NativeBackgroundTask.StartBeforeNativeResult.DONE, result); 129 verify(mTriggerScheduler).checkAndResetTrigger(eq(timestamp)); 130 verify(mTaskFinishedCallback, never()).taskFinished(anyBoolean()); 131 } 132 133 @Test testStartWithNativeCallsTriggerNotifications()134 public void testStartWithNativeCallsTriggerNotifications() { 135 long timestamp = System.currentTimeMillis() + 1000; 136 new NotificationTriggerBackgroundTask().onStartTaskWithNative( 137 RuntimeEnvironment.application, createTaskParameters(timestamp), 138 mTaskFinishedCallback); 139 140 verify(mTriggerScheduler).triggerNotifications(); 141 verify(mTaskFinishedCallback).taskFinished(eq(false)); 142 } 143 144 @Test testReschedule_BeforeNative()145 public void testReschedule_BeforeNative() { 146 long timestamp = System.currentTimeMillis() + 1000; 147 boolean shouldReschedule = 148 new NotificationTriggerBackgroundTask().onStopTaskBeforeNativeLoaded( 149 RuntimeEnvironment.application, createTaskParameters(timestamp)); 150 assertTrue(shouldReschedule); 151 } 152 153 @Test testReschedule_WithNative()154 public void testReschedule_WithNative() { 155 long timestamp = System.currentTimeMillis() + 1000; 156 boolean shouldReschedule = new NotificationTriggerBackgroundTask().onStopTaskWithNative( 157 RuntimeEnvironment.application, createTaskParameters(timestamp)); 158 assertTrue(shouldReschedule); 159 } 160 161 @Test testReschedule_AfterTriggerBeforeNative()162 public void testReschedule_AfterTriggerBeforeNative() { 163 long timestamp = System.currentTimeMillis() + 1000; 164 165 NotificationTriggerBackgroundTask task = new NotificationTriggerBackgroundTask(); 166 TaskParameters params = createTaskParameters(timestamp); 167 task.onStartTaskWithNative(RuntimeEnvironment.application, params, mTaskFinishedCallback); 168 boolean shouldReschedule = 169 task.onStopTaskBeforeNativeLoaded(RuntimeEnvironment.application, params); 170 171 assertFalse(shouldReschedule); 172 } 173 174 @Test testReschedule_AfterTriggerWithNative()175 public void testReschedule_AfterTriggerWithNative() { 176 long timestamp = System.currentTimeMillis() + 1000; 177 178 NotificationTriggerBackgroundTask task = new NotificationTriggerBackgroundTask(); 179 TaskParameters params = createTaskParameters(timestamp); 180 task.onStartTaskWithNative(RuntimeEnvironment.application, params, mTaskFinishedCallback); 181 boolean shouldReschedule = 182 task.onStopTaskWithNative(RuntimeEnvironment.application, params); 183 184 assertFalse(shouldReschedule); 185 } 186 187 @Test testReschedule_ValidTriggerBeforeNative()188 public void testReschedule_ValidTriggerBeforeNative() { 189 long timestamp = System.currentTimeMillis() + 1000; 190 doReturn(true).when(mTriggerScheduler).checkAndResetTrigger(eq(timestamp)); 191 192 NotificationTriggerBackgroundTask task = new NotificationTriggerBackgroundTask(); 193 TaskParameters params = createTaskParameters(timestamp); 194 task.onStartTaskBeforeNativeLoaded( 195 RuntimeEnvironment.application, params, mTaskFinishedCallback); 196 boolean shouldReschedule = 197 task.onStopTaskBeforeNativeLoaded(RuntimeEnvironment.application, params); 198 199 assertTrue(shouldReschedule); 200 } 201 202 @Test testReschedule_ValidTriggerWithNative()203 public void testReschedule_ValidTriggerWithNative() { 204 long timestamp = System.currentTimeMillis() + 1000; 205 doReturn(true).when(mTriggerScheduler).checkAndResetTrigger(eq(timestamp)); 206 207 NotificationTriggerBackgroundTask task = new NotificationTriggerBackgroundTask(); 208 TaskParameters params = createTaskParameters(timestamp); 209 task.onStartTaskBeforeNativeLoaded( 210 RuntimeEnvironment.application, params, mTaskFinishedCallback); 211 boolean shouldReschedule = 212 task.onStopTaskWithNative(RuntimeEnvironment.application, params); 213 214 assertTrue(shouldReschedule); 215 } 216 217 @Test testReschedule_InvalidTriggerBeforeNative()218 public void testReschedule_InvalidTriggerBeforeNative() { 219 long timestamp = System.currentTimeMillis() + 1000; 220 doReturn(false).when(mTriggerScheduler).checkAndResetTrigger(eq(timestamp)); 221 222 NotificationTriggerBackgroundTask task = new NotificationTriggerBackgroundTask(); 223 TaskParameters params = createTaskParameters(timestamp); 224 task.onStartTaskBeforeNativeLoaded( 225 RuntimeEnvironment.application, params, mTaskFinishedCallback); 226 boolean shouldReschedule = 227 task.onStopTaskBeforeNativeLoaded(RuntimeEnvironment.application, params); 228 229 assertFalse(shouldReschedule); 230 } 231 232 @Test testReschedule_InvalidTriggerWithNative()233 public void testReschedule_InvalidTriggerWithNative() { 234 long timestamp = System.currentTimeMillis() + 1000; 235 doReturn(false).when(mTriggerScheduler).checkAndResetTrigger(eq(timestamp)); 236 237 NotificationTriggerBackgroundTask task = new NotificationTriggerBackgroundTask(); 238 TaskParameters params = createTaskParameters(timestamp); 239 task.onStartTaskBeforeNativeLoaded( 240 RuntimeEnvironment.application, params, mTaskFinishedCallback); 241 boolean shouldReschedule = 242 task.onStopTaskWithNative(RuntimeEnvironment.application, params); 243 244 assertFalse(shouldReschedule); 245 } 246 } 247