Rahul Ravikumar | 06eec68 | 2019-09-18 14:29:19 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2019 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | package androidx.work.impl.foreground |
| 18 | |
| 19 | import android.app.Notification |
| 20 | import android.content.Context |
| 21 | import android.util.Log |
| 22 | import androidx.test.core.app.ApplicationProvider |
| 23 | import androidx.test.ext.junit.runners.AndroidJUnit4 |
| 24 | import androidx.test.filters.MediumTest |
| 25 | import androidx.work.Configuration |
| 26 | import androidx.work.Constraints |
Rahul Ravikumar | 3ceb16d | 2019-10-03 17:20:59 -0700 | [diff] [blame] | 27 | import androidx.work.ForegroundInfo |
Rahul Ravikumar | 06eec68 | 2019-09-18 14:29:19 -0700 | [diff] [blame] | 28 | import androidx.work.NetworkType |
Rahul Ravikumar | 06eec68 | 2019-09-18 14:29:19 -0700 | [diff] [blame] | 29 | import androidx.work.OneTimeWorkRequest |
Rahul Ravikumar | 0edc382 | 2019-09-26 16:07:46 -0700 | [diff] [blame] | 30 | import androidx.work.impl.Processor |
| 31 | import androidx.work.impl.Scheduler |
Rahul Ravikumar | 06eec68 | 2019-09-18 14:29:19 -0700 | [diff] [blame] | 32 | import androidx.work.impl.WorkDatabase |
| 33 | import androidx.work.impl.WorkManagerImpl |
| 34 | import androidx.work.impl.constraints.WorkConstraintsCallback |
| 35 | import androidx.work.impl.constraints.WorkConstraintsTracker |
Rahul Ravikumar | bee795cf | 2019-10-22 13:40:27 -0700 | [diff] [blame] | 36 | import androidx.work.impl.foreground.SystemForegroundDispatcher.createCancelWorkIntent |
Rahul Ravikumar | 06eec68 | 2019-09-18 14:29:19 -0700 | [diff] [blame] | 37 | import androidx.work.impl.foreground.SystemForegroundDispatcher.createNotifyIntent |
| 38 | import androidx.work.impl.foreground.SystemForegroundDispatcher.createStartForegroundIntent |
| 39 | import androidx.work.impl.foreground.SystemForegroundDispatcher.createStopForegroundIntent |
| 40 | import androidx.work.impl.utils.SynchronousExecutor |
| 41 | import androidx.work.impl.utils.taskexecutor.InstantWorkTaskExecutor |
| 42 | import androidx.work.impl.utils.taskexecutor.TaskExecutor |
| 43 | import androidx.work.worker.TestWorker |
Rahul Ravikumar | bee795cf | 2019-10-22 13:40:27 -0700 | [diff] [blame] | 44 | import org.hamcrest.CoreMatchers.`is` |
| 45 | import org.hamcrest.MatcherAssert.assertThat |
Rahul Ravikumar | 06eec68 | 2019-09-18 14:29:19 -0700 | [diff] [blame] | 46 | import org.junit.Before |
| 47 | import org.junit.Test |
| 48 | import org.junit.runner.RunWith |
| 49 | import org.mockito.ArgumentMatchers.any |
| 50 | import org.mockito.ArgumentMatchers.eq |
| 51 | import org.mockito.Mockito.mock |
| 52 | import org.mockito.Mockito.spy |
| 53 | import org.mockito.Mockito.times |
| 54 | import org.mockito.Mockito.verify |
| 55 | import org.mockito.Mockito.verifyZeroInteractions |
Rahul Ravikumar | bf043169 | 2019-10-03 11:26:50 -0700 | [diff] [blame] | 56 | import java.util.UUID |
Rahul Ravikumar | 06eec68 | 2019-09-18 14:29:19 -0700 | [diff] [blame] | 57 | |
| 58 | @RunWith(AndroidJUnit4::class) |
| 59 | @MediumTest |
| 60 | class SystemForegroundDispatcherTest { |
| 61 | |
| 62 | private lateinit var context: Context |
| 63 | private lateinit var config: Configuration |
| 64 | private lateinit var taskExecutor: TaskExecutor |
| 65 | private lateinit var workManager: WorkManagerImpl |
| 66 | private lateinit var workDatabase: WorkDatabase |
Rahul Ravikumar | 0edc382 | 2019-09-26 16:07:46 -0700 | [diff] [blame] | 67 | private lateinit var processor: Processor |
Rahul Ravikumar | 06eec68 | 2019-09-18 14:29:19 -0700 | [diff] [blame] | 68 | private lateinit var tracker: WorkConstraintsTracker |
| 69 | private lateinit var constraintsCallback: WorkConstraintsCallback |
| 70 | private lateinit var dispatcher: SystemForegroundDispatcher |
| 71 | private lateinit var dispatcherCallback: SystemForegroundDispatcher.Callback |
| 72 | |
| 73 | @Before |
| 74 | fun setUp() { |
| 75 | context = ApplicationProvider.getApplicationContext() |
| 76 | config = Configuration.Builder() |
| 77 | .setExecutor(SynchronousExecutor()) |
| 78 | .setMinimumLoggingLevel(Log.DEBUG) |
| 79 | .build() |
| 80 | taskExecutor = InstantWorkTaskExecutor() |
Rahul Ravikumar | 0edc382 | 2019-09-26 16:07:46 -0700 | [diff] [blame] | 81 | val scheduler = mock(Scheduler::class.java) |
| 82 | workDatabase = WorkDatabase.create(context, taskExecutor.backgroundExecutor, true) |
| 83 | processor = Processor(context, config, taskExecutor, workDatabase, listOf(scheduler)) |
| 84 | workManager = spy( |
| 85 | WorkManagerImpl( |
| 86 | context, |
| 87 | config, |
| 88 | taskExecutor, |
| 89 | workDatabase, |
| 90 | listOf(scheduler), |
| 91 | processor |
| 92 | ) |
| 93 | ) |
Rahul Ravikumar | 06eec68 | 2019-09-18 14:29:19 -0700 | [diff] [blame] | 94 | workDatabase = workManager.workDatabase |
Rahul Ravikumar | 06eec68 | 2019-09-18 14:29:19 -0700 | [diff] [blame] | 95 | // Initialize WorkConstraintsTracker |
| 96 | constraintsCallback = mock(WorkConstraintsCallback::class.java) |
| 97 | tracker = spy(WorkConstraintsTracker(context, taskExecutor, constraintsCallback)) |
| 98 | // Initialize dispatcher |
| 99 | dispatcherCallback = mock(SystemForegroundDispatcher.Callback::class.java) |
Rahul Ravikumar | 0908203 | 2019-10-18 13:26:48 -0700 | [diff] [blame] | 100 | dispatcher = spy(SystemForegroundDispatcher(context, workManager, tracker)) |
Rahul Ravikumar | 06eec68 | 2019-09-18 14:29:19 -0700 | [diff] [blame] | 101 | dispatcher.setCallback(dispatcherCallback) |
| 102 | } |
| 103 | |
| 104 | @Test |
| 105 | fun testStartForeground_noInteractions_workSpecHasNoConstraints() { |
| 106 | val request = OneTimeWorkRequest.Builder(TestWorker::class.java).build() |
| 107 | workDatabase.workSpecDao().insertWorkSpec(request.workSpec) |
| 108 | val intent = createStartForegroundIntent(context, request.stringId) |
| 109 | dispatcher.onStartCommand(intent) |
| 110 | verifyZeroInteractions(tracker) |
| 111 | } |
| 112 | |
| 113 | @Test |
| 114 | fun testStartForeground_trackConstraints_workSpecHasConstraints() { |
| 115 | val request = OneTimeWorkRequest.Builder(TestWorker::class.java) |
| 116 | .setConstraints( |
| 117 | Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build() |
| 118 | ).build() |
| 119 | workDatabase.workSpecDao().insertWorkSpec(request.workSpec) |
| 120 | |
| 121 | val intent = createStartForegroundIntent(context, request.stringId) |
| 122 | dispatcher.onStartCommand(intent) |
| 123 | verify(tracker, times(1)).replace(setOf(request.workSpec)) |
| 124 | } |
| 125 | |
| 126 | @Test |
| 127 | fun testStopForeground() { |
| 128 | val intent = createStopForegroundIntent(context) |
| 129 | dispatcher.onStartCommand(intent) |
| 130 | verify(dispatcherCallback, times(1)).stop() |
| 131 | } |
| 132 | |
| 133 | @Test |
| 134 | fun testHandleNotify() { |
Rahul Ravikumar | 3ceb16d | 2019-10-03 17:20:59 -0700 | [diff] [blame] | 135 | val workSpecId = "workSpecId" |
Rahul Ravikumar | b29c1de | 2019-12-04 12:20:34 -0800 | [diff] [blame^] | 136 | val notificationId = 1 |
Rahul Ravikumar | 06eec68 | 2019-09-18 14:29:19 -0700 | [diff] [blame] | 137 | val notification = mock(Notification::class.java) |
Rahul Ravikumar | b29c1de | 2019-12-04 12:20:34 -0800 | [diff] [blame^] | 138 | val metadata = ForegroundInfo(notificationId, notification) |
Rahul Ravikumar | 3ceb16d | 2019-10-03 17:20:59 -0700 | [diff] [blame] | 139 | val intent = createNotifyIntent(context, workSpecId, metadata) |
Rahul Ravikumar | 06eec68 | 2019-09-18 14:29:19 -0700 | [diff] [blame] | 140 | dispatcher.onStartCommand(intent) |
| 141 | verify(dispatcherCallback, times(1)) |
Rahul Ravikumar | b29c1de | 2019-12-04 12:20:34 -0800 | [diff] [blame^] | 142 | .notify(eq(notificationId), eq(0), eq(workSpecId), any<Notification>()) |
Rahul Ravikumar | 06eec68 | 2019-09-18 14:29:19 -0700 | [diff] [blame] | 143 | } |
| 144 | |
| 145 | @Test |
| 146 | fun testStartForeground_trackConstraints_constraintsUnMet() { |
| 147 | val request = OneTimeWorkRequest.Builder(TestWorker::class.java) |
| 148 | .setConstraints( |
| 149 | Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build() |
| 150 | ).build() |
| 151 | workDatabase.workSpecDao().insertWorkSpec(request.workSpec) |
| 152 | |
| 153 | val intent = createStartForegroundIntent(context, request.stringId) |
| 154 | dispatcher.onStartCommand(intent) |
| 155 | verify(tracker, times(1)).replace(setOf(request.workSpec)) |
| 156 | dispatcher.onAllConstraintsNotMet(listOf(request.workSpec.id)) |
| 157 | verify(workManager, times(1)).stopForegroundWork(eq(request.workSpec.id)) |
| 158 | } |
Rahul Ravikumar | bf043169 | 2019-10-03 11:26:50 -0700 | [diff] [blame] | 159 | |
| 160 | @Test |
| 161 | fun testCancelForegroundWork() { |
| 162 | val request = OneTimeWorkRequest.Builder(TestWorker::class.java) |
| 163 | .setConstraints( |
| 164 | Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build() |
| 165 | ).build() |
| 166 | workDatabase.workSpecDao().insertWorkSpec(request.workSpec) |
| 167 | |
| 168 | val intent = createStartForegroundIntent(context, request.stringId) |
| 169 | dispatcher.onStartCommand(intent) |
| 170 | verify(tracker, times(1)).replace(setOf(request.workSpec)) |
| 171 | val stopIntent = createCancelWorkIntent(context, request.stringId) |
| 172 | dispatcher.onStartCommand(stopIntent) |
| 173 | verify(workManager, times(1)).cancelWorkById(eq(UUID.fromString(request.workSpec.id))) |
Rahul Ravikumar | bee795cf | 2019-10-22 13:40:27 -0700 | [diff] [blame] | 174 | assertThat(processor.hasWork(), `is`(false)) |
Rahul Ravikumar | bf043169 | 2019-10-03 11:26:50 -0700 | [diff] [blame] | 175 | } |
Rahul Ravikumar | 06eec68 | 2019-09-18 14:29:19 -0700 | [diff] [blame] | 176 | } |