diff --git a/windows-rdp/main.test.ts b/windows-rdp/main.test.ts index 4e34285..64738e0 100644 --- a/windows-rdp/main.test.ts +++ b/windows-rdp/main.test.ts @@ -1,5 +1,7 @@ import { describe, expect, it, test } from "bun:test"; import { + JsonValue, + TerraformState, executeScriptInContainer, runTerraformApply, runTerraformInit, @@ -13,6 +15,11 @@ type TestVariables = Readonly<{ admin_password?: string; }>; +/** + * @todo It would be nice if we had a way to verify that the Devolutions root + * HTML file is modified to include the import for the patched Coder script, + * but the current test setup doesn't really make that viable + */ describe("Web RDP", async () => { await runTerraformInit(import.meta.dir); testRequiredVariables(import.meta.dir, { @@ -29,21 +36,38 @@ describe("Web RDP", async () => { throw new Error("Not implemented yet"); }); - /** - * @todo Verify that the HTML file has been modified, and that the JS file is - * also part of the file system - */ - it("Patches the Devolutions Angular app's .html file to include an import for the custom JS file", async () => { - const state = await runTerraformApply(import.meta.dir, { - agent_id: "foo", - resource_id: "bar", - }); + it("Injects Terraform's username and password into the JS patch file", async () => { + const findInstancesScript = (state: TerraformState): string | null => { + let instancesScript: string | null = null; + for (const resource of state.resources) { + if (resource.type !== "coder_script") { + continue; + } - throw new Error("Not implemented yet"); - }); + for (const instance of resource.instances) { + if (instance.attributes.display_name === "windows-rdp") { + instancesScript = instance.attributes.script; + } + } + } - it("Injects Terraform's username and password into the JS patch file", async () => { - throw new Error("Not implemented yet"); + return instancesScript; + }; + + /** + * Using a regex as a quick-and-dirty way to get at the username and + * password values. + * + * Tried going through the trouble of extracting out the form entries + * variable from the main output, converting it from Prettier/JS-based JSON + * text to universal JSON text, and exposing it as a parsed JSON value. That + * got to be too much, though. + * + * Written and tested via Regex101 + * @see {@link https://regex101.com/r/UMgQpv/2} + */ + const formEntryValuesRe = + /^const formFieldEntries = \{$.*?^\s+username: \{$.*?^\s*?querySelector.*?,$.*?^\s*value: "(?.+?)",$.*?password: \{$.*?^\s+querySelector: .*?,$.*?^\s*value: "(?.+?)",$.*?^};$/ms; // Test that things work with the default username/password const defaultState = await runTerraformApply( @@ -54,19 +78,35 @@ describe("Web RDP", async () => { }, ); - const output = await executeScriptInContainer(defaultState, "alpine"); + const defaultInstancesScript = findInstancesScript(defaultState); + expect(defaultInstancesScript).toBeString(); + + const { username: defaultUsername, password: defaultPassword } = + formEntryValuesRe.exec(defaultInstancesScript)?.groups ?? {}; + + expect(defaultUsername).toBe("Administrator"); + expect(defaultPassword).toBe("coderRDP!"); // Test that custom usernames/passwords are also forwarded correctly - const customUsername = "crouton"; - const customPassword = "VeryVeryVeryVeryVerySecurePassword97!"; + const userDefinedUsername = "crouton"; + const userDefinedPassword = "VeryVeryVeryVeryVerySecurePassword97!"; const customizedState = await runTerraformApply( import.meta.dir, { agent_id: "foo", resource_id: "bar", - admin_username: customUsername, - admin_password: customPassword, + admin_username: userDefinedUsername, + admin_password: userDefinedPassword, }, ); + + const customInstancesScript = findInstancesScript(customizedState); + expect(customInstancesScript).toBeString(); + + const { username: customUsername, password: customPassword } = + formEntryValuesRe.exec(customInstancesScript)?.groups ?? {}; + + expect(customUsername).toBe(userDefinedUsername); + expect(customPassword).toBe(userDefinedPassword); }); });