Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions Coder-Desktop/Coder-Desktop/VPN/MenuState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -156,12 +156,11 @@ struct VPNMenuState {
var invalidAgents: [Vpn_Agent] = []

public func findAgent(workspaceID: UUID, name: String) -> Agent? {
agents.first(where: { $0.value.wsID == workspaceID && $0.value.name == name })?.value
agents.values.first { $0.wsID == workspaceID && $0.name.caseInsensitiveCompare(name) == .orderedSame }
}

public func findWorkspace(name: String) -> Workspace? {
workspaces
.first(where: { $0.value.name == name })?.value
workspaces.values.first { $0.name.caseInsensitiveCompare(name) == .orderedSame }
}

mutating func upsertAgent(_ agent: Vpn_Agent) {
Expand All @@ -179,7 +178,7 @@ struct VPNMenuState {

// An existing agent with the same name, belonging to the same workspace
// is from a previous workspace build, and should be removed.
agents.filter { $0.value.name == agent.name && $0.value.wsID == wsID }
agents.filter { $0.value.name.caseInsensitiveCompare(agent.name) == .orderedSame && $0.value.wsID == wsID }
.forEach { agents[$0.key] = nil }
Comment thread
ethanndickson marked this conversation as resolved.
workspace.agents.insert(id)
workspaces[wsID] = workspace
Expand Down Expand Up @@ -226,9 +225,7 @@ struct VPNMenuState {

mutating func upsertWorkspace(_ workspace: Vpn_Workspace) {
guard let wsID = UUID(uuidData: workspace.id) else { return }
// Workspace names are unique & case-insensitive, and we want to show offline workspaces
// with a valid hostname (lowercase).
workspaces[wsID] = Workspace(id: wsID, name: workspace.name.lowercased(), agents: [])
workspaces[wsID] = Workspace(id: wsID, name: workspace.name, agents: [])
// Check if we can associate any invalid agents with this workspace
invalidAgents.filter { agent in
agent.workspaceID == workspace.id
Expand Down
2 changes: 1 addition & 1 deletion Coder-Desktop/Coder-Desktop/Views/VPN/VPNMenuItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ enum VPNMenuItem: Equatable, Comparable, Identifiable {
func primaryHost(hostnameSuffix: String) -> String {
switch self {
case let .agent(agent): agent.primaryHost
case .offlineWorkspace: "\(wsName).\(hostnameSuffix)"
case .offlineWorkspace: "\(wsName.lowercased()).\(hostnameSuffix)"
}
}

Expand Down
30 changes: 24 additions & 6 deletions Coder-Desktop/Coder-DesktopTests/VPNMenuStateTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ struct VPNMenuStateTests {
let newAgent = Vpn_Agent.with {
$0.id = newAgentID.uuidData
$0.workspaceID = workspaceID.uuidData
$0.name = "agent1" // Same name as old agent
$0.name = "Agent1" // Same name as old agent, different case
$0.lastHandshake = .init(date: Date.now)
$0.lastPing = .with {
$0.latency = .init(floatLiteral: 0.05)
Expand All @@ -174,7 +174,7 @@ struct VPNMenuStateTests {

#expect(state.agents[oldAgentID] == nil)
let storedAgent = try #require(state.agents[newAgentID])
#expect(storedAgent.name == "agent1")
#expect(storedAgent.name == "Agent1")
#expect(storedAgent.wsID == workspaceID)
#expect(storedAgent.primaryHost == "foo.coder")
#expect(storedAgent.status == .okay)
Expand All @@ -183,15 +183,16 @@ struct VPNMenuStateTests {
@Test
mutating func testUpsertWorkspace_addsOfflineWorkspace() async throws {
let workspaceID = UUID()
state.upsertWorkspace(Vpn_Workspace.with { $0.id = workspaceID.uuidData; $0.name = "foo" })
state.upsertWorkspace(Vpn_Workspace.with { $0.id = workspaceID.uuidData; $0.name = "Foo" })

let storedWorkspace = try #require(state.workspaces[workspaceID])
#expect(storedWorkspace.name == "foo")
#expect(storedWorkspace.name == "Foo")

var output = state.sorted
#expect(output.count == 1)
#expect(output[0].id == workspaceID)
#expect(output[0].wsName == "foo")
#expect(output[0].wsName == "Foo")
#expect(output[0].primaryHost(hostnameSuffix: "coder") == "foo.coder")

let agentID = UUID()
let agent = Vpn_Agent.with {
Expand All @@ -210,14 +211,31 @@ struct VPNMenuStateTests {
output = state.sorted
#expect(output.count == 1)
#expect(output[0].id == agentID)
#expect(output[0].wsName == "foo")
#expect(output[0].wsName == "Foo")
#expect(output[0].status == .okay)
let storedAgentFromSort = try #require(state.agents[agentID])
#expect(storedAgentFromSort.statusString.contains("You're connected through a DERP relay."))
#expect(storedAgentFromSort.statusString.contains("Total latency: 50.00 ms"))
#expect(storedAgentFromSort.statusString.contains("Last handshake: 3 minutes ago"))
}

@Test
mutating func testFind_ignoresNameCase() async throws {
let workspaceID = UUID()
let agentID = UUID()
state.upsertWorkspace(Vpn_Workspace.with { $0.id = workspaceID.uuidData; $0.name = "My-Workspace" })
state.upsertAgent(Vpn_Agent.with {
$0.id = agentID.uuidData
$0.workspaceID = workspaceID.uuidData
$0.name = "Main"
$0.fqdn = ["main.my-workspace.me.coder"]
})

#expect(state.findWorkspace(name: "MY-WORKSPACE")?.id == workspaceID)
#expect(state.findAgent(workspaceID: workspaceID, name: "MAIN")?.id == agentID)
#expect(state.findWorkspace(name: "other") == nil)
}

@Test
mutating func testUpsertAgent_invalidAgent_noUUID() async throws {
let agent = Vpn_Agent.with {
Expand Down
Loading