@@ -5,10 +5,11 @@ import android.content.Intent
55import io.mockk.coVerify
66import io.mockk.every
77import io.mockk.mockk
8- import io.mockk.mockkConstructor
98import io.mockk.mockkStatic
9+ import io.mockk.spyk
10+ import io.mockk.verify
11+ import android.content.BroadcastReceiver
1012import io.mockk.unmockkAll
11- import io.mockk.unmockkConstructor
1213import kotlinx.coroutines.CoroutineDispatcher
1314import kotlinx.coroutines.ExperimentalCoroutinesApi
1415import kotlinx.coroutines.test.StandardTestDispatcher
@@ -23,16 +24,24 @@ import org.ole.planet.myplanet.di.getBroadcastService
2324import org.ole.planet.myplanet.repository.NotificationsRepository
2425import org.ole.planet.myplanet.utils.DispatcherProvider
2526import org.ole.planet.myplanet.utils.NotificationUtils
26-
27+ import android.provider.Settings
28+ import org.junit.runner.RunWith
29+ import org.robolectric.RobolectricTestRunner
30+ import org.robolectric.annotation.Config
31+ import androidx.test.core.app.ApplicationProvider
32+
33+ @RunWith(RobolectricTestRunner ::class )
34+ @Config(sdk = [33 ], application = android.app.Application ::class )
2735@OptIn(ExperimentalCoroutinesApi ::class )
2836class NotificationActionReceiverTest {
2937
3038 private lateinit var receiver: NotificationActionReceiver
3139 private lateinit var mockContext: Context
32- private lateinit var mockNotificationsRepository: NotificationsRepository
3340 private lateinit var testDispatcher: CoroutineDispatcher
34- private lateinit var mockDispatcherProvider: DispatcherProvider
3541 private lateinit var testScope: TestScope
42+
43+ private val mockNotificationsRepository: NotificationsRepository = mockk(relaxed = true )
44+ private var mockDispatcherProvider: DispatcherProvider = mockk(relaxed = true )
3645 private lateinit var mockNotificationUtils: NotificationUtils .NotificationManager
3746
3847 @Before
@@ -42,22 +51,13 @@ class NotificationActionReceiverTest {
4251
4352 MainApplication .applicationScope = testScope
4453
45- mockContext = mockk<Context >(relaxed = true )
46- mockNotificationsRepository = mockk(relaxed = true )
47-
48- mockDispatcherProvider = object : DispatcherProvider {
49- override val main: CoroutineDispatcher = testDispatcher
50- override val io: CoroutineDispatcher = testDispatcher
51- override val default: CoroutineDispatcher = testDispatcher
52- override val unconfined: CoroutineDispatcher = testDispatcher
53- }
54+ mockContext = spyk(ApplicationProvider .getApplicationContext<Context >())
55+ every { mockContext.startActivity(any()) } returns Unit
5456
55- mockkConstructor(Intent ::class )
56- every { anyConstructed<Intent >().setPackage(any()) } answers { mockk() }
57- every { anyConstructed<Intent >().putExtra(any<String >(), any<String >()) } answers { mockk() }
58- every { anyConstructed<Intent >().putExtra(any<String >(), any<Boolean >()) } answers { mockk() }
59- every { anyConstructed<Intent >().flags = any() } returns Unit
60- every { anyConstructed<Intent >().action = any() } returns Unit
57+ every { mockDispatcherProvider.main } returns testDispatcher
58+ every { mockDispatcherProvider.io } returns testDispatcher
59+ every { mockDispatcherProvider.default } returns testDispatcher
60+ every { mockDispatcherProvider.unconfined } returns testDispatcher
6161
6262 mockNotificationUtils = mockk(relaxed = true )
6363 mockkStatic(NotificationUtils ::class )
@@ -66,17 +66,22 @@ class NotificationActionReceiverTest {
6666 mockkStatic(" org.ole.planet.myplanet.di.ServiceDependenciesEntryPointKt" )
6767 every { getBroadcastService(any()) } returns mockk(relaxed = true )
6868
69-
70- receiver = NotificationActionReceiver ().apply {
69+ receiver = spyk(NotificationActionReceiver ().apply {
7170 notificationsRepository = mockNotificationsRepository
7271 dispatcherProvider = mockDispatcherProvider
72+ })
73+ try {
74+ val injectedField = org.ole.planet.myplanet.services.Hilt_NotificationActionReceiver ::class .java.getDeclaredField(" injected" )
75+ injectedField.isAccessible = true
76+ injectedField.set(receiver, true )
77+ } catch (e: Exception ) {
78+ e.printStackTrace()
7379 }
7480 }
7581
7682 @After
7783 fun tearDown () {
7884 unmockkAll()
79- unmockkConstructor(Intent ::class )
8085 }
8186
8287 @Test
@@ -89,4 +94,71 @@ class NotificationActionReceiverTest {
8994
9095 coVerify { mockNotificationsRepository.markNotificationsAsRead(setOf (notificationId)) }
9196 }
97+
98+ @Test
99+ fun `test onReceive ACTION_MARK_AS_READ` () = testScope.runTest {
100+ val notificationId = " test_id"
101+ val mockIntent = Intent (NotificationUtils .ACTION_MARK_AS_READ )
102+ mockIntent.putExtra(NotificationUtils .EXTRA_NOTIFICATION_ID , notificationId)
103+
104+ val pendingResult = mockk<BroadcastReceiver .PendingResult >(relaxed = true )
105+ every { receiver.goAsync() } returns pendingResult
106+
107+ receiver.onReceive(mockContext, mockIntent)
108+ advanceUntilIdle()
109+
110+ coVerify { mockNotificationsRepository.markNotificationsAsRead(setOf (notificationId)) }
111+ verify { mockNotificationUtils.clearNotification(notificationId) }
112+ verify { pendingResult.finish() }
113+ }
114+
115+ @Test
116+ fun `test onReceive ACTION_STORAGE_SETTINGS` () = testScope.runTest {
117+ val notificationId = " test_id"
118+ val mockIntent = Intent (NotificationUtils .ACTION_STORAGE_SETTINGS )
119+ mockIntent.putExtra(NotificationUtils .EXTRA_NOTIFICATION_ID , notificationId)
120+
121+ val pendingResult = mockk<BroadcastReceiver .PendingResult >(relaxed = true )
122+ every { receiver.goAsync() } returns pendingResult
123+
124+ receiver.onReceive(mockContext, mockIntent)
125+ advanceUntilIdle()
126+
127+ coVerify { mockNotificationsRepository.markNotificationsAsRead(setOf (notificationId)) }
128+ val intentList = mutableListOf<Intent >()
129+ verify { mockContext.startActivity(capture(intentList)) }
130+ assert (intentList.any { it.action == Settings .ACTION_INTERNAL_STORAGE_SETTINGS })
131+ verify { mockNotificationUtils.clearNotification(notificationId) }
132+ verify { pendingResult.finish() }
133+ }
134+
135+ @Test
136+ fun `test onReceive ACTION_OPEN_NOTIFICATION` () = testScope.runTest {
137+ val notificationId = " test_id"
138+ val notificationType = " type"
139+ val relatedId = " related_id"
140+
141+ val mockIntent = Intent (NotificationUtils .ACTION_OPEN_NOTIFICATION )
142+ mockIntent.putExtra(NotificationUtils .EXTRA_NOTIFICATION_ID , notificationId)
143+ mockIntent.putExtra(NotificationUtils .EXTRA_NOTIFICATION_TYPE , notificationType)
144+ mockIntent.putExtra(NotificationUtils .EXTRA_RELATED_ID , relatedId)
145+
146+ val pendingResult = mockk<BroadcastReceiver .PendingResult >(relaxed = true )
147+ every { receiver.goAsync() } returns pendingResult
148+
149+ receiver.onReceive(mockContext, mockIntent)
150+ advanceUntilIdle()
151+
152+ coVerify { mockNotificationsRepository.markNotificationsAsRead(setOf (notificationId)) }
153+ val intentList = mutableListOf<Intent >()
154+ verify { mockContext.startActivity(capture(intentList)) }
155+ val targetIntent = intentList.find { it.getStringExtra(" notification_type" ) == notificationType }
156+ assert (targetIntent != null )
157+ assert (targetIntent?.getStringExtra(" notification_type" ) == notificationType)
158+ assert (targetIntent?.getStringExtra(" notification_id" ) == notificationId)
159+ assert (targetIntent?.getStringExtra(" related_id" ) == relatedId)
160+
161+ verify { mockNotificationUtils.clearNotification(notificationId) }
162+ verify { pendingResult.finish() }
163+ }
92164}
0 commit comments