44package software.aws.toolkits.jetbrains.services.amazonq.workspace.context
55
66import com.github.tomakehurst.wiremock.client.WireMock.aResponse
7+ import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
78import com.github.tomakehurst.wiremock.client.WireMock.any
9+ import com.github.tomakehurst.wiremock.client.WireMock.equalTo
10+ import com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor
811import com.github.tomakehurst.wiremock.client.WireMock.stubFor
912import com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo
1013import com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig
@@ -25,10 +28,13 @@ import org.mockito.kotlin.times
2528import org.mockito.kotlin.verify
2629import org.mockito.kotlin.whenever
2730import software.aws.toolkits.jetbrains.services.amazonq.project.EncoderServer
31+ import software.aws.toolkits.jetbrains.services.amazonq.project.IndexRequest
2832import software.aws.toolkits.jetbrains.services.amazonq.project.InlineBm25Chunk
2933import software.aws.toolkits.jetbrains.services.amazonq.project.LspMessage
3034import software.aws.toolkits.jetbrains.services.amazonq.project.ProjectContextProvider
35+ import software.aws.toolkits.jetbrains.services.amazonq.project.QueryChatRequest
3136import software.aws.toolkits.jetbrains.services.amazonq.project.RelevantDocument
37+ import software.aws.toolkits.jetbrains.services.amazonq.project.UpdateIndexRequest
3238import software.aws.toolkits.jetbrains.utils.rules.CodeInsightTestFixtureRule
3339import software.aws.toolkits.jetbrains.utils.rules.JavaCodeInsightTestFixtureRule
3440import java.net.ConnectException
@@ -50,6 +56,8 @@ class ProjectContextProviderTest {
5056 private lateinit var encoderServer: EncoderServer
5157 private lateinit var sut: ProjectContextProvider
5258
59+ private val mapper = jacksonObjectMapper()
60+
5361 @Before
5462 fun setup () {
5563 encoderServer = spy(EncoderServer (project))
@@ -107,7 +115,86 @@ class ProjectContextProviderTest {
107115 }
108116
109117 @Test
110- fun `query chat should return empty if resultset non deserializable` () = runTest {
118+ fun `index should send files within the project to lsp` () {
119+ projectRule.fixture.addFileToProject(" Foo.java" , " foo" )
120+ projectRule.fixture.addFileToProject(" Bar.java" , " bar" )
121+ projectRule.fixture.addFileToProject(" Baz.java" , " baz" )
122+
123+ sut.index()
124+
125+ val request = IndexRequest (listOf (" /src/Foo.java" , " /src/Bar.java" , " /src/Baz.java" ), " /src" , " all" , " " )
126+ assertThat(request.filePaths).hasSize(3 )
127+ assertThat(request.filePaths).satisfies({
128+ it.contains(" /src/Foo.java" ) &&
129+ it.contains(" /src/Baz.java" ) &&
130+ it.contains(" /src/Bar.java" )
131+ })
132+ assertThat(request.config).isEqualTo(" all" )
133+
134+ wireMock.verify(
135+ 1 ,
136+ postRequestedFor(urlPathEqualTo(" /buildIndex" ))
137+ .withHeader(" Content-Type" , equalTo(" text/plain" ))
138+ // comment it out because order matters and will cause json string different
139+ // .withRequestBody(equalTo(encryptedRequest))
140+ )
141+ }
142+
143+ @Test
144+ fun `updateIndex will not send message to lsp if index is not complete` () {
145+ sut.isIndexComplete.set(false )
146+
147+ sut.updateIndex(listOf (" foo.java" ), ProjectContextProvider .IndexUpdateMode .UPDATE )
148+
149+ assertThat(wireMock.allServeEvents).isEmpty()
150+ wireMock.verify(
151+ 0 ,
152+ postRequestedFor(urlPathEqualTo(" /updateIndexV2" ))
153+ .withHeader(" Content-Type" , equalTo(" text/plain" ))
154+ )
155+ }
156+
157+ @Test
158+ fun `updateIndex should send correct encrypted request to lsp` () {
159+ sut.isIndexComplete.set(true )
160+
161+ sut.updateIndex(listOf (" foo.java" ), ProjectContextProvider .IndexUpdateMode .UPDATE )
162+ val request = UpdateIndexRequest (listOf (" foo.java" ), ProjectContextProvider .IndexUpdateMode .UPDATE .value)
163+ val requestJson = mapper.writeValueAsString(request)
164+
165+ assertThat(mapper.readTree(requestJson)).isEqualTo(mapper.readTree(""" { "filePaths": ["foo.java"], "mode": "update" }""" ))
166+
167+ val encryptedRequest = encoderServer.encrypt(requestJson)
168+
169+ wireMock.verify(
170+ 1 ,
171+ postRequestedFor(urlPathEqualTo(" /updateIndexV2" ))
172+ .withHeader(" Content-Type" , equalTo(" text/plain" ))
173+ .withRequestBody(equalTo(encryptedRequest))
174+ )
175+ }
176+
177+ @Test
178+ fun `query should send correct encrypted request to lsp` () {
179+ sut.query(" foo" )
180+
181+ val request = QueryChatRequest (" foo" )
182+ val requestJson = mapper.writeValueAsString(request)
183+
184+ assertThat(mapper.readTree(requestJson)).isEqualTo(mapper.readTree(""" { "query": "foo" }""" ))
185+
186+ val encryptedRequest = encoderServer.encrypt(requestJson)
187+
188+ wireMock.verify(
189+ 1 ,
190+ postRequestedFor(urlPathEqualTo(" /query" ))
191+ .withHeader(" Content-Type" , equalTo(" text/plain" ))
192+ .withRequestBody(equalTo(encryptedRequest))
193+ )
194+ }
195+
196+ @Test
197+ fun `query chat should return empty if result set non deserializable` () = runTest {
111198 stubFor(
112199 any(urlPathEqualTo(" /query" )).willReturn(
113200 aResponse().withStatus(200 ).withResponseBody(
0 commit comments