|
2 | 2 | import { it, afterEach, vi, expect } from "vitest"
|
3 | 3 | import { SSHConfig } from "./sshConfig"
|
4 | 4 |
|
5 |
| -const sshFilePath = "~/.config/ssh" |
| 5 | +// This is not the usual path to ~/.ssh/config, but |
| 6 | +// setting it to a different path makes it easier to test |
| 7 | +// and makes mistakes abundantly clear. |
| 8 | +const sshFilePath = "/Path/To/UserHomeDir/.sshConfigDir/sshConfigFile" |
| 9 | +const sshTempFilePathExpr = `^/Path/To/UserHomeDir/.sshConfigDir/.sshConfigFile.vscode-coder-tmp.[a-z0-9]+$` |
6 | 10 |
|
7 | 11 | const mockFileSystem = {
|
8 | 12 | mkdir: vi.fn(),
|
@@ -42,11 +46,14 @@ Host coder-vscode--*
|
42 | 46 |
|
43 | 47 | expect(mockFileSystem.readFile).toBeCalledWith(sshFilePath, expect.anything())
|
44 | 48 | expect(mockFileSystem.writeFile).toBeCalledWith(
|
45 |
| - expect.stringContaining(sshFilePath), |
| 49 | + expect.stringMatching(sshTempFilePathExpr), |
46 | 50 | expectedOutput,
|
47 |
| - expect.anything(), |
| 51 | + expect.objectContaining({ |
| 52 | + encoding: "utf-8", |
| 53 | + mode: 0o600, // Default mode for new files. |
| 54 | + }), |
48 | 55 | )
|
49 |
| - expect(mockFileSystem.rename).toBeCalledWith(expect.stringContaining(sshFilePath + "."), sshFilePath) |
| 56 | + expect(mockFileSystem.rename).toBeCalledWith(expect.stringMatching(sshTempFilePathExpr), sshFilePath) |
50 | 57 | })
|
51 | 58 |
|
52 | 59 | it("creates a new file and adds the config", async () => {
|
@@ -75,11 +82,14 @@ Host coder-vscode.dev.coder.com--*
|
75 | 82 |
|
76 | 83 | expect(mockFileSystem.readFile).toBeCalledWith(sshFilePath, expect.anything())
|
77 | 84 | expect(mockFileSystem.writeFile).toBeCalledWith(
|
78 |
| - expect.stringContaining(sshFilePath), |
| 85 | + expect.stringMatching(sshTempFilePathExpr), |
79 | 86 | expectedOutput,
|
80 |
| - expect.anything(), |
| 87 | + expect.objectContaining({ |
| 88 | + encoding: "utf-8", |
| 89 | + mode: 0o600, // Default mode for new files. |
| 90 | + }), |
81 | 91 | )
|
82 |
| - expect(mockFileSystem.rename).toBeCalledWith(expect.stringContaining(sshFilePath + "."), sshFilePath) |
| 92 | + expect(mockFileSystem.rename).toBeCalledWith(expect.stringMatching(sshTempFilePathExpr), sshFilePath) |
83 | 93 | })
|
84 | 94 |
|
85 | 95 | it("adds a new coder config in an existent SSH configuration", async () => {
|
@@ -115,11 +125,11 @@ Host coder-vscode.dev.coder.com--*
|
115 | 125 | UserKnownHostsFile /dev/null
|
116 | 126 | # --- END CODER VSCODE dev.coder.com ---`
|
117 | 127 |
|
118 |
| - expect(mockFileSystem.writeFile).toBeCalledWith(expect.stringContaining(sshFilePath), expectedOutput, { |
| 128 | + expect(mockFileSystem.writeFile).toBeCalledWith(expect.stringMatching(sshTempFilePathExpr), expectedOutput, { |
119 | 129 | encoding: "utf-8",
|
120 | 130 | mode: 0o644,
|
121 | 131 | })
|
122 |
| - expect(mockFileSystem.rename).toBeCalledWith(expect.stringContaining(sshFilePath + "."), sshFilePath) |
| 132 | + expect(mockFileSystem.rename).toBeCalledWith(expect.stringMatching(sshTempFilePathExpr), sshFilePath) |
123 | 133 | })
|
124 | 134 |
|
125 | 135 | it("updates an existent coder config", async () => {
|
@@ -181,11 +191,11 @@ Host coder-vscode.dev-updated.coder.com--*
|
181 | 191 | Host *
|
182 | 192 | SetEnv TEST=1`
|
183 | 193 |
|
184 |
| - expect(mockFileSystem.writeFile).toBeCalledWith(expect.stringContaining(sshFilePath), expectedOutput, { |
| 194 | + expect(mockFileSystem.writeFile).toBeCalledWith(expect.stringMatching(sshTempFilePathExpr), expectedOutput, { |
185 | 195 | encoding: "utf-8",
|
186 | 196 | mode: 0o644,
|
187 | 197 | })
|
188 |
| - expect(mockFileSystem.rename).toBeCalledWith(expect.stringContaining(sshFilePath + "."), sshFilePath) |
| 198 | + expect(mockFileSystem.rename).toBeCalledWith(expect.stringMatching(sshTempFilePathExpr), sshFilePath) |
189 | 199 | })
|
190 | 200 |
|
191 | 201 | it("does not remove deployment-unaware SSH config and adds the new one", async () => {
|
@@ -228,11 +238,11 @@ Host coder-vscode.dev.coder.com--*
|
228 | 238 | UserKnownHostsFile /dev/null
|
229 | 239 | # --- END CODER VSCODE dev.coder.com ---`
|
230 | 240 |
|
231 |
| - expect(mockFileSystem.writeFile).toBeCalledWith(expect.stringContaining(sshFilePath), expectedOutput, { |
| 241 | + expect(mockFileSystem.writeFile).toBeCalledWith(expect.stringMatching(sshTempFilePathExpr), expectedOutput, { |
232 | 242 | encoding: "utf-8",
|
233 | 243 | mode: 0o644,
|
234 | 244 | })
|
235 |
| - expect(mockFileSystem.rename).toBeCalledWith(expect.stringContaining(sshFilePath + "."), sshFilePath) |
| 245 | + expect(mockFileSystem.rename).toBeCalledWith(expect.stringMatching(sshTempFilePathExpr), sshFilePath) |
236 | 246 | })
|
237 | 247 |
|
238 | 248 | it("it does not remove a user-added block that only matches the host of an old coder SSH config", async () => {
|
@@ -264,11 +274,11 @@ Host coder-vscode.dev.coder.com--*
|
264 | 274 | UserKnownHostsFile /dev/null
|
265 | 275 | # --- END CODER VSCODE dev.coder.com ---`
|
266 | 276 |
|
267 |
| - expect(mockFileSystem.writeFile).toBeCalledWith(expect.stringContaining(sshFilePath), expectedOutput, { |
| 277 | + expect(mockFileSystem.writeFile).toBeCalledWith(expect.stringMatching(sshTempFilePathExpr), expectedOutput, { |
268 | 278 | encoding: "utf-8",
|
269 | 279 | mode: 0o644,
|
270 | 280 | })
|
271 |
| - expect(mockFileSystem.rename).toBeCalledWith(expect.stringContaining(sshFilePath + "."), sshFilePath) |
| 281 | + expect(mockFileSystem.rename).toBeCalledWith(expect.stringMatching(sshTempFilePathExpr), sshFilePath) |
272 | 282 | })
|
273 | 283 |
|
274 | 284 | it("throws an error if there is a mismatched start and end block count", async () => {
|
@@ -500,11 +510,11 @@ Host afterconfig
|
500 | 510 | LogLevel: "ERROR",
|
501 | 511 | })
|
502 | 512 |
|
503 |
| - expect(mockFileSystem.writeFile).toBeCalledWith(expect.stringContaining(sshFilePath), expectedOutput, { |
| 513 | + expect(mockFileSystem.writeFile).toBeCalledWith(expect.stringMatching(sshTempFilePathExpr), expectedOutput, { |
504 | 514 | encoding: "utf-8",
|
505 | 515 | mode: 0o644,
|
506 | 516 | })
|
507 |
| - expect(mockFileSystem.rename).toBeCalledWith(expect.stringContaining(sshFilePath + "."), sshFilePath) |
| 517 | + expect(mockFileSystem.rename).toBeCalledWith(expect.stringMatching(sshTempFilePathExpr), sshFilePath) |
508 | 518 | })
|
509 | 519 |
|
510 | 520 | it("override values", async () => {
|
@@ -548,9 +558,12 @@ Host coder-vscode.dev.coder.com--*
|
548 | 558 |
|
549 | 559 | expect(mockFileSystem.readFile).toBeCalledWith(sshFilePath, expect.anything())
|
550 | 560 | expect(mockFileSystem.writeFile).toBeCalledWith(
|
551 |
| - expect.stringContaining(sshFilePath), |
| 561 | + expect.stringMatching(sshTempFilePathExpr), |
552 | 562 | expectedOutput,
|
553 |
| - expect.anything(), |
| 563 | + expect.objectContaining({ |
| 564 | + encoding: "utf-8", |
| 565 | + mode: 0o600, // Default mode for new files. |
| 566 | + }), |
554 | 567 | )
|
555 |
| - expect(mockFileSystem.rename).toBeCalledWith(expect.stringContaining(sshFilePath + "."), sshFilePath) |
| 568 | + expect(mockFileSystem.rename).toBeCalledWith(expect.stringMatching(sshTempFilePathExpr), sshFilePath) |
556 | 569 | })
|
0 commit comments