Skip to content

Commit 81fa23a

Browse files
committed
tests
1 parent 54799ef commit 81fa23a

File tree

1 file changed

+165
-0
lines changed

1 file changed

+165
-0
lines changed
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package software.aws.toolkits.jetbrains.core.notifications
5+
6+
import io.mockk.every
7+
import io.mockk.mockk
8+
import io.mockk.spyk
9+
import io.mockk.verify
10+
import io.mockk.unmockkAll
11+
import io.mockk.mockkObject
12+
import org.junit.jupiter.api.AfterEach
13+
import org.junit.jupiter.api.BeforeEach
14+
import org.junit.jupiter.api.Test
15+
import com.intellij.openapi.project.Project
16+
import com.intellij.testFramework.ApplicationExtension
17+
import org.junit.jupiter.api.extension.ExtendWith
18+
import java.util.concurrent.atomic.AtomicBoolean
19+
20+
@ExtendWith(ApplicationExtension::class)
21+
class ProcessNotificationsBaseTest {
22+
private lateinit var sut: ProcessNotificationsBase
23+
private lateinit var project: Project
24+
private lateinit var dismissalState: NotificationDismissalState
25+
26+
@BeforeEach
27+
fun setUp() {
28+
project = mockk()
29+
dismissalState = spyk(NotificationDismissalState())
30+
31+
mockkObject(NotificationDismissalState)
32+
every { NotificationDismissalState.getInstance() } returns dismissalState
33+
34+
sut = spyk<ProcessNotificationsBase>(
35+
objToCopy = ProcessNotificationsBase(project)
36+
)
37+
38+
}
39+
40+
@Test
41+
fun `startup notifications are only processed on first poll`() {
42+
resetIsStartup()
43+
val startupNotification = createNotification("startup-1", NotificationScheduleType.STARTUP)
44+
every { sut["getNotificationsFromFile"]() } returns createNotificationsList(startupNotification)
45+
every { dismissalState.isDismissed(any()) } returns false
46+
47+
sut.retrieveStartupAndEmergencyNotifications()
48+
49+
verify(exactly = 1) { sut.processNotification(project, startupNotification) }
50+
51+
// Second poll
52+
sut.retrieveStartupAndEmergencyNotifications()
53+
54+
// Verify processNotification wasn't called again
55+
verify(exactly = 1) { sut.processNotification(project, any()) }
56+
}
57+
58+
@Test
59+
fun `non startup notifications are processed on every poll`() {
60+
val emergencyNotification = createNotification("emergency-1", NotificationScheduleType.EMERGENCY)
61+
every { sut["getNotificationsFromFile"]() } returns createNotificationsList(emergencyNotification)
62+
every { dismissalState.isDismissed(any()) } returns false
63+
64+
// First poll
65+
sut.retrieveStartupAndEmergencyNotifications()
66+
// Second poll
67+
sut.retrieveStartupAndEmergencyNotifications()
68+
69+
verify(exactly = 2) { sut.processNotification(project, emergencyNotification) }
70+
}
71+
72+
@Test
73+
fun `dismissed notifications are not processed`() {
74+
val notification = createNotification("toBeDismissed-1", NotificationScheduleType.EMERGENCY)
75+
every { sut["getNotificationsFromFile"]() } returns createNotificationsList(notification)
76+
77+
// first poll results in showing/dismissal
78+
sut.retrieveStartupAndEmergencyNotifications()
79+
NotificationDismissalState.getInstance().dismissNotification(notification.id)
80+
81+
// second poll skips processing
82+
sut.retrieveStartupAndEmergencyNotifications()
83+
84+
85+
verify(exactly = 1) { sut.processNotification(project, any()) }
86+
}
87+
88+
@Test
89+
fun `null notifications list is handled gracefully`() {
90+
every { sut["getNotificationsFromFile"]() } returns null
91+
92+
sut.retrieveStartupAndEmergencyNotifications()
93+
94+
verify(exactly = 0) { sut.processNotification(project, any()) }
95+
}
96+
97+
@Test
98+
fun `empty notifications list is handled gracefully`() {
99+
every { sut["getNotificationsFromFile"]()} returns createNotificationsList()
100+
101+
sut.retrieveStartupAndEmergencyNotifications()
102+
103+
verify(exactly = 0) { sut.processNotification(project, any()) }
104+
}
105+
106+
@Test
107+
fun `multiple notifications are processed correctly`() {
108+
val startupNotification = createNotification("startup-1", NotificationScheduleType.STARTUP)
109+
val emergencyNotification = createNotification("emergency-1", NotificationScheduleType.EMERGENCY)
110+
111+
every { sut["getNotificationsFromFile"]() } returns createNotificationsList(
112+
startupNotification,
113+
emergencyNotification
114+
)
115+
every { dismissalState.isDismissed(any()) } returns false
116+
117+
// First poll - both should be processed
118+
sut.retrieveStartupAndEmergencyNotifications()
119+
120+
verify(exactly = 1) { sut.processNotification(project, startupNotification) }
121+
verify(exactly = 1) { sut.processNotification(project, emergencyNotification) }
122+
123+
// Second poll - only emergency should be processed
124+
sut.retrieveStartupAndEmergencyNotifications()
125+
126+
verify(exactly = 1) { sut.processNotification(project, startupNotification) }
127+
verify(exactly = 2) { sut.processNotification(project, emergencyNotification) }
128+
}
129+
130+
// Helper functions to create test data
131+
private fun createNotification(id: String, type: NotificationScheduleType) = NotificationData(
132+
id = id,
133+
schedule = NotificationSchedule(type = type),
134+
severity = "INFO",
135+
condition = null,
136+
content = NotificationContentDescriptionLocale(
137+
NotificationContentDescription(
138+
title = "Look at this!",
139+
description = "Some bug is there"
140+
)
141+
),
142+
actions = emptyList()
143+
)
144+
145+
private fun createNotificationsList(vararg notifications: NotificationData) = NotificationsList(
146+
schema = Schema("1.0"),
147+
notifications = notifications.toList()
148+
)
149+
150+
private fun resetIsStartup() {
151+
val clazz = Class.forName("software.aws.toolkits.jetbrains.core.notifications.ProcessNotificationsBaseKt")
152+
val field = clazz.getDeclaredField("isStartup")
153+
field.isAccessible = true
154+
155+
val value = field.get(null) as AtomicBoolean
156+
value.set(true)
157+
}
158+
159+
160+
161+
@AfterEach
162+
fun tearDown() {
163+
unmockkAll()
164+
}
165+
}

0 commit comments

Comments
 (0)