Skip to content

Commit 122db33

Browse files
committed
chore: simplify uri handling implementation (5)
Removed unused code and refactored unit tests to take into account that some of the methods are no longer static, and that return type changed.
1 parent 32b3911 commit 122db33

File tree

3 files changed

+66
-140
lines changed

3 files changed

+66
-140
lines changed

src/main/kotlin/com/coder/toolbox/util/CoderProtocolHandler.kt

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,14 @@ import com.coder.toolbox.sdk.CoderRestClient
99
import com.coder.toolbox.sdk.v2.models.Workspace
1010
import com.coder.toolbox.sdk.v2.models.WorkspaceAgent
1111
import com.coder.toolbox.sdk.v2.models.WorkspaceStatus
12-
import com.jetbrains.toolbox.api.localization.LocalizableString
1312
import com.jetbrains.toolbox.api.remoteDev.connection.RemoteToolsHelper
1413
import kotlinx.coroutines.Job
1514
import kotlinx.coroutines.TimeoutCancellationException
1615
import kotlinx.coroutines.delay
1716
import kotlinx.coroutines.flow.StateFlow
1817
import kotlinx.coroutines.launch
1918
import kotlinx.coroutines.time.withTimeout
20-
import java.net.HttpURLConnection
2119
import java.net.URI
22-
import java.net.URL
2320
import java.util.UUID
2421
import kotlin.time.Duration
2522
import kotlin.time.Duration.Companion.minutes
@@ -227,7 +224,7 @@ open class CoderProtocolHandler(
227224
*
228225
* @throws [IllegalArgumentException]
229226
*/
230-
private suspend fun getMatchingAgent(
227+
internal suspend fun getMatchingAgent(
231228
parameters: Map<String, String?>,
232229
workspace: Workspace,
233230
): WorkspaceAgent? {
@@ -238,7 +235,6 @@ open class CoderProtocolHandler(
238235
}
239236

240237
// If the agent is missing and the workspace has only one, use that.
241-
// Prefer the ID over the name if both are set.
242238
val agent =
243239
if (!parameters.agentID().isNullOrBlank()) {
244240
agents.firstOrNull { it.id.toString() == parameters.agentID() }
@@ -430,44 +426,6 @@ open class CoderProtocolHandler(
430426
}
431427
}
432428

433-
/**
434-
* Follow a URL's redirects to its final destination.
435-
*/
436-
internal fun resolveRedirects(url: URL): URL {
437-
var location = url
438-
val maxRedirects = 10
439-
for (i in 1..maxRedirects) {
440-
val conn = location.openConnection() as HttpURLConnection
441-
conn.instanceFollowRedirects = false
442-
conn.connect()
443-
val code = conn.responseCode
444-
val nextLocation = conn.getHeaderField("Location")
445-
conn.disconnect()
446-
// Redirects are triggered by any code starting with 3 plus a
447-
// location header.
448-
if (code < 300 || code >= 400 || nextLocation.isNullOrBlank()) {
449-
return location
450-
}
451-
// Location headers might be relative.
452-
location = URL(location, nextLocation)
453-
}
454-
throw Exception("Too many redirects")
455-
}
456-
457-
private suspend fun CoderToolboxContext.showErrorPopup(error: Throwable) {
458-
popupPluginMainPage()
459-
this.ui.showErrorInfoPopup(error)
460-
}
461-
462-
private suspend fun CoderToolboxContext.showInfoPopup(
463-
title: LocalizableString,
464-
message: LocalizableString,
465-
okLabel: LocalizableString
466-
) {
467-
popupPluginMainPage()
468-
this.ui.showInfoPopup(title, message, okLabel)
469-
}
470-
471429
private fun CoderToolboxContext.popupPluginMainPage() {
472430
this.ui.showWindow()
473431
this.envPageManager.showPluginEnvironmentsPage(true)

src/main/kotlin/com/coder/toolbox/util/LinkMap.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package com.coder.toolbox.util
33
const val URL = "url"
44
const val TOKEN = "token"
55
const val WORKSPACE = "workspace"
6-
const val AGENT_NAME = "agent"
76
const val AGENT_ID = "agent_id"
87
private const val IDE_PRODUCT_CODE = "ide_product_code"
98
private const val IDE_BUILD_NUMBER = "ide_build_number"
Lines changed: 65 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,49 @@
11
package com.coder.toolbox.util
22

3+
import com.coder.toolbox.CoderToolboxContext
34
import com.coder.toolbox.sdk.DataGen
4-
import com.sun.net.httpserver.HttpHandler
5-
import com.sun.net.httpserver.HttpServer
6-
import java.net.HttpURLConnection
7-
import java.net.InetSocketAddress
5+
import com.coder.toolbox.settings.Environment
6+
import com.coder.toolbox.store.CoderSecretsStore
7+
import com.coder.toolbox.store.CoderSettingsStore
8+
import com.jetbrains.toolbox.api.core.diagnostics.Logger
9+
import com.jetbrains.toolbox.api.core.os.LocalDesktopManager
10+
import com.jetbrains.toolbox.api.localization.LocalizableStringFactory
11+
import com.jetbrains.toolbox.api.remoteDev.connection.ClientHelper
12+
import com.jetbrains.toolbox.api.remoteDev.connection.RemoteToolsHelper
13+
import com.jetbrains.toolbox.api.remoteDev.connection.ToolboxProxySettings
14+
import com.jetbrains.toolbox.api.remoteDev.states.EnvironmentStateColorPalette
15+
import com.jetbrains.toolbox.api.remoteDev.ui.EnvironmentUiPageManager
16+
import com.jetbrains.toolbox.api.ui.ToolboxUi
17+
import io.mockk.mockk
18+
import kotlinx.coroutines.CoroutineScope
19+
import kotlinx.coroutines.flow.MutableStateFlow
20+
import kotlinx.coroutines.runBlocking
821
import java.util.UUID
922
import kotlin.test.Test
10-
import kotlin.test.assertContains
1123
import kotlin.test.assertEquals
12-
import kotlin.test.assertFailsWith
24+
import kotlin.test.assertNull
1325

1426
internal class LinkHandlerTest {
15-
/**
16-
* Create, start, and return a server that uses the provided handler.
17-
*/
18-
private fun mockServer(handler: HttpHandler): Pair<HttpServer, String> {
19-
val srv = HttpServer.create(InetSocketAddress(0), 0)
20-
srv.createContext("/", handler)
21-
srv.start()
22-
return Pair(srv, "http://localhost:" + srv.address.port)
23-
}
24-
25-
/**
26-
* Create, start, and return a server that mocks redirects.
27-
*/
28-
private fun mockRedirectServer(
29-
location: String,
30-
temp: Boolean,
31-
): Pair<HttpServer, String> = mockServer { exchange ->
32-
exchange.responseHeaders.set("Location", location)
33-
exchange.sendResponseHeaders(
34-
if (temp) HttpURLConnection.HTTP_MOVED_TEMP else HttpURLConnection.HTTP_MOVED_PERM,
35-
-1,
36-
)
37-
exchange.close()
38-
}
27+
private val context = CoderToolboxContext(
28+
mockk<ToolboxUi>(relaxed = true),
29+
mockk<EnvironmentUiPageManager>(),
30+
mockk<EnvironmentStateColorPalette>(),
31+
mockk<RemoteToolsHelper>(),
32+
mockk<ClientHelper>(),
33+
mockk<LocalDesktopManager>(),
34+
mockk<CoroutineScope>(),
35+
mockk<Logger>(relaxed = true),
36+
mockk<LocalizableStringFactory>(relaxed = true),
37+
CoderSettingsStore(pluginTestSettingsStore(), Environment(), mockk<Logger>(relaxed = true)),
38+
mockk<CoderSecretsStore>(),
39+
mockk<ToolboxProxySettings>()
40+
)
41+
42+
private val protocolHandler = CoderProtocolHandler(
43+
context,
44+
DialogUi(context),
45+
MutableStateFlow(false)
46+
)
3947

4048
private val agents =
4149
mapOf(
@@ -49,7 +57,7 @@ internal class LinkHandlerTest {
4957
)
5058

5159
@Test
52-
fun getMatchingAgent() {
60+
fun tstgetMatchingAgent() {
5361
val ws = DataGen.workspace("ws", agents = agents)
5462

5563
val tests =
@@ -74,9 +82,10 @@ internal class LinkHandlerTest {
7482
"b0e4c54d-9ba9-4413-8512-11ca1e826a24",
7583
),
7684
)
77-
78-
tests.forEach {
79-
assertEquals(UUID.fromString(it.second), getMatchingAgent(it.first, ws).id)
85+
runBlocking {
86+
tests.forEach {
87+
assertEquals(UUID.fromString(it.second), protocolHandler.getMatchingAgent(it.first, ws)?.id)
88+
}
8089
}
8190
}
8291

@@ -104,14 +113,10 @@ internal class LinkHandlerTest {
104113
"agent with ID",
105114
),
106115
)
107-
108-
tests.forEach {
109-
val ex =
110-
assertFailsWith(
111-
exceptionClass = it.second,
112-
block = { getMatchingAgent(it.first, ws).id },
113-
)
114-
assertContains(ex.message.toString(), it.third)
116+
runBlocking {
117+
tests.forEach {
118+
assertNull(protocolHandler.getMatchingAgent(it.first, ws)?.id)
119+
}
115120
}
116121
}
117122

@@ -126,15 +131,16 @@ internal class LinkHandlerTest {
126131
mapOf("agent" to null),
127132
mapOf("agent_id" to null),
128133
)
129-
130-
tests.forEach {
131-
assertEquals(
132-
UUID.fromString("b0e4c54d-9ba9-4413-8512-11ca1e826a24"),
133-
getMatchingAgent(
134-
it,
135-
ws,
136-
).id,
137-
)
134+
runBlocking {
135+
tests.forEach {
136+
assertEquals(
137+
UUID.fromString("b0e4c54d-9ba9-4413-8512-11ca1e826a24"),
138+
protocolHandler.getMatchingAgent(
139+
it,
140+
ws,
141+
)?.id,
142+
)
143+
}
138144
}
139145
}
140146

@@ -149,14 +155,10 @@ internal class LinkHandlerTest {
149155
"agent with ID"
150156
),
151157
)
152-
153-
tests.forEach {
154-
val ex =
155-
assertFailsWith(
156-
exceptionClass = it.second,
157-
block = { getMatchingAgent(it.first, ws).id },
158-
)
159-
assertContains(ex.message.toString(), it.third)
158+
runBlocking {
159+
tests.forEach {
160+
assertNull(protocolHandler.getMatchingAgent(it.first, ws)?.id)
161+
}
160162
}
161163
}
162164

@@ -177,43 +179,10 @@ internal class LinkHandlerTest {
177179
"has no agents"
178180
),
179181
)
180-
181-
tests.forEach {
182-
val ex =
183-
assertFailsWith(
184-
exceptionClass = it.second,
185-
block = { getMatchingAgent(it.first, ws).id },
186-
)
187-
assertContains(ex.message.toString(), it.third)
188-
}
189-
}
190-
191-
@Test
192-
fun followsRedirects() {
193-
val (srv1, url1) =
194-
mockServer { exchange ->
195-
exchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, -1)
196-
exchange.close()
182+
runBlocking {
183+
tests.forEach {
184+
assertNull(protocolHandler.getMatchingAgent(it.first, ws)?.id)
197185
}
198-
val (srv2, url2) = mockRedirectServer(url1, false)
199-
val (srv3, url3) = mockRedirectServer(url2, true)
200-
201-
assertEquals(url1.toURL(), resolveRedirects(java.net.URL(url3)))
202-
203-
srv1.stop(0)
204-
srv2.stop(0)
205-
srv3.stop(0)
206-
}
207-
208-
@Test
209-
fun followsMaximumRedirects() {
210-
val (srv, url) = mockRedirectServer(".", true)
211-
212-
assertFailsWith(
213-
exceptionClass = Exception::class,
214-
block = { resolveRedirects(java.net.URL(url)) },
215-
)
216-
217-
srv.stop(0)
186+
}
218187
}
219188
}

0 commit comments

Comments
 (0)