From ebdce9b3beddcfaef34e75ab51912d89d95a8881 Mon Sep 17 00:00:00 2001 From: samgst-amazon Date: Mon, 9 Dec 2024 14:48:06 -0800 Subject: [PATCH 01/14] dismiss notification expiry --- .../notifications/NotificationStateUtils.kt | 39 ++++++++++++++----- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt index ce53118e249..5e867621db8 100644 --- a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt +++ b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt @@ -9,35 +9,54 @@ import com.intellij.openapi.components.Service import com.intellij.openapi.components.State import com.intellij.openapi.components.Storage import com.intellij.openapi.components.service +import java.time.Duration +import java.time.Instant + +data class DismissedNotification( + val id: String, + val dismissedAt: Instant = Instant.now() +) + +data class NotificationDismissalConfiguration( + var dismissedNotifications: MutableSet = mutableSetOf() +) @Service @State(name = "notificationDismissals", storages = [Storage("aws.xml", roamingType = RoamingType.DISABLED)]) class NotificationDismissalState : PersistentStateComponent { private val state = NotificationDismissalConfiguration() + private val retentionPeriod = Duration.ofDays(60) // 2 months override fun getState(): NotificationDismissalConfiguration = state override fun loadState(state: NotificationDismissalConfiguration) { - this.state.dismissedNotificationIds.clear() - this.state.dismissedNotificationIds.addAll(state.dismissedNotificationIds) + this.state.dismissedNotifications.clear() + this.state.dismissedNotifications.addAll(state.dismissedNotifications) + cleanExpiredNotifications() } - fun isDismissed(notificationId: String): Boolean = - state.dismissedNotificationIds.contains(notificationId) + fun isDismissed(notificationId: String): Boolean { + cleanExpiredNotifications() + return state.dismissedNotifications.any { it.id == notificationId } + } fun dismissNotification(notificationId: String) { - state.dismissedNotificationIds.add(notificationId) + state.dismissedNotifications.add(DismissedNotification(notificationId)) + cleanExpiredNotifications() + } + + private fun cleanExpiredNotifications() { + val now = Instant.now() + state.dismissedNotifications.removeAll { notification -> + Duration.between(notification.dismissedAt, now) > retentionPeriod + } } companion object { - fun getInstance(): NotificationDismissalState = - service() + fun getInstance(): NotificationDismissalState = service() } } -data class NotificationDismissalConfiguration( - var dismissedNotificationIds: MutableSet = mutableSetOf(), -) @Service @State(name = "notificationEtag", storages = [Storage("aws.xml", roamingType = RoamingType.DISABLED)]) From bcfbb2782653163abf9e64037157fba393923fab Mon Sep 17 00:00:00 2001 From: samgst-amazon Date: Mon, 9 Dec 2024 17:06:43 -0800 Subject: [PATCH 02/14] test --- .../NotificationDismissalStateTest.kt | 125 ++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 plugins/core/jetbrains-community/tst/software/aws/toolkits/jetbrains/core/notifications/NotificationDismissalStateTest.kt diff --git a/plugins/core/jetbrains-community/tst/software/aws/toolkits/jetbrains/core/notifications/NotificationDismissalStateTest.kt b/plugins/core/jetbrains-community/tst/software/aws/toolkits/jetbrains/core/notifications/NotificationDismissalStateTest.kt new file mode 100644 index 00000000000..3fff5db1555 --- /dev/null +++ b/plugins/core/jetbrains-community/tst/software/aws/toolkits/jetbrains/core/notifications/NotificationDismissalStateTest.kt @@ -0,0 +1,125 @@ +// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.core.notifications + +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import java.time.Instant +import java.time.temporal.ChronoUnit + +class NotificationDismissalStateTest { + private lateinit var state: NotificationDismissalState + + @BeforeEach + fun setUp() { + state = NotificationDismissalState() + } + + @Test + fun `notifications less than 2 months old are not removed`() { + // Given + val recentNotification = DismissedNotification( + id = "recent-notification", + dismissedAt = Instant.now().minus(30, ChronoUnit.DAYS) + ) + + state.loadState(NotificationDismissalConfiguration(mutableSetOf(recentNotification))) + + // When + val persistedState = state.getState() + + // Then + assertEquals(1, persistedState.dismissedNotifications.size) + assertTrue(persistedState.dismissedNotifications.any { it.id == "recent-notification" }) + assertTrue(state.isDismissed("recent-notification")) + } + + @Test + fun `notifications older than 2 months are removed`() { + // Given + val oldNotification = DismissedNotification( + id = "old-notification", + dismissedAt = Instant.now().minus(61, ChronoUnit.DAYS) + ) + + state.loadState(NotificationDismissalConfiguration(mutableSetOf(oldNotification))) + + // When/Then + assertFalse(state.isDismissed("old-notification")) + } + + @Test + fun `mixed age notifications are handled correctly`() { + // Given + val recentNotification = DismissedNotification( + id = "recent-notification", + dismissedAt = Instant.now().minus(30, ChronoUnit.DAYS) + ) + val oldNotification = DismissedNotification( + id = "old-notification", + dismissedAt = Instant.now().minus(61, ChronoUnit.DAYS) + ) + + state.loadState( + NotificationDismissalConfiguration( + mutableSetOf(recentNotification, oldNotification) + ) + ) + + // When/Then + assertTrue(state.isDismissed("recent-notification")) + assertFalse(state.isDismissed("old-notification")) + } + + @Test + fun `dismissing new notification retains it`() { + // When + state.dismissNotification("new-notification") + + // Then + assertTrue(state.isDismissed("new-notification")) + } + + @Test + fun `state is correctly persisted`() { + // Given + val notification = DismissedNotification( + id = "test-notification", + dismissedAt = Instant.now() + ) + + // When + state.loadState(NotificationDismissalConfiguration(mutableSetOf(notification))) + val persistedState = state.getState() + + // Then + assertTrue(persistedState.dismissedNotifications.any { it.id == "test-notification" }) + } + + @Test + fun `clean up happens on load state`() { + // Given + val oldNotification = DismissedNotification( + id = "old-notification", + dismissedAt = Instant.now().minus(61, ChronoUnit.DAYS) + ) + val recentNotification = DismissedNotification( + id = "recent-notification", + dismissedAt = Instant.now() + ) + + // When + state.loadState( + NotificationDismissalConfiguration( + mutableSetOf(oldNotification, recentNotification) + ) + ) + + // Then + val persistedState = state.getState() + assertEquals(1, persistedState.dismissedNotifications.size) + assertTrue(persistedState.dismissedNotifications.any { it.id == "recent-notification" }) + } +} From 4367447a961a61bc17fcdfa4f68b56db55acce7f Mon Sep 17 00:00:00 2001 From: samgst-amazon Date: Tue, 10 Dec 2024 11:32:42 -0800 Subject: [PATCH 03/14] fix tests --- .../NotificationDismissalStateTest.kt | 36 ++++--------------- 1 file changed, 7 insertions(+), 29 deletions(-) diff --git a/plugins/core/jetbrains-community/tst/software/aws/toolkits/jetbrains/core/notifications/NotificationDismissalStateTest.kt b/plugins/core/jetbrains-community/tst/software/aws/toolkits/jetbrains/core/notifications/NotificationDismissalStateTest.kt index 3fff5db1555..a342f84a004 100644 --- a/plugins/core/jetbrains-community/tst/software/aws/toolkits/jetbrains/core/notifications/NotificationDismissalStateTest.kt +++ b/plugins/core/jetbrains-community/tst/software/aws/toolkits/jetbrains/core/notifications/NotificationDismissalStateTest.kt @@ -19,7 +19,6 @@ class NotificationDismissalStateTest { @Test fun `notifications less than 2 months old are not removed`() { - // Given val recentNotification = DismissedNotification( id = "recent-notification", dismissedAt = Instant.now().minus(30, ChronoUnit.DAYS) @@ -27,18 +26,15 @@ class NotificationDismissalStateTest { state.loadState(NotificationDismissalConfiguration(mutableSetOf(recentNotification))) - // When val persistedState = state.getState() - // Then assertEquals(1, persistedState.dismissedNotifications.size) assertTrue(persistedState.dismissedNotifications.any { it.id == "recent-notification" }) assertTrue(state.isDismissed("recent-notification")) } @Test - fun `notifications older than 2 months are removed`() { - // Given +fun `notifications older than 2 months are removed`() { val oldNotification = DismissedNotification( id = "old-notification", dismissedAt = Instant.now().minus(61, ChronoUnit.DAYS) @@ -46,13 +42,14 @@ class NotificationDismissalStateTest { state.loadState(NotificationDismissalConfiguration(mutableSetOf(oldNotification))) - // When/Then + val persistedState = state.getState() + + assertEquals(0, persistedState.dismissedNotifications.size) assertFalse(state.isDismissed("old-notification")) } @Test fun `mixed age notifications are handled correctly`() { - // Given val recentNotification = DismissedNotification( id = "recent-notification", dismissedAt = Instant.now().minus(30, ChronoUnit.DAYS) @@ -68,39 +65,22 @@ class NotificationDismissalStateTest { ) ) - // When/Then + val persistedState = state.getState() + + assertEquals(1, persistedState.dismissedNotifications.size) assertTrue(state.isDismissed("recent-notification")) assertFalse(state.isDismissed("old-notification")) } @Test fun `dismissing new notification retains it`() { - // When state.dismissNotification("new-notification") - // Then assertTrue(state.isDismissed("new-notification")) } - @Test - fun `state is correctly persisted`() { - // Given - val notification = DismissedNotification( - id = "test-notification", - dismissedAt = Instant.now() - ) - - // When - state.loadState(NotificationDismissalConfiguration(mutableSetOf(notification))) - val persistedState = state.getState() - - // Then - assertTrue(persistedState.dismissedNotifications.any { it.id == "test-notification" }) - } - @Test fun `clean up happens on load state`() { - // Given val oldNotification = DismissedNotification( id = "old-notification", dismissedAt = Instant.now().minus(61, ChronoUnit.DAYS) @@ -110,14 +90,12 @@ class NotificationDismissalStateTest { dismissedAt = Instant.now() ) - // When state.loadState( NotificationDismissalConfiguration( mutableSetOf(oldNotification, recentNotification) ) ) - // Then val persistedState = state.getState() assertEquals(1, persistedState.dismissedNotifications.size) assertTrue(persistedState.dismissedNotifications.any { it.id == "recent-notification" }) From 824314d80f21641cd7f2260327da0a0b2073c78b Mon Sep 17 00:00:00 2001 From: samgst-amazon Date: Tue, 10 Dec 2024 16:24:53 -0800 Subject: [PATCH 04/14] redundant cleanExpired function calls --- .../jetbrains/core/notifications/NotificationStateUtils.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt index 5e867621db8..32b8eb62d6f 100644 --- a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt +++ b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt @@ -36,13 +36,11 @@ class NotificationDismissalState : PersistentStateComponent Date: Tue, 10 Dec 2024 16:50:20 -0800 Subject: [PATCH 05/14] converter --- .../notifications/NotificationStateUtils.kt | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt index 32b8eb62d6f..8879b5362f8 100644 --- a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt +++ b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt @@ -9,15 +9,27 @@ import com.intellij.openapi.components.Service import com.intellij.openapi.components.State import com.intellij.openapi.components.Storage import com.intellij.openapi.components.service +import com.intellij.util.xmlb.Converter +import com.intellij.util.xmlb.annotations.Attribute +import com.intellij.util.xmlb.annotations.Property import java.time.Duration import java.time.Instant +class InstantConverter : Converter() { + override fun toString(value: Instant): String = value.toEpochMilli().toString() + + override fun fromString(value: String): Instant = Instant.ofEpochMilli(value.toLong()) +} + + data class DismissedNotification( - val id: String, + val id: String = "", + @Attribute(converter = InstantConverter::class) val dismissedAt: Instant = Instant.now() ) data class NotificationDismissalConfiguration( + @Property var dismissedNotifications: MutableSet = mutableSetOf() ) @@ -40,7 +52,11 @@ class NotificationDismissalState : PersistentStateComponent Date: Tue, 10 Dec 2024 17:10:33 -0800 Subject: [PATCH 06/14] detekt --- .../core/notifications/NotificationStateUtils.kt | 12 +++++------- .../notifications/NotificationDismissalStateTest.kt | 6 ++++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt index 8879b5362f8..7b10bf14077 100644 --- a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt +++ b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt @@ -21,16 +21,16 @@ class InstantConverter : Converter() { override fun fromString(value: String): Instant = Instant.ofEpochMilli(value.toLong()) } - data class DismissedNotification( + @Attribute val id: String = "", @Attribute(converter = InstantConverter::class) - val dismissedAt: Instant = Instant.now() + val dismissedAt: Instant = Instant.now(), ) data class NotificationDismissalConfiguration( @Property - var dismissedNotifications: MutableSet = mutableSetOf() + var dismissedNotifications: MutableSet = mutableSetOf(), ) @Service @@ -47,9 +47,8 @@ class NotificationDismissalState : PersistentStateComponent { diff --git a/plugins/core/jetbrains-community/tst/software/aws/toolkits/jetbrains/core/notifications/NotificationDismissalStateTest.kt b/plugins/core/jetbrains-community/tst/software/aws/toolkits/jetbrains/core/notifications/NotificationDismissalStateTest.kt index a342f84a004..b173bb68e62 100644 --- a/plugins/core/jetbrains-community/tst/software/aws/toolkits/jetbrains/core/notifications/NotificationDismissalStateTest.kt +++ b/plugins/core/jetbrains-community/tst/software/aws/toolkits/jetbrains/core/notifications/NotificationDismissalStateTest.kt @@ -3,7 +3,9 @@ package software.aws.toolkits.jetbrains.core.notifications -import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import java.time.Instant @@ -34,7 +36,7 @@ class NotificationDismissalStateTest { } @Test -fun `notifications older than 2 months are removed`() { + fun `notifications older than 2 months are removed`() { val oldNotification = DismissedNotification( id = "old-notification", dismissedAt = Instant.now().minus(61, ChronoUnit.DAYS) From ef6ec8598f0a702cafbe1950e316c88ee70a2e96 Mon Sep 17 00:00:00 2001 From: samgst-amazon Date: Wed, 11 Dec 2024 15:21:24 -0800 Subject: [PATCH 07/14] remove whitespace from conflict --- .../jetbrains/core/notifications/NotificationStateUtils.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt index 48a5816f9ff..06695565fdc 100644 --- a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt +++ b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt @@ -34,8 +34,6 @@ data class NotificationDismissalConfiguration( var dismissedNotifications: MutableSet = mutableSetOf(), ) - - @Service @State(name = "notificationDismissals", storages = [Storage("aws.xml", roamingType = RoamingType.DISABLED)]) class NotificationDismissalState : PersistentStateComponent { From ba2638fabf391a2f4c0c35ab8468ee085e2e0bd2 Mon Sep 17 00:00:00 2001 From: samgst-amazon Date: Wed, 11 Dec 2024 16:10:20 -0800 Subject: [PATCH 08/14] detekt --- .../jetbrains/core/notifications/NotificationStateUtils.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt index 06695565fdc..20f5f8b032a 100644 --- a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt +++ b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt @@ -12,9 +12,9 @@ import com.intellij.openapi.components.service import com.intellij.util.xmlb.Converter import com.intellij.util.xmlb.annotations.Attribute import com.intellij.util.xmlb.annotations.Property +import software.aws.toolkits.core.utils.ETagProvider import java.time.Duration import java.time.Instant -import software.aws.toolkits.core.utils.ETagProvider class InstantConverter : Converter() { override fun toString(value: Instant): String = value.toEpochMilli().toString() From 2a96250a9c6cd3e3ccfbe3d594703415ce688f32 Mon Sep 17 00:00:00 2001 From: samgst-amazon Date: Mon, 6 Jan 2025 13:21:45 -0800 Subject: [PATCH 09/14] remove attribute tags, unnecessary clear --- .../core/notifications/NotificationStateUtils.kt | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt index 20f5f8b032a..278d8967862 100644 --- a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt +++ b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt @@ -10,8 +10,6 @@ import com.intellij.openapi.components.State import com.intellij.openapi.components.Storage import com.intellij.openapi.components.service import com.intellij.util.xmlb.Converter -import com.intellij.util.xmlb.annotations.Attribute -import com.intellij.util.xmlb.annotations.Property import software.aws.toolkits.core.utils.ETagProvider import java.time.Duration import java.time.Instant @@ -23,15 +21,12 @@ class InstantConverter : Converter() { } data class DismissedNotification( - @Attribute val id: String = "", - @Attribute(converter = InstantConverter::class) val dismissedAt: Instant = Instant.now(), ) data class NotificationDismissalConfiguration( - @Property - var dismissedNotifications: MutableSet = mutableSetOf(), + val dismissedNotifications: MutableSet = mutableSetOf(), ) @Service @@ -43,7 +38,6 @@ class NotificationDismissalState : PersistentStateComponent Date: Mon, 6 Jan 2025 14:01:18 -0800 Subject: [PATCH 10/14] replace attribute tags --- .../jetbrains/core/notifications/NotificationStateUtils.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt index 278d8967862..9c9734569fd 100644 --- a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt +++ b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt @@ -10,6 +10,8 @@ import com.intellij.openapi.components.State import com.intellij.openapi.components.Storage import com.intellij.openapi.components.service import com.intellij.util.xmlb.Converter +import com.intellij.util.xmlb.annotations.Attribute +import com.intellij.util.xmlb.annotations.Property import software.aws.toolkits.core.utils.ETagProvider import java.time.Duration import java.time.Instant @@ -21,11 +23,14 @@ class InstantConverter : Converter() { } data class DismissedNotification( + @Attribute val id: String = "", + @Attribute(converter = InstantConverter::class) val dismissedAt: Instant = Instant.now(), ) data class NotificationDismissalConfiguration( + @Property val dismissedNotifications: MutableSet = mutableSetOf(), ) From 960f5f1ab95366a14e4cd88fdccf7b64937a09ab Mon Sep 17 00:00:00 2001 From: samgst-amazon Date: Tue, 7 Jan 2025 11:27:17 -0800 Subject: [PATCH 11/14] change properties to var for serialization --- .../notifications/NotificationStateUtils.kt | 30 +++++++------------ .../NotificationDismissalStateTest.kt | 12 ++++---- 2 files changed, 16 insertions(+), 26 deletions(-) diff --git a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt index 9c9734569fd..02f29cdc3fe 100644 --- a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt +++ b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt @@ -9,41 +9,31 @@ import com.intellij.openapi.components.Service import com.intellij.openapi.components.State import com.intellij.openapi.components.Storage import com.intellij.openapi.components.service -import com.intellij.util.xmlb.Converter -import com.intellij.util.xmlb.annotations.Attribute -import com.intellij.util.xmlb.annotations.Property import software.aws.toolkits.core.utils.ETagProvider import java.time.Duration import java.time.Instant -class InstantConverter : Converter() { - override fun toString(value: Instant): String = value.toEpochMilli().toString() - - override fun fromString(value: String): Instant = Instant.ofEpochMilli(value.toLong()) -} - data class DismissedNotification( - @Attribute - val id: String = "", - @Attribute(converter = InstantConverter::class) - val dismissedAt: Instant = Instant.now(), + var id: String = "", + var dismissedAt: String = Instant.now().toEpochMilli().toString() ) data class NotificationDismissalConfiguration( - @Property - val dismissedNotifications: MutableSet = mutableSetOf(), + var dismissedNotifications: MutableSet = mutableSetOf(), ) @Service -@State(name = "notificationDismissals", storages = [Storage("aws.xml", roamingType = RoamingType.DISABLED)]) +@State(name = "notificationDismissals", storages = [Storage("aws.xml")]) class NotificationDismissalState : PersistentStateComponent { - private val state = NotificationDismissalConfiguration() + private var state = NotificationDismissalConfiguration() private val retentionPeriod = Duration.ofDays(60) // 2 months - override fun getState(): NotificationDismissalConfiguration = state + override fun getState(): NotificationDismissalConfiguration { + return state + } override fun loadState(state: NotificationDismissalConfiguration) { - this.state.dismissedNotifications.addAll(state.dismissedNotifications) + this.state = state cleanExpiredNotifications() } @@ -61,7 +51,7 @@ class NotificationDismissalState : PersistentStateComponent - Duration.between(notification.dismissedAt, now) > retentionPeriod + Duration.between(Instant.ofEpochMilli(notification.dismissedAt.toLong()), now) > retentionPeriod } } diff --git a/plugins/core/jetbrains-community/tst/software/aws/toolkits/jetbrains/core/notifications/NotificationDismissalStateTest.kt b/plugins/core/jetbrains-community/tst/software/aws/toolkits/jetbrains/core/notifications/NotificationDismissalStateTest.kt index b173bb68e62..f105f86cf31 100644 --- a/plugins/core/jetbrains-community/tst/software/aws/toolkits/jetbrains/core/notifications/NotificationDismissalStateTest.kt +++ b/plugins/core/jetbrains-community/tst/software/aws/toolkits/jetbrains/core/notifications/NotificationDismissalStateTest.kt @@ -23,7 +23,7 @@ class NotificationDismissalStateTest { fun `notifications less than 2 months old are not removed`() { val recentNotification = DismissedNotification( id = "recent-notification", - dismissedAt = Instant.now().minus(30, ChronoUnit.DAYS) + dismissedAt = Instant.now().minus(30, ChronoUnit.DAYS).toEpochMilli().toString() ) state.loadState(NotificationDismissalConfiguration(mutableSetOf(recentNotification))) @@ -39,7 +39,7 @@ class NotificationDismissalStateTest { fun `notifications older than 2 months are removed`() { val oldNotification = DismissedNotification( id = "old-notification", - dismissedAt = Instant.now().minus(61, ChronoUnit.DAYS) + dismissedAt = Instant.now().minus(61, ChronoUnit.DAYS).toEpochMilli().toString() ) state.loadState(NotificationDismissalConfiguration(mutableSetOf(oldNotification))) @@ -54,11 +54,11 @@ class NotificationDismissalStateTest { fun `mixed age notifications are handled correctly`() { val recentNotification = DismissedNotification( id = "recent-notification", - dismissedAt = Instant.now().minus(30, ChronoUnit.DAYS) + dismissedAt = Instant.now().minus(30, ChronoUnit.DAYS).toEpochMilli().toString() ) val oldNotification = DismissedNotification( id = "old-notification", - dismissedAt = Instant.now().minus(61, ChronoUnit.DAYS) + dismissedAt = Instant.now().minus(61, ChronoUnit.DAYS).toEpochMilli().toString() ) state.loadState( @@ -85,11 +85,11 @@ class NotificationDismissalStateTest { fun `clean up happens on load state`() { val oldNotification = DismissedNotification( id = "old-notification", - dismissedAt = Instant.now().minus(61, ChronoUnit.DAYS) + dismissedAt = Instant.now().minus(61, ChronoUnit.DAYS).toEpochMilli().toString() ) val recentNotification = DismissedNotification( id = "recent-notification", - dismissedAt = Instant.now() + dismissedAt = Instant.now().toEpochMilli().toString() ) state.loadState( From 2475c07619564c74c24b9f470e3a41b76f6308bc Mon Sep 17 00:00:00 2001 From: samgst-amazon Date: Tue, 7 Jan 2025 11:30:27 -0800 Subject: [PATCH 12/14] simplify getState --- .../jetbrains/core/notifications/NotificationStateUtils.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt index 02f29cdc3fe..e9d82030894 100644 --- a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt +++ b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt @@ -28,9 +28,7 @@ class NotificationDismissalState : PersistentStateComponent Date: Tue, 7 Jan 2025 11:33:19 -0800 Subject: [PATCH 13/14] detekt --- .../jetbrains/core/notifications/NotificationStateUtils.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt index e9d82030894..58d01e82bcc 100644 --- a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt +++ b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/notifications/NotificationStateUtils.kt @@ -15,7 +15,7 @@ import java.time.Instant data class DismissedNotification( var id: String = "", - var dismissedAt: String = Instant.now().toEpochMilli().toString() + var dismissedAt: String = Instant.now().toEpochMilli().toString(), ) data class NotificationDismissalConfiguration( From cb7d9f9bae80d7ad24416206c10231b5acce7822 Mon Sep 17 00:00:00 2001 From: samgst-amazon Date: Wed, 8 Jan 2025 11:58:15 -0800 Subject: [PATCH 14/14] reduntant test --- .../NotificationDismissalStateTest.kt | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/plugins/core/jetbrains-community/tst/software/aws/toolkits/jetbrains/core/notifications/NotificationDismissalStateTest.kt b/plugins/core/jetbrains-community/tst/software/aws/toolkits/jetbrains/core/notifications/NotificationDismissalStateTest.kt index f105f86cf31..eca7e1e6cac 100644 --- a/plugins/core/jetbrains-community/tst/software/aws/toolkits/jetbrains/core/notifications/NotificationDismissalStateTest.kt +++ b/plugins/core/jetbrains-community/tst/software/aws/toolkits/jetbrains/core/notifications/NotificationDismissalStateTest.kt @@ -80,26 +80,4 @@ class NotificationDismissalStateTest { assertTrue(state.isDismissed("new-notification")) } - - @Test - fun `clean up happens on load state`() { - val oldNotification = DismissedNotification( - id = "old-notification", - dismissedAt = Instant.now().minus(61, ChronoUnit.DAYS).toEpochMilli().toString() - ) - val recentNotification = DismissedNotification( - id = "recent-notification", - dismissedAt = Instant.now().toEpochMilli().toString() - ) - - state.loadState( - NotificationDismissalConfiguration( - mutableSetOf(oldNotification, recentNotification) - ) - ) - - val persistedState = state.getState() - assertEquals(1, persistedState.dismissedNotifications.size) - assertTrue(persistedState.dismissedNotifications.any { it.id == "recent-notification" }) - } }