@@ -7,8 +7,10 @@ import com.intellij.openapi.application.ApplicationManager
77import com.intellij.testFramework.ApplicationRule
88import com.intellij.testFramework.DisposableRule
99import com.intellij.testFramework.ProjectRule
10+ import com.intellij.testFramework.registerServiceInstance
1011import com.intellij.testFramework.replaceService
1112import com.intellij.util.xmlb.XmlSerializer
13+ import migration.software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererModelConfigurator
1214import org.assertj.core.api.Assertions.assertThat
1315import org.jdom.output.XMLOutputter
1416import org.junit.Before
@@ -40,10 +42,14 @@ import software.aws.toolkits.jetbrains.core.credentials.sono.isSono
4042import software.aws.toolkits.jetbrains.core.region.MockRegionProviderRule
4143import software.aws.toolkits.jetbrains.services.amazonq.CodeWhispererFeatureConfigService
4244import software.aws.toolkits.jetbrains.services.amazonq.FeatureContext
45+ import software.aws.toolkits.jetbrains.services.amazonq.profile.QRegionProfileSelectedListener
46+ import software.aws.toolkits.jetbrains.services.codewhisperer.credentials.CodeWhispererClientAdaptor
4347import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererCustomization
4448import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererCustomizationState
4549import software.aws.toolkits.jetbrains.services.codewhisperer.customization.DefaultCodeWhispererModelConfigurator
4650import software.aws.toolkits.jetbrains.utils.xmlElement
51+ import java.util.concurrent.CountDownLatch
52+ import java.util.concurrent.TimeUnit
4753import kotlin.reflect.full.memberProperties
4854import kotlin.reflect.jvm.isAccessible
4955
@@ -75,6 +81,7 @@ class CodeWhispererModelConfiguratorTest {
7581 private lateinit var sut: DefaultCodeWhispererModelConfigurator
7682 private lateinit var mockClient: CodeWhispererRuntimeClient
7783 private lateinit var abManager: CodeWhispererFeatureConfigService
84+ private lateinit var mockClintAdaptor: CodeWhispererClientAdaptor
7885
7986 @Before
8087 fun setup () {
@@ -83,7 +90,13 @@ class CodeWhispererModelConfiguratorTest {
8390 regionProvider.addRegion(Region .US_EAST_1 )
8491 regionProvider.addRegion(Region .US_EAST_2 )
8592
86- sut = DefaultCodeWhispererModelConfigurator ()
93+ val original = CodeWhispererModelConfigurator .getInstance()
94+ sut = spy(original) as DefaultCodeWhispererModelConfigurator
95+ ApplicationManager .getApplication().replaceService(
96+ DefaultCodeWhispererModelConfigurator ::class .java,
97+ sut,
98+ disposableRule.disposable
99+ )
87100
88101 (ToolkitConnectionManager .getInstance(projectRule.project) as DefaultToolkitConnectionManager ).loadState(ToolkitConnectionManagerState ())
89102 mockClient.stub {
@@ -110,6 +123,9 @@ class CodeWhispererModelConfiguratorTest {
110123 abManager,
111124 disposableRule.disposable
112125 )
126+
127+ mockClintAdaptor = mock()
128+ projectRule.project.registerServiceInstance(CodeWhispererClientAdaptor ::class .java, mockClintAdaptor)
113129 }
114130
115131 @Test
@@ -550,4 +566,48 @@ class CodeWhispererModelConfiguratorTest {
550566 assertThat(actual.previousAvailableCustomizations).hasSize(1 )
551567 assertThat(actual.previousAvailableCustomizations[" fake-sso-url" ]).isEqualTo(listOf (" arn_1" , " arn_2" , " arn_3" ))
552568 }
569+
570+ @Test
571+ fun `profile switch should keep using existing customization if new list still contains that arn` () {
572+ val ssoConn = spy(LegacyManagedBearerSsoConnection (region = " us-east-1" , startUrl = " url 1" , scopes = Q_SCOPES ))
573+ ToolkitConnectionManager .getInstance(projectRule.project).switchConnection(ssoConn)
574+ val oldCustomization = CodeWhispererCustomization (" oldArn" , " oldName" , " oldDescription" )
575+ sut.switchCustomization(projectRule.project, oldCustomization)
576+
577+ assertThat(sut.activeCustomization(projectRule.project)).isEqualTo(oldCustomization)
578+
579+ val fakeCustomizations = listOf (
580+ CodeWhispererCustomization (" oldArn" , " oldName" , " oldDescription" )
581+ )
582+ mockClintAdaptor.stub { on { listAvailableCustomizations() } doReturn fakeCustomizations }
583+
584+ ApplicationManager .getApplication().messageBus
585+ .syncPublisher(QRegionProfileSelectedListener .TOPIC )
586+ .onProfileSelected(projectRule.project, null )
587+
588+ assertThat(sut.activeCustomization(projectRule.project)).isEqualTo(oldCustomization)
589+ }
590+
591+ @Test
592+ fun `profile switch should invalidate obsolete customization if it's not in the new list` () {
593+ val ssoConn = spy(LegacyManagedBearerSsoConnection (region = " us-east-1" , startUrl = " url 1" , scopes = Q_SCOPES ))
594+ ToolkitConnectionManager .getInstance(projectRule.project).switchConnection(ssoConn)
595+ val oldCustomization = CodeWhispererCustomization (" oldArn" , " oldName" , " oldDescription" )
596+ sut.switchCustomization(projectRule.project, oldCustomization)
597+ assertThat(sut.activeCustomization(projectRule.project)).isEqualTo(oldCustomization)
598+ val fakeCustomizations = listOf (
599+ CodeWhispererCustomization (" newArn" , " newName" , " newDescription" )
600+ )
601+ mockClintAdaptor.stub { on { listAvailableCustomizations() } doReturn fakeCustomizations }
602+
603+ val latch = CountDownLatch (1 )
604+
605+ ApplicationManager .getApplication().messageBus
606+ .syncPublisher(QRegionProfileSelectedListener .TOPIC )
607+ .onProfileSelected(projectRule.project, null )
608+
609+ latch.await(2 , TimeUnit .SECONDS )
610+
611+ assertThat(sut.activeCustomization(projectRule.project)).isNull()
612+ }
553613}
0 commit comments