@zuplo/cli 6.63.34 → 6.63.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/archive-utils.test.js.map +1 -1
- package/dist/__tests__/import-openapi-utils.test.js +1 -1
- package/dist/__tests__/import-openapi-utils.test.js.map +1 -1
- package/dist/__tests__/import-openapi.test.js.map +1 -1
- package/dist/__tests__/integration/delete.integration.test.js +1 -1
- package/dist/__tests__/integration/delete.integration.test.js.map +1 -1
- package/dist/__tests__/integration/deploy.integration.test.js +1 -1
- package/dist/__tests__/integration/deploy.integration.test.js.map +1 -1
- package/dist/__tests__/integration/link.integration.test.js +1 -1
- package/dist/__tests__/integration/link.integration.test.js.map +1 -1
- package/dist/__tests__/integration/list.integration.test.js +1 -1
- package/dist/__tests__/integration/list.integration.test.js.map +1 -1
- package/dist/__tests__/integration/tunnel.integration.test.js +1 -1
- package/dist/__tests__/integration/tunnel.integration.test.js.map +1 -1
- package/dist/__tests__/integration/variable.integration.test.js +1 -1
- package/dist/__tests__/integration/variable.integration.test.js.map +1 -1
- package/dist/__tests__/populate.test.js +4 -4
- package/dist/__tests__/populate.test.js.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/cli.js.map +1 -1
- package/dist/cmds/delete.js +2 -2
- package/dist/cmds/delete.js.map +1 -1
- package/dist/cmds/deploy.js +3 -3
- package/dist/cmds/deploy.js.map +1 -1
- package/dist/cmds/link.js +3 -3
- package/dist/cmds/link.js.map +1 -1
- package/dist/cmds/list.js +2 -2
- package/dist/cmds/list.js.map +1 -1
- package/dist/cmds/mtls-certificates/create.js +2 -2
- package/dist/cmds/mtls-certificates/create.js.map +1 -1
- package/dist/cmds/mtls-certificates/delete.js +2 -2
- package/dist/cmds/mtls-certificates/delete.js.map +1 -1
- package/dist/cmds/mtls-certificates/describe.js +2 -2
- package/dist/cmds/mtls-certificates/describe.js.map +1 -1
- package/dist/cmds/mtls-certificates/disable.js +2 -2
- package/dist/cmds/mtls-certificates/disable.js.map +1 -1
- package/dist/cmds/mtls-certificates/list.js +2 -2
- package/dist/cmds/mtls-certificates/list.js.map +1 -1
- package/dist/cmds/mtls-certificates/update.js +2 -2
- package/dist/cmds/mtls-certificates/update.js.map +1 -1
- package/dist/cmds/project/create.d.ts.map +1 -1
- package/dist/cmds/project/create.js +3 -3
- package/dist/cmds/project/create.js.map +1 -1
- package/dist/cmds/source/migrate.d.ts.map +1 -1
- package/dist/cmds/source/migrate.js +2 -2
- package/dist/cmds/source/migrate.js.map +1 -1
- package/dist/cmds/tunnel/create.js +2 -2
- package/dist/cmds/tunnel/create.js.map +1 -1
- package/dist/cmds/tunnel/delete.js +2 -2
- package/dist/cmds/tunnel/delete.js.map +1 -1
- package/dist/cmds/tunnel/describe.js +2 -2
- package/dist/cmds/tunnel/describe.js.map +1 -1
- package/dist/cmds/tunnel/list.js +2 -2
- package/dist/cmds/tunnel/list.js.map +1 -1
- package/dist/cmds/tunnel/rotate-token.js +2 -2
- package/dist/cmds/tunnel/rotate-token.js.map +1 -1
- package/dist/cmds/tunnel/services/describe.js +2 -2
- package/dist/cmds/tunnel/services/describe.js.map +1 -1
- package/dist/cmds/tunnel/services/update.js +2 -2
- package/dist/cmds/tunnel/services/update.js.map +1 -1
- package/dist/cmds/variable/create.js +2 -2
- package/dist/cmds/variable/create.js.map +1 -1
- package/dist/cmds/variable/update.js +2 -2
- package/dist/cmds/variable/update.js.map +1 -1
- package/dist/common/middleware/get-project-param.js +3 -3
- package/dist/common/middleware/get-project-param.js.map +1 -1
- package/dist/common/populate.d.ts.map +1 -1
- package/dist/common/populate.js.map +1 -1
- package/dist/common/utils/stringify-config.test.js +1 -1
- package/dist/common/utils/stringify-config.test.js.map +1 -1
- package/dist/common/worker-output.d.ts.map +1 -1
- package/dist/common/worker-output.js +1 -1
- package/dist/common/worker-output.js.map +1 -1
- package/dist/delete/handler.js +1 -1
- package/dist/delete/handler.js.map +1 -1
- package/dist/deploy/archive.js.map +1 -1
- package/dist/deploy/archive.test.js +2 -2
- package/dist/deploy/archive.test.js.map +1 -1
- package/dist/deploy/handler.d.ts.map +1 -1
- package/dist/deploy/handler.js +2 -2
- package/dist/deploy/handler.js.map +1 -1
- package/dist/dev/handler.js +1 -1
- package/dist/dev/handler.js.map +1 -1
- package/dist/editor/handler.js +2 -2
- package/dist/editor/handler.js.map +1 -1
- package/dist/login/login.js +1 -1
- package/dist/login/login.js.map +1 -1
- package/dist/open-api/convert/convert-engine.d.ts +1 -1
- package/dist/open-api/convert/convert-engine.d.ts.map +1 -1
- package/dist/open-api/convert/convert-engine.js.map +1 -1
- package/dist/open-api/convert/convert-engine.spec.js +2 -2
- package/dist/open-api/convert/convert-engine.spec.js.map +1 -1
- package/dist/open-api/convert/handler.js +2 -2
- package/dist/open-api/convert/handler.js.map +1 -1
- package/dist/open-api/convert/handler.spec.js +1 -1
- package/dist/open-api/convert/handler.spec.js.map +1 -1
- package/dist/open-api/merge/handler.d.ts.map +1 -1
- package/dist/open-api/merge/handler.js +1 -1
- package/dist/open-api/merge/handler.js.map +1 -1
- package/dist/open-api/merge/handler.spec.js +1 -1
- package/dist/open-api/merge/handler.spec.js.map +1 -1
- package/dist/open-api/merge/merge-engine.spec.js +2 -2
- package/dist/open-api/merge/merge-engine.spec.js.map +1 -1
- package/dist/open-api/merge/utils.js +1 -1
- package/dist/open-api/merge/utils.js.map +1 -1
- package/dist/open-api/overlay/handler.js +1 -1
- package/dist/open-api/overlay/handler.js.map +1 -1
- package/dist/open-api/overlay/handler.spec.js +1 -1
- package/dist/open-api/overlay/handler.spec.js.map +1 -1
- package/dist/open-api/overlay/overlay-engine.d.ts.map +1 -1
- package/dist/open-api/overlay/overlay-engine.js.map +1 -1
- package/dist/open-api/overlay/overlay-engine.spec.js +2 -2
- package/dist/open-api/overlay/overlay-engine.spec.js.map +1 -1
- package/dist/source/migrate/dev-portal/handler.d.ts.map +1 -1
- package/dist/source/migrate/dev-portal/handler.js +7 -4
- package/dist/source/migrate/dev-portal/handler.js.map +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.integration.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/list.integration.test.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Integration tests for the list command\n */\n/// <reference types=\"jest\" />\nimport nock from \"nock\";\nimport yargs from \"yargs/yargs\";\nimport listCommand from \"../../cmds/list.js\";\nimport {\n setupTestEnvironment,\n cleanupTest,\n setupAuthenticatedNock,\n RequestCapture,\n TEST_API_BASE,\n TEST_ACCOUNT_NAME,\n TEST_PROJECT_NAME,\n TEST_AUTH_TOKEN,\n} from \"./test-utils.js\";\n\n/**\n * Execute list command with given arguments using actual yargs command\n */\nasync function executeListCommand(args: {\n account?: string;\n project?: string;\n \"api-key\"?: string;\n \"self-hosted-endpoint\"?: string;\n}) {\n const yargsInstance = yargs([])\n .command(listCommand)\n .help(false)\n .version(false)\n .exitProcess(false);\n\n // Build command line arguments\n const commandArgs = [\"list\"];\n\n if (args.account) {\n commandArgs.push(\"--account\", args.account);\n }\n\n if (args.project) {\n commandArgs.push(\"--project\", args.project);\n }\n\n if (args[\"api-key\"]) {\n commandArgs.push(\"--api-key\", args[\"api-key\"]);\n }\n\n if (args[\"self-hosted-endpoint\"]) {\n commandArgs.push(\"--self-hosted-endpoint\", args[\"self-hosted-endpoint\"]);\n }\n\n // Parse and execute the command\n return await yargsInstance.parse(commandArgs);\n}\n\n// Get the mocked functions\nconst mockPrintResult = jest.mocked(\n require(\"../../common/output.js\").printResultToConsoleAndExitGracefully\n);\nconst mockPrintDiagnostics = jest.mocked(\n require(\"../../common/output.js\").printDiagnosticsToConsole\n);\n\ndescribe(\"List Command Integration Tests\", () => {\n let requestCapture: RequestCapture;\n\n beforeEach(() => {\n setupTestEnvironment();\n requestCapture = new RequestCapture();\n\n // Disable real HTTP requests\n nock.disableNetConnect();\n\n // Clear mock calls from previous tests\n jest.clearAllMocks();\n });\n\n afterEach(() => {\n cleanupTest();\n requestCapture.clear();\n });\n\n describe(\"SaaS version\", () => {\n it(\"should intercept GET request to list deployments with account and project\", async () => {\n const mockResponse = {\n data: [\n { url: \"https://test-project-production.zuplo.app\" },\n { url: \"https://test-project-staging.zuplo.app\" },\n ],\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/deployments`\n )\n .reply(200, mockResponse);\n\n // Capture requests for snapshot testing\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n // Execute the list command through yargs\n await executeListCommand({\n account: TEST_ACCOUNT_NAME,\n project: TEST_PROJECT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n });\n\n // Verify the request was made\n expect(scope.isDone()).toBe(true);\n\n // Verify the output function was called with the URLs\n const expectedOutput =\n \"https://test-project-production.zuplo.app\\nhttps://test-project-staging.zuplo.app\";\n expect(mockPrintResult).toHaveBeenCalledWith(expectedOutput);\n\n // Snapshot test for captured requests\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"list-deployments-saas-requests\"\n );\n });\n\n it(\"should handle empty deployments list\", async () => {\n const mockResponse = { data: [] };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/deployments`\n )\n .reply(200, mockResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeListCommand({\n account: TEST_ACCOUNT_NAME,\n project: TEST_PROJECT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintResult).toHaveBeenCalledWith(\"\");\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"list-deployments-empty-requests\"\n );\n });\n\n it(\"should handle API error responses\", async () => {\n const errorResponse = {\n error: \"Not Found\",\n message: \"Project not found\",\n statusCode: 404,\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/deployments`\n )\n .reply(404, errorResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeListCommand({\n account: TEST_ACCOUNT_NAME,\n project: TEST_PROJECT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintDiagnostics).toHaveBeenCalled();\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"list-deployments-error-requests\"\n );\n });\n });\n\n describe(\"Self-hosted version\", () => {\n it(\"should intercept GET request to self-hosted endpoint\", async () => {\n const selfHostedEndpoint = \"https://my-zuplo.company.com\";\n const mockResponse = {\n data: [\n { deploymentUrl: \"https://my-zuplo.company.com/project1\" },\n { deploymentUrl: \"https://my-zuplo.company.com/project2\" },\n ],\n };\n\n const scope = setupAuthenticatedNock(nock(selfHostedEndpoint))\n .get(\"/v1/deployments\")\n .reply(200, mockResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeListCommand({\n account: TEST_ACCOUNT_NAME,\n project: TEST_PROJECT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"self-hosted-endpoint\": selfHostedEndpoint,\n });\n\n expect(scope.isDone()).toBe(true);\n const expectedOutput =\n \"https://my-zuplo.company.com/project1\\nhttps://my-zuplo.company.com/project2\";\n expect(mockPrintResult).toHaveBeenCalledWith(expectedOutput);\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"list-deployments-self-hosted-requests\"\n );\n });\n });\n\n describe(\"Request headers validation\", () => {\n it(\"should include correct authorization headers\", async () => {\n const mockResponse = { data: [{ url: \"https://test.zuplo.app\" }] };\n\n const scope = nock(TEST_API_BASE)\n .get(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/deployments`\n )\n .matchHeader(\"authorization\", `Bearer ${TEST_AUTH_TOKEN}`)\n .reply(200, mockResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeListCommand({\n account: TEST_ACCOUNT_NAME,\n project: TEST_PROJECT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintResult).toHaveBeenCalledWith(\"https://test.zuplo.app\");\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"list-deployments-headers-validation\"\n );\n });\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"list.integration.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/list.integration.test.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Integration tests for the list command\n */\n/// <reference types=\"jest\" />\nimport nock from \"nock\";\nimport yargs from \"yargs/yargs\";\nimport listCommand from \"../../cmds/list.js\";\nimport {\n cleanupTest,\n RequestCapture,\n setupAuthenticatedNock,\n setupTestEnvironment,\n TEST_ACCOUNT_NAME,\n TEST_API_BASE,\n TEST_AUTH_TOKEN,\n TEST_PROJECT_NAME,\n} from \"./test-utils.js\";\n\n/**\n * Execute list command with given arguments using actual yargs command\n */\nasync function executeListCommand(args: {\n account?: string;\n project?: string;\n \"api-key\"?: string;\n \"self-hosted-endpoint\"?: string;\n}) {\n const yargsInstance = yargs([])\n .command(listCommand)\n .help(false)\n .version(false)\n .exitProcess(false);\n\n // Build command line arguments\n const commandArgs = [\"list\"];\n\n if (args.account) {\n commandArgs.push(\"--account\", args.account);\n }\n\n if (args.project) {\n commandArgs.push(\"--project\", args.project);\n }\n\n if (args[\"api-key\"]) {\n commandArgs.push(\"--api-key\", args[\"api-key\"]);\n }\n\n if (args[\"self-hosted-endpoint\"]) {\n commandArgs.push(\"--self-hosted-endpoint\", args[\"self-hosted-endpoint\"]);\n }\n\n // Parse and execute the command\n return await yargsInstance.parse(commandArgs);\n}\n\n// Get the mocked functions\nconst mockPrintResult = jest.mocked(\n require(\"../../common/output.js\").printResultToConsoleAndExitGracefully\n);\nconst mockPrintDiagnostics = jest.mocked(\n require(\"../../common/output.js\").printDiagnosticsToConsole\n);\n\ndescribe(\"List Command Integration Tests\", () => {\n let requestCapture: RequestCapture;\n\n beforeEach(() => {\n setupTestEnvironment();\n requestCapture = new RequestCapture();\n\n // Disable real HTTP requests\n nock.disableNetConnect();\n\n // Clear mock calls from previous tests\n jest.clearAllMocks();\n });\n\n afterEach(() => {\n cleanupTest();\n requestCapture.clear();\n });\n\n describe(\"SaaS version\", () => {\n it(\"should intercept GET request to list deployments with account and project\", async () => {\n const mockResponse = {\n data: [\n { url: \"https://test-project-production.zuplo.app\" },\n { url: \"https://test-project-staging.zuplo.app\" },\n ],\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/deployments`\n )\n .reply(200, mockResponse);\n\n // Capture requests for snapshot testing\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n // Execute the list command through yargs\n await executeListCommand({\n account: TEST_ACCOUNT_NAME,\n project: TEST_PROJECT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n });\n\n // Verify the request was made\n expect(scope.isDone()).toBe(true);\n\n // Verify the output function was called with the URLs\n const expectedOutput =\n \"https://test-project-production.zuplo.app\\nhttps://test-project-staging.zuplo.app\";\n expect(mockPrintResult).toHaveBeenCalledWith(expectedOutput);\n\n // Snapshot test for captured requests\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"list-deployments-saas-requests\"\n );\n });\n\n it(\"should handle empty deployments list\", async () => {\n const mockResponse = { data: [] };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/deployments`\n )\n .reply(200, mockResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeListCommand({\n account: TEST_ACCOUNT_NAME,\n project: TEST_PROJECT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintResult).toHaveBeenCalledWith(\"\");\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"list-deployments-empty-requests\"\n );\n });\n\n it(\"should handle API error responses\", async () => {\n const errorResponse = {\n error: \"Not Found\",\n message: \"Project not found\",\n statusCode: 404,\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/deployments`\n )\n .reply(404, errorResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeListCommand({\n account: TEST_ACCOUNT_NAME,\n project: TEST_PROJECT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintDiagnostics).toHaveBeenCalled();\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"list-deployments-error-requests\"\n );\n });\n });\n\n describe(\"Self-hosted version\", () => {\n it(\"should intercept GET request to self-hosted endpoint\", async () => {\n const selfHostedEndpoint = \"https://my-zuplo.company.com\";\n const mockResponse = {\n data: [\n { deploymentUrl: \"https://my-zuplo.company.com/project1\" },\n { deploymentUrl: \"https://my-zuplo.company.com/project2\" },\n ],\n };\n\n const scope = setupAuthenticatedNock(nock(selfHostedEndpoint))\n .get(\"/v1/deployments\")\n .reply(200, mockResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeListCommand({\n account: TEST_ACCOUNT_NAME,\n project: TEST_PROJECT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"self-hosted-endpoint\": selfHostedEndpoint,\n });\n\n expect(scope.isDone()).toBe(true);\n const expectedOutput =\n \"https://my-zuplo.company.com/project1\\nhttps://my-zuplo.company.com/project2\";\n expect(mockPrintResult).toHaveBeenCalledWith(expectedOutput);\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"list-deployments-self-hosted-requests\"\n );\n });\n });\n\n describe(\"Request headers validation\", () => {\n it(\"should include correct authorization headers\", async () => {\n const mockResponse = { data: [{ url: \"https://test.zuplo.app\" }] };\n\n const scope = nock(TEST_API_BASE)\n .get(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/deployments`\n )\n .matchHeader(\"authorization\", `Bearer ${TEST_AUTH_TOKEN}`)\n .reply(200, mockResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeListCommand({\n account: TEST_ACCOUNT_NAME,\n project: TEST_PROJECT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintResult).toHaveBeenCalledWith(\"https://test.zuplo.app\");\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"list-deployments-headers-validation\"\n );\n });\n });\n});\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import nock from "nock";
|
|
2
2
|
import yargs from "yargs/yargs";
|
|
3
3
|
import tunnelCommand from "../../cmds/tunnel/index.js";
|
|
4
|
-
import {
|
|
4
|
+
import { cleanupTest, RequestCapture, setupAuthenticatedNock, setupTestEnvironment, TEST_ACCOUNT_NAME, TEST_API_BASE, TEST_AUTH_TOKEN, } from "./test-utils.js";
|
|
5
5
|
async function executeTunnelCommand(subcommand, args) {
|
|
6
6
|
const yargsInstance = yargs([])
|
|
7
7
|
.command(tunnelCommand)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tunnel.integration.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/tunnel.integration.test.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Integration tests for the tunnel commands (create and list)\n */\n/// <reference types=\"jest\" />\nimport nock from \"nock\";\nimport yargs from \"yargs/yargs\";\nimport tunnelCommand from \"../../cmds/tunnel/index.js\";\nimport {\n setupTestEnvironment,\n cleanupTest,\n setupAuthenticatedNock,\n RequestCapture,\n TEST_API_BASE,\n TEST_ACCOUNT_NAME,\n TEST_AUTH_TOKEN,\n} from \"./test-utils.js\";\n\n/**\n * Execute tunnel command with given arguments using actual yargs command\n */\nasync function executeTunnelCommand(\n subcommand: \"create\" | \"list\" | \"delete\" | \"describe\" | \"rotate-token\",\n args: {\n account?: string;\n \"api-key\"?: string;\n \"tunnel-name\"?: string;\n \"tunnel-id\"?: string;\n }\n) {\n const yargsInstance = yargs([])\n .command(tunnelCommand)\n .help(false)\n .version(false)\n .exitProcess(false);\n\n // Build command line arguments\n const commandArgs = [\"tunnel\", subcommand];\n\n if (args.account) {\n commandArgs.push(\"--account\", args.account);\n }\n\n if (args[\"api-key\"]) {\n commandArgs.push(\"--api-key\", args[\"api-key\"]);\n }\n\n if (args[\"tunnel-name\"]) {\n commandArgs.push(\"--tunnel-name\", args[\"tunnel-name\"]);\n }\n\n if (args[\"tunnel-id\"]) {\n commandArgs.push(\"--tunnel-id\", args[\"tunnel-id\"]);\n }\n\n // Parse and execute the command\n return await yargsInstance.parse(commandArgs);\n}\n\n/**\n * Execute tunnel services command with given arguments using actual yargs command\n */\nasync function executeTunnelServicesCommand(\n subcommand: \"describe\" | \"update\",\n args: {\n account?: string;\n \"api-key\"?: string;\n \"tunnel-id\"?: string;\n \"configuration-file\"?: string;\n }\n) {\n const yargsInstance = yargs([])\n .command(tunnelCommand)\n .help(false)\n .version(false)\n .exitProcess(false);\n\n // Build command line arguments\n const commandArgs = [\"tunnel\", \"services\", subcommand];\n\n if (args.account) {\n commandArgs.push(\"--account\", args.account);\n }\n\n if (args[\"api-key\"]) {\n commandArgs.push(\"--api-key\", args[\"api-key\"]);\n }\n\n if (args[\"tunnel-id\"]) {\n commandArgs.push(\"--tunnel-id\", args[\"tunnel-id\"]);\n }\n\n if (args[\"configuration-file\"]) {\n commandArgs.push(\"--configuration-file\", args[\"configuration-file\"]);\n }\n\n // Parse and execute the command\n return await yargsInstance.parse(commandArgs);\n}\n\n// Get the mocked functions\nconst mockPrintResult = jest.mocked(\n require(\"../../common/output.js\").printResultToConsoleAndExitGracefully\n);\nconst mockPrintTable = jest.mocked(\n require(\"../../common/output.js\").printTableToConsoleAndExitGracefully\n);\nconst mockPrintDiagnostics = jest.mocked(\n require(\"../../common/output.js\").printDiagnosticsToConsole\n);\n\ndescribe(\"Tunnel Command Integration Tests\", () => {\n let requestCapture: RequestCapture;\n\n beforeEach(() => {\n setupTestEnvironment();\n requestCapture = new RequestCapture();\n\n // Disable real HTTP requests\n nock.disableNetConnect();\n\n // Clear mock calls from previous tests\n jest.clearAllMocks();\n });\n\n afterEach(() => {\n cleanupTest();\n requestCapture.clear();\n });\n\n describe(\"Tunnel Create Command\", () => {\n it(\"should intercept POST request to create tunnel\", async () => {\n const testTunnelName = \"my-test-tunnel\";\n const mockResponse = {\n id: \"tunnel-123\",\n name: testTunnelName,\n token: \"tunnel-token-abc123\",\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .post(`/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels`)\n .reply(201, mockResponse);\n\n // Capture requests for snapshot testing\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n // Execute the tunnel create command through yargs\n await executeTunnelCommand(\"create\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-name\": testTunnelName,\n });\n\n // Verify the request was made\n expect(scope.isDone()).toBe(true);\n\n // Verify the output function was called with tunnel info\n expect(mockPrintTable).toHaveBeenCalledWith(mockResponse);\n\n // Snapshot test for captured requests\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\"tunnel-create-requests\");\n\n // Verify request body\n const request = capturedRequests[0];\n expect(request.method).toBe(\"POST\");\n expect(request.body).toEqual({\n name: testTunnelName,\n });\n });\n\n it(\"should handle tunnel creation error\", async () => {\n const testTunnelName = \"invalid-tunnel\";\n const errorResponse = {\n error: \"Bad Request\",\n message: \"Tunnel name already exists\",\n statusCode: 400,\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .post(`/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels`)\n .reply(400, errorResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelCommand(\"create\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-name\": testTunnelName,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintDiagnostics).toHaveBeenCalled();\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\"tunnel-create-error-requests\");\n });\n });\n\n describe(\"Tunnel List Command\", () => {\n it(\"should intercept GET request to list tunnels\", async () => {\n const mockResponse = {\n data: [\n { id: \"tunnel-123\", name: \"tunnel-1\" },\n { id: \"tunnel-456\", name: \"tunnel-2\" },\n ],\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels`)\n .reply(200, mockResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelCommand(\"list\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n });\n\n expect(scope.isDone()).toBe(true);\n\n // Verify the output function was called with formatted table\n const expectedTable = [\n { \"tunnel-id\": \"tunnel-123\", name: \"tunnel-1\" },\n { \"tunnel-id\": \"tunnel-456\", name: \"tunnel-2\" },\n ];\n expect(mockPrintTable).toHaveBeenCalledWith(expectedTable);\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\"tunnel-list-requests\");\n });\n\n it(\"should handle empty tunnels list\", async () => {\n const mockResponse = { data: [] };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels`)\n .reply(200, mockResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelCommand(\"list\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintResult).toHaveBeenCalledWith(\"No tunnels found\");\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\"tunnel-list-empty-requests\");\n });\n\n it(\"should handle API error responses\", async () => {\n const errorResponse = {\n error: \"Forbidden\",\n message: \"Access denied\",\n statusCode: 403,\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels`)\n .reply(403, errorResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelCommand(\"list\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintDiagnostics).toHaveBeenCalled();\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\"tunnel-list-error-requests\");\n });\n });\n\n describe(\"Tunnel Delete Command\", () => {\n it(\"should intercept DELETE request to delete tunnel\", async () => {\n const tunnelId = \"test-tunnel-123\";\n const mockTeardownResponse = {\n id: \"teardown-op-456\",\n status: \"in-progress\",\n };\n\n const mockCompletedTeardown = {\n id: \"teardown-op-456\",\n status: \"success\",\n message: \"Tunnel deleted successfully\",\n };\n\n // Mock the delete initiation\n const deleteScope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .delete(`/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels/${tunnelId}`)\n .reply(200, mockTeardownResponse);\n\n // Mock the polling endpoint\n const pollScope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels/${tunnelId}/teardown-operations/teardown-op-456`\n )\n .reply(200, mockCompletedTeardown);\n\n deleteScope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n pollScope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelCommand(\"delete\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-id\": tunnelId,\n });\n\n expect(deleteScope.isDone()).toBe(true);\n expect(pollScope.isDone()).toBe(true);\n expect(mockPrintResult).toHaveBeenCalledWith(\n \"Tunnel test-tunnel-123 deleted successfully.\"\n );\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\"tunnel-delete-requests\");\n });\n\n it(\"should handle tunnel deletion error\", async () => {\n const tunnelId = \"nonexistent-tunnel\";\n const errorResponse = {\n error: \"Not Found\",\n message: \"Tunnel not found\",\n statusCode: 404,\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .delete(`/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels/${tunnelId}`)\n .reply(404, errorResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelCommand(\"delete\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-id\": tunnelId,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintDiagnostics).toHaveBeenCalled();\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\"tunnel-delete-error-requests\");\n });\n });\n\n describe(\"Tunnel Describe Command\", () => {\n it(\"should intercept GET request to describe tunnel\", async () => {\n const tunnelId = \"test-tunnel-123\";\n const mockTunnelDetails = {\n id: tunnelId,\n name: \"Test Tunnel\",\n status: \"active\",\n endpoint: \"https://test-tunnel.zuplo.dev\",\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels/${tunnelId}`)\n .reply(200, mockTunnelDetails);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelCommand(\"describe\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-id\": tunnelId,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintTable).toHaveBeenCalledWith(mockTunnelDetails);\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\"tunnel-describe-requests\");\n });\n\n it(\"should handle tunnel describe error\", async () => {\n const tunnelId = \"nonexistent-tunnel\";\n const errorResponse = {\n error: \"Not Found\",\n message: \"Tunnel not found\",\n statusCode: 404,\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels/${tunnelId}`)\n .reply(404, errorResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelCommand(\"describe\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-id\": tunnelId,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintDiagnostics).toHaveBeenCalled();\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"tunnel-describe-error-requests\"\n );\n });\n });\n\n describe(\"Tunnel Rotate Token Command\", () => {\n it(\"should intercept POST request to rotate tunnel token\", async () => {\n const tunnelId = \"test-tunnel-123\";\n const mockTokenResponse = {\n tunnelId: tunnelId,\n newToken: \"new-token-abc123\",\n message: \"Token rotated successfully\",\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .post(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels/${tunnelId}/$rotate-token`\n )\n .reply(200, mockTokenResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelCommand(\"rotate-token\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-id\": tunnelId,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintTable).toHaveBeenCalledWith(mockTokenResponse);\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\"tunnel-rotate-token-requests\");\n });\n\n it(\"should handle token rotation error\", async () => {\n const tunnelId = \"nonexistent-tunnel\";\n const errorResponse = {\n error: \"Forbidden\",\n message: \"Access denied\",\n statusCode: 403,\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .post(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels/${tunnelId}/$rotate-token`\n )\n .reply(403, errorResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelCommand(\"rotate-token\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-id\": tunnelId,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintDiagnostics).toHaveBeenCalled();\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"tunnel-rotate-token-error-requests\"\n );\n });\n });\n\n describe(\"Tunnel Services Describe Command\", () => {\n it(\"should intercept GET request to describe tunnel services\", async () => {\n const tunnelId = \"test-tunnel-123\";\n const mockServicesResponse = {\n tunnelId: tunnelId,\n services: [\n { name: \"api-service\", port: 3000, status: \"running\" },\n { name: \"web-service\", port: 8080, status: \"running\" },\n ],\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels/${tunnelId}/services-configuration`\n )\n .reply(200, mockServicesResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelServicesCommand(\"describe\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-id\": tunnelId,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintResult).toHaveBeenCalledWith(\n JSON.stringify(mockServicesResponse, null, 2)\n );\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"tunnel-services-describe-requests\"\n );\n });\n\n it(\"should handle services describe error\", async () => {\n const tunnelId = \"nonexistent-tunnel\";\n const errorResponse = {\n error: \"Not Found\",\n message: \"Tunnel not found\",\n statusCode: 404,\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels/${tunnelId}/services-configuration`\n )\n .reply(404, errorResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelServicesCommand(\"describe\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-id\": tunnelId,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintDiagnostics).toHaveBeenCalled();\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"tunnel-services-describe-error-requests\"\n );\n });\n });\n\n describe(\"Tunnel Services Update Command\", () => {\n it(\"should handle services update error due to file read failure\", async () => {\n const tunnelId = \"test-tunnel-123\";\n const configFile = \"/nonexistent/config.json\";\n\n // This test will fail when trying to read the file, triggering printCriticalFailureToConsoleAndExit\n await expect(\n executeTunnelServicesCommand(\"update\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-id\": tunnelId,\n \"configuration-file\": configFile,\n })\n ).rejects.toThrow(\"Process would exit\");\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"tunnel-services-update-file-error-requests\"\n );\n });\n\n it(\"should handle services update API error\", async () => {\n const tunnelId = \"test-tunnel-123\";\n // Create a temporary config file for testing\n const tempConfigFile = \"/tmp/test-config.json\";\n\n // Mock filesystem operations\n const mockFs = require(\"node:fs/promises\");\n const originalReadFile = mockFs.readFile;\n mockFs.readFile = jest.fn().mockResolvedValue('{\"services\": []}');\n\n const errorResponse = {\n error: \"Bad Request\",\n message: \"Invalid configuration file\",\n statusCode: 400,\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .put(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels/${tunnelId}/services-configuration`\n )\n .reply(400, errorResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelServicesCommand(\"update\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-id\": tunnelId,\n \"configuration-file\": tempConfigFile,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintDiagnostics).toHaveBeenCalled();\n\n // Restore mock\n mockFs.readFile = originalReadFile;\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"tunnel-services-update-error-requests\"\n );\n });\n });\n\n describe(\"Request validation\", () => {\n it(\"should include correct headers for create request\", async () => {\n const testTunnelName = \"test-tunnel\";\n const mockResponse = {\n id: \"tunnel-123\",\n name: testTunnelName,\n token: \"tunnel-token-abc123\",\n };\n\n const scope = nock(TEST_API_BASE)\n .post(`/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels`)\n .matchHeader(\"authorization\", `Bearer ${TEST_AUTH_TOKEN}`)\n .matchHeader(\"content-type\", \"application/json\")\n .reply(201, mockResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelCommand(\"create\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-name\": testTunnelName,\n });\n\n expect(scope.isDone()).toBe(true);\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"tunnel-create-headers-validation\"\n );\n });\n\n it(\"should include correct headers for list request\", async () => {\n const mockResponse = { data: [{ id: \"tunnel-123\", name: \"tunnel-1\" }] };\n\n const scope = nock(TEST_API_BASE)\n .get(`/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels`)\n .matchHeader(\"authorization\", `Bearer ${TEST_AUTH_TOKEN}`)\n .reply(200, mockResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelCommand(\"list\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n });\n\n expect(scope.isDone()).toBe(true);\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"tunnel-list-headers-validation\"\n );\n\n // Verify it's a GET request with no body\n const request = capturedRequests[0];\n expect(request.method).toBe(\"GET\");\n expect(request.body).toBeUndefined();\n });\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"tunnel.integration.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/tunnel.integration.test.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Integration tests for the tunnel commands (create and list)\n */\n/// <reference types=\"jest\" />\nimport nock from \"nock\";\nimport yargs from \"yargs/yargs\";\nimport tunnelCommand from \"../../cmds/tunnel/index.js\";\nimport {\n cleanupTest,\n RequestCapture,\n setupAuthenticatedNock,\n setupTestEnvironment,\n TEST_ACCOUNT_NAME,\n TEST_API_BASE,\n TEST_AUTH_TOKEN,\n} from \"./test-utils.js\";\n\n/**\n * Execute tunnel command with given arguments using actual yargs command\n */\nasync function executeTunnelCommand(\n subcommand: \"create\" | \"list\" | \"delete\" | \"describe\" | \"rotate-token\",\n args: {\n account?: string;\n \"api-key\"?: string;\n \"tunnel-name\"?: string;\n \"tunnel-id\"?: string;\n }\n) {\n const yargsInstance = yargs([])\n .command(tunnelCommand)\n .help(false)\n .version(false)\n .exitProcess(false);\n\n // Build command line arguments\n const commandArgs = [\"tunnel\", subcommand];\n\n if (args.account) {\n commandArgs.push(\"--account\", args.account);\n }\n\n if (args[\"api-key\"]) {\n commandArgs.push(\"--api-key\", args[\"api-key\"]);\n }\n\n if (args[\"tunnel-name\"]) {\n commandArgs.push(\"--tunnel-name\", args[\"tunnel-name\"]);\n }\n\n if (args[\"tunnel-id\"]) {\n commandArgs.push(\"--tunnel-id\", args[\"tunnel-id\"]);\n }\n\n // Parse and execute the command\n return await yargsInstance.parse(commandArgs);\n}\n\n/**\n * Execute tunnel services command with given arguments using actual yargs command\n */\nasync function executeTunnelServicesCommand(\n subcommand: \"describe\" | \"update\",\n args: {\n account?: string;\n \"api-key\"?: string;\n \"tunnel-id\"?: string;\n \"configuration-file\"?: string;\n }\n) {\n const yargsInstance = yargs([])\n .command(tunnelCommand)\n .help(false)\n .version(false)\n .exitProcess(false);\n\n // Build command line arguments\n const commandArgs = [\"tunnel\", \"services\", subcommand];\n\n if (args.account) {\n commandArgs.push(\"--account\", args.account);\n }\n\n if (args[\"api-key\"]) {\n commandArgs.push(\"--api-key\", args[\"api-key\"]);\n }\n\n if (args[\"tunnel-id\"]) {\n commandArgs.push(\"--tunnel-id\", args[\"tunnel-id\"]);\n }\n\n if (args[\"configuration-file\"]) {\n commandArgs.push(\"--configuration-file\", args[\"configuration-file\"]);\n }\n\n // Parse and execute the command\n return await yargsInstance.parse(commandArgs);\n}\n\n// Get the mocked functions\nconst mockPrintResult = jest.mocked(\n require(\"../../common/output.js\").printResultToConsoleAndExitGracefully\n);\nconst mockPrintTable = jest.mocked(\n require(\"../../common/output.js\").printTableToConsoleAndExitGracefully\n);\nconst mockPrintDiagnostics = jest.mocked(\n require(\"../../common/output.js\").printDiagnosticsToConsole\n);\n\ndescribe(\"Tunnel Command Integration Tests\", () => {\n let requestCapture: RequestCapture;\n\n beforeEach(() => {\n setupTestEnvironment();\n requestCapture = new RequestCapture();\n\n // Disable real HTTP requests\n nock.disableNetConnect();\n\n // Clear mock calls from previous tests\n jest.clearAllMocks();\n });\n\n afterEach(() => {\n cleanupTest();\n requestCapture.clear();\n });\n\n describe(\"Tunnel Create Command\", () => {\n it(\"should intercept POST request to create tunnel\", async () => {\n const testTunnelName = \"my-test-tunnel\";\n const mockResponse = {\n id: \"tunnel-123\",\n name: testTunnelName,\n token: \"tunnel-token-abc123\",\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .post(`/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels`)\n .reply(201, mockResponse);\n\n // Capture requests for snapshot testing\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n // Execute the tunnel create command through yargs\n await executeTunnelCommand(\"create\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-name\": testTunnelName,\n });\n\n // Verify the request was made\n expect(scope.isDone()).toBe(true);\n\n // Verify the output function was called with tunnel info\n expect(mockPrintTable).toHaveBeenCalledWith(mockResponse);\n\n // Snapshot test for captured requests\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\"tunnel-create-requests\");\n\n // Verify request body\n const request = capturedRequests[0];\n expect(request.method).toBe(\"POST\");\n expect(request.body).toEqual({\n name: testTunnelName,\n });\n });\n\n it(\"should handle tunnel creation error\", async () => {\n const testTunnelName = \"invalid-tunnel\";\n const errorResponse = {\n error: \"Bad Request\",\n message: \"Tunnel name already exists\",\n statusCode: 400,\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .post(`/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels`)\n .reply(400, errorResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelCommand(\"create\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-name\": testTunnelName,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintDiagnostics).toHaveBeenCalled();\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\"tunnel-create-error-requests\");\n });\n });\n\n describe(\"Tunnel List Command\", () => {\n it(\"should intercept GET request to list tunnels\", async () => {\n const mockResponse = {\n data: [\n { id: \"tunnel-123\", name: \"tunnel-1\" },\n { id: \"tunnel-456\", name: \"tunnel-2\" },\n ],\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels`)\n .reply(200, mockResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelCommand(\"list\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n });\n\n expect(scope.isDone()).toBe(true);\n\n // Verify the output function was called with formatted table\n const expectedTable = [\n { \"tunnel-id\": \"tunnel-123\", name: \"tunnel-1\" },\n { \"tunnel-id\": \"tunnel-456\", name: \"tunnel-2\" },\n ];\n expect(mockPrintTable).toHaveBeenCalledWith(expectedTable);\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\"tunnel-list-requests\");\n });\n\n it(\"should handle empty tunnels list\", async () => {\n const mockResponse = { data: [] };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels`)\n .reply(200, mockResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelCommand(\"list\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintResult).toHaveBeenCalledWith(\"No tunnels found\");\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\"tunnel-list-empty-requests\");\n });\n\n it(\"should handle API error responses\", async () => {\n const errorResponse = {\n error: \"Forbidden\",\n message: \"Access denied\",\n statusCode: 403,\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels`)\n .reply(403, errorResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelCommand(\"list\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintDiagnostics).toHaveBeenCalled();\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\"tunnel-list-error-requests\");\n });\n });\n\n describe(\"Tunnel Delete Command\", () => {\n it(\"should intercept DELETE request to delete tunnel\", async () => {\n const tunnelId = \"test-tunnel-123\";\n const mockTeardownResponse = {\n id: \"teardown-op-456\",\n status: \"in-progress\",\n };\n\n const mockCompletedTeardown = {\n id: \"teardown-op-456\",\n status: \"success\",\n message: \"Tunnel deleted successfully\",\n };\n\n // Mock the delete initiation\n const deleteScope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .delete(`/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels/${tunnelId}`)\n .reply(200, mockTeardownResponse);\n\n // Mock the polling endpoint\n const pollScope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels/${tunnelId}/teardown-operations/teardown-op-456`\n )\n .reply(200, mockCompletedTeardown);\n\n deleteScope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n pollScope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelCommand(\"delete\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-id\": tunnelId,\n });\n\n expect(deleteScope.isDone()).toBe(true);\n expect(pollScope.isDone()).toBe(true);\n expect(mockPrintResult).toHaveBeenCalledWith(\n \"Tunnel test-tunnel-123 deleted successfully.\"\n );\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\"tunnel-delete-requests\");\n });\n\n it(\"should handle tunnel deletion error\", async () => {\n const tunnelId = \"nonexistent-tunnel\";\n const errorResponse = {\n error: \"Not Found\",\n message: \"Tunnel not found\",\n statusCode: 404,\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .delete(`/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels/${tunnelId}`)\n .reply(404, errorResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelCommand(\"delete\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-id\": tunnelId,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintDiagnostics).toHaveBeenCalled();\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\"tunnel-delete-error-requests\");\n });\n });\n\n describe(\"Tunnel Describe Command\", () => {\n it(\"should intercept GET request to describe tunnel\", async () => {\n const tunnelId = \"test-tunnel-123\";\n const mockTunnelDetails = {\n id: tunnelId,\n name: \"Test Tunnel\",\n status: \"active\",\n endpoint: \"https://test-tunnel.zuplo.dev\",\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels/${tunnelId}`)\n .reply(200, mockTunnelDetails);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelCommand(\"describe\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-id\": tunnelId,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintTable).toHaveBeenCalledWith(mockTunnelDetails);\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\"tunnel-describe-requests\");\n });\n\n it(\"should handle tunnel describe error\", async () => {\n const tunnelId = \"nonexistent-tunnel\";\n const errorResponse = {\n error: \"Not Found\",\n message: \"Tunnel not found\",\n statusCode: 404,\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(`/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels/${tunnelId}`)\n .reply(404, errorResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelCommand(\"describe\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-id\": tunnelId,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintDiagnostics).toHaveBeenCalled();\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"tunnel-describe-error-requests\"\n );\n });\n });\n\n describe(\"Tunnel Rotate Token Command\", () => {\n it(\"should intercept POST request to rotate tunnel token\", async () => {\n const tunnelId = \"test-tunnel-123\";\n const mockTokenResponse = {\n tunnelId: tunnelId,\n newToken: \"new-token-abc123\",\n message: \"Token rotated successfully\",\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .post(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels/${tunnelId}/$rotate-token`\n )\n .reply(200, mockTokenResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelCommand(\"rotate-token\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-id\": tunnelId,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintTable).toHaveBeenCalledWith(mockTokenResponse);\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\"tunnel-rotate-token-requests\");\n });\n\n it(\"should handle token rotation error\", async () => {\n const tunnelId = \"nonexistent-tunnel\";\n const errorResponse = {\n error: \"Forbidden\",\n message: \"Access denied\",\n statusCode: 403,\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .post(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels/${tunnelId}/$rotate-token`\n )\n .reply(403, errorResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelCommand(\"rotate-token\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-id\": tunnelId,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintDiagnostics).toHaveBeenCalled();\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"tunnel-rotate-token-error-requests\"\n );\n });\n });\n\n describe(\"Tunnel Services Describe Command\", () => {\n it(\"should intercept GET request to describe tunnel services\", async () => {\n const tunnelId = \"test-tunnel-123\";\n const mockServicesResponse = {\n tunnelId: tunnelId,\n services: [\n { name: \"api-service\", port: 3000, status: \"running\" },\n { name: \"web-service\", port: 8080, status: \"running\" },\n ],\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels/${tunnelId}/services-configuration`\n )\n .reply(200, mockServicesResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelServicesCommand(\"describe\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-id\": tunnelId,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintResult).toHaveBeenCalledWith(\n JSON.stringify(mockServicesResponse, null, 2)\n );\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"tunnel-services-describe-requests\"\n );\n });\n\n it(\"should handle services describe error\", async () => {\n const tunnelId = \"nonexistent-tunnel\";\n const errorResponse = {\n error: \"Not Found\",\n message: \"Tunnel not found\",\n statusCode: 404,\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels/${tunnelId}/services-configuration`\n )\n .reply(404, errorResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelServicesCommand(\"describe\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-id\": tunnelId,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintDiagnostics).toHaveBeenCalled();\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"tunnel-services-describe-error-requests\"\n );\n });\n });\n\n describe(\"Tunnel Services Update Command\", () => {\n it(\"should handle services update error due to file read failure\", async () => {\n const tunnelId = \"test-tunnel-123\";\n const configFile = \"/nonexistent/config.json\";\n\n // This test will fail when trying to read the file, triggering printCriticalFailureToConsoleAndExit\n await expect(\n executeTunnelServicesCommand(\"update\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-id\": tunnelId,\n \"configuration-file\": configFile,\n })\n ).rejects.toThrow(\"Process would exit\");\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"tunnel-services-update-file-error-requests\"\n );\n });\n\n it(\"should handle services update API error\", async () => {\n const tunnelId = \"test-tunnel-123\";\n // Create a temporary config file for testing\n const tempConfigFile = \"/tmp/test-config.json\";\n\n // Mock filesystem operations\n const mockFs = require(\"node:fs/promises\");\n const originalReadFile = mockFs.readFile;\n mockFs.readFile = jest.fn().mockResolvedValue('{\"services\": []}');\n\n const errorResponse = {\n error: \"Bad Request\",\n message: \"Invalid configuration file\",\n statusCode: 400,\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .put(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels/${tunnelId}/services-configuration`\n )\n .reply(400, errorResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelServicesCommand(\"update\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-id\": tunnelId,\n \"configuration-file\": tempConfigFile,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintDiagnostics).toHaveBeenCalled();\n\n // Restore mock\n mockFs.readFile = originalReadFile;\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"tunnel-services-update-error-requests\"\n );\n });\n });\n\n describe(\"Request validation\", () => {\n it(\"should include correct headers for create request\", async () => {\n const testTunnelName = \"test-tunnel\";\n const mockResponse = {\n id: \"tunnel-123\",\n name: testTunnelName,\n token: \"tunnel-token-abc123\",\n };\n\n const scope = nock(TEST_API_BASE)\n .post(`/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels`)\n .matchHeader(\"authorization\", `Bearer ${TEST_AUTH_TOKEN}`)\n .matchHeader(\"content-type\", \"application/json\")\n .reply(201, mockResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelCommand(\"create\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-name\": testTunnelName,\n });\n\n expect(scope.isDone()).toBe(true);\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"tunnel-create-headers-validation\"\n );\n });\n\n it(\"should include correct headers for list request\", async () => {\n const mockResponse = { data: [{ id: \"tunnel-123\", name: \"tunnel-1\" }] };\n\n const scope = nock(TEST_API_BASE)\n .get(`/v1/accounts/${TEST_ACCOUNT_NAME}/tunnels`)\n .matchHeader(\"authorization\", `Bearer ${TEST_AUTH_TOKEN}`)\n .reply(200, mockResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeTunnelCommand(\"list\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n });\n\n expect(scope.isDone()).toBe(true);\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"tunnel-list-headers-validation\"\n );\n\n // Verify it's a GET request with no body\n const request = capturedRequests[0];\n expect(request.method).toBe(\"GET\");\n expect(request.body).toBeUndefined();\n });\n });\n});\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import nock from "nock";
|
|
2
2
|
import yargs from "yargs/yargs";
|
|
3
3
|
import variableCommand from "../../cmds/variable/index.js";
|
|
4
|
-
import {
|
|
4
|
+
import { cleanupTest, RequestCapture, setupAuthenticatedNock, setupTestEnvironment, TEST_ACCOUNT_NAME, TEST_API_BASE, TEST_AUTH_TOKEN, TEST_PROJECT_NAME, } from "./test-utils.js";
|
|
5
5
|
async function executeVariableCommand(subcommand, args) {
|
|
6
6
|
const yargsInstance = yargs([])
|
|
7
7
|
.command(variableCommand)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"variable.integration.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/variable.integration.test.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Integration tests for the variable commands (create and update)\n */\n/// <reference types=\"jest\" />\nimport nock from \"nock\";\nimport yargs from \"yargs/yargs\";\nimport variableCommand from \"../../cmds/variable/index.js\";\nimport {\n setupTestEnvironment,\n cleanupTest,\n setupAuthenticatedNock,\n RequestCapture,\n TEST_API_BASE,\n TEST_ACCOUNT_NAME,\n TEST_PROJECT_NAME,\n TEST_AUTH_TOKEN,\n} from \"./test-utils.js\";\n\n/**\n * Execute variable command with given arguments using actual yargs command\n */\nasync function executeVariableCommand(\n subcommand: \"create\" | \"update\",\n args: {\n account?: string;\n project?: string;\n \"api-key\"?: string;\n name: string;\n value: string;\n branch: string;\n \"is-secret\"?: boolean;\n }\n) {\n const yargsInstance = yargs([])\n .command(variableCommand)\n .help(false)\n .version(false)\n .exitProcess(false);\n\n // Build command line arguments\n const commandArgs = [\"variable\", subcommand];\n\n if (args.account) {\n commandArgs.push(\"--account\", args.account);\n }\n\n if (args.project) {\n commandArgs.push(\"--project\", args.project);\n }\n\n if (args[\"api-key\"]) {\n commandArgs.push(\"--api-key\", args[\"api-key\"]);\n }\n\n commandArgs.push(\"--name\", args.name);\n commandArgs.push(\"--value\", args.value);\n commandArgs.push(\"--branch\", args.branch);\n\n if (subcommand === \"create\") {\n // is-secret is required for create command\n if (args[\"is-secret\"]) {\n commandArgs.push(\"--is-secret\");\n } else {\n commandArgs.push(\"--is-secret\", \"false\");\n }\n }\n\n // Parse and execute the command\n return await yargsInstance.parse(commandArgs);\n}\n\n// Get the mocked functions\nconst mockPrintResult = jest.mocked(\n require(\"../../common/output.js\").printResultToConsole\n);\nconst mockPrintDiagnostics = jest.mocked(\n require(\"../../common/output.js\").printDiagnosticsToConsole\n);\n\ndescribe(\"Variable Command Integration Tests\", () => {\n let requestCapture: RequestCapture;\n\n beforeEach(() => {\n setupTestEnvironment();\n requestCapture = new RequestCapture();\n\n // Disable real HTTP requests\n nock.disableNetConnect();\n\n // Clear mock calls from previous tests\n jest.clearAllMocks();\n });\n\n afterEach(() => {\n cleanupTest();\n requestCapture.clear();\n });\n\n describe(\"Variable Create Command\", () => {\n it(\"should intercept POST request to create variable\", async () => {\n const testBranch = \"main\";\n const testVariableName = \"API_URL\";\n const testValue = \"https://api.example.com\";\n const mockResponse = {\n name: testVariableName,\n \"is-secret\": false,\n value: testValue,\n branch: testBranch,\n createdOn: \"2024-01-01T00:00:00Z\",\n updatedOn: \"2024-01-01T00:00:00Z\",\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .post(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/branches/${encodeURIComponent(testBranch)}/variables`\n )\n .reply(201, mockResponse);\n\n // Capture requests for snapshot testing\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n // Execute the variable create command through yargs\n await executeVariableCommand(\"create\", {\n account: TEST_ACCOUNT_NAME,\n project: TEST_PROJECT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n name: testVariableName,\n value: testValue,\n branch: testBranch,\n \"is-secret\": false,\n });\n\n // Verify the request was made\n expect(scope.isDone()).toBe(true);\n\n // Verify the output function was called\n expect(mockPrintResult).toHaveBeenCalledWith(\n `${testVariableName} created successfully`\n );\n\n // Snapshot test for captured requests\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\"variable-create-requests\");\n\n // Verify request body\n const request = capturedRequests[0];\n expect(request.method).toBe(\"POST\");\n expect(request.body).toEqual({\n name: testVariableName,\n isSecret: false,\n value: testValue,\n });\n });\n\n it(\"should handle secret variable creation\", async () => {\n const testBranch = \"production\";\n const testVariableName = \"DATABASE_PASSWORD\";\n const testValue = \"super-secret-password\";\n const mockResponse = {\n name: testVariableName,\n \"is-secret\": true,\n value: \"[REDACTED]\",\n branch: testBranch,\n createdOn: \"2024-01-01T00:00:00Z\",\n updatedOn: \"2024-01-01T00:00:00Z\",\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .post(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/branches/${encodeURIComponent(testBranch)}/variables`\n )\n .reply(201, mockResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeVariableCommand(\"create\", {\n account: TEST_ACCOUNT_NAME,\n project: TEST_PROJECT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n name: testVariableName,\n value: testValue,\n branch: testBranch,\n \"is-secret\": true,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintResult).toHaveBeenCalledWith(\n `${testVariableName} created successfully`\n );\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"variable-create-secret-requests\"\n );\n\n // Verify secret flag is set correctly\n const request = capturedRequests[0];\n expect(request.body).toEqual({\n name: testVariableName,\n isSecret: true,\n value: testValue,\n });\n });\n\n it(\"should handle variable creation error\", async () => {\n const testBranch = \"main\";\n const testVariableName = \"INVALID_VAR\";\n const testValue = \"test-value\";\n const errorResponse = {\n error: \"Bad Request\",\n message: \"Variable name already exists\",\n statusCode: 400,\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .post(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/branches/${encodeURIComponent(testBranch)}/variables`\n )\n .reply(400, errorResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeVariableCommand(\"create\", {\n account: TEST_ACCOUNT_NAME,\n project: TEST_PROJECT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n name: testVariableName,\n value: testValue,\n branch: testBranch,\n \"is-secret\": false,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintDiagnostics).toHaveBeenCalled();\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"variable-create-error-requests\"\n );\n });\n });\n\n describe(\"Variable Update Command\", () => {\n it(\"should intercept PATCH request to update variable\", async () => {\n const testBranch = \"main\";\n const testVariableName = \"API_URL\";\n const testValue = \"https://api-v2.example.com\";\n const mockResponse = {\n name: testVariableName,\n \"is-secret\": false,\n value: testValue,\n branch: testBranch,\n createdOn: \"2024-01-01T00:00:00Z\",\n updatedOn: \"2024-01-02T00:00:00Z\",\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .patch(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/branches/${encodeURIComponent(testBranch)}/variables/${encodeURIComponent(testVariableName)}`\n )\n .reply(200, mockResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeVariableCommand(\"update\", {\n account: TEST_ACCOUNT_NAME,\n project: TEST_PROJECT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n name: testVariableName,\n value: testValue,\n branch: testBranch,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintResult).toHaveBeenCalledWith(\n `${testVariableName} updated successfully`\n );\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\"variable-update-requests\");\n\n // Verify request body contains only value for update\n const request = capturedRequests[0];\n expect(request.method).toBe(\"PATCH\");\n expect(request.body).toEqual({\n value: testValue,\n });\n });\n\n it(\"should handle variable not found error\", async () => {\n const testBranch = \"main\";\n const testVariableName = \"NONEXISTENT_VAR\";\n const testValue = \"new-value\";\n const errorResponse = {\n error: \"Not Found\",\n message: \"Variable not found\",\n statusCode: 404,\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .patch(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/branches/${encodeURIComponent(testBranch)}/variables/${encodeURIComponent(testVariableName)}`\n )\n .reply(404, errorResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeVariableCommand(\"update\", {\n account: TEST_ACCOUNT_NAME,\n project: TEST_PROJECT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n name: testVariableName,\n value: testValue,\n branch: testBranch,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintDiagnostics).toHaveBeenCalled();\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"variable-update-error-requests\"\n );\n });\n });\n\n describe(\"Request validation\", () => {\n it(\"should include correct headers and content-type\", async () => {\n const testBranch = \"main\";\n const testVariableName = \"TEST_VAR\";\n const testValue = \"test-value\";\n const mockResponse = {\n name: testVariableName,\n \"is-secret\": false,\n value: testValue,\n branch: testBranch,\n createdOn: \"2024-01-01T00:00:00Z\",\n updatedOn: \"2024-01-01T00:00:00Z\",\n };\n\n const scope = nock(TEST_API_BASE)\n .post(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/branches/${encodeURIComponent(testBranch)}/variables`\n )\n .matchHeader(\"authorization\", `Bearer ${TEST_AUTH_TOKEN}`)\n .matchHeader(\"content-type\", \"application/json\")\n .reply(201, mockResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeVariableCommand(\"create\", {\n account: TEST_ACCOUNT_NAME,\n project: TEST_PROJECT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n name: testVariableName,\n value: testValue,\n branch: testBranch,\n \"is-secret\": false,\n });\n\n expect(scope.isDone()).toBe(true);\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\"variable-headers-validation\");\n });\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"variable.integration.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/variable.integration.test.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Integration tests for the variable commands (create and update)\n */\n/// <reference types=\"jest\" />\nimport nock from \"nock\";\nimport yargs from \"yargs/yargs\";\nimport variableCommand from \"../../cmds/variable/index.js\";\nimport {\n cleanupTest,\n RequestCapture,\n setupAuthenticatedNock,\n setupTestEnvironment,\n TEST_ACCOUNT_NAME,\n TEST_API_BASE,\n TEST_AUTH_TOKEN,\n TEST_PROJECT_NAME,\n} from \"./test-utils.js\";\n\n/**\n * Execute variable command with given arguments using actual yargs command\n */\nasync function executeVariableCommand(\n subcommand: \"create\" | \"update\",\n args: {\n account?: string;\n project?: string;\n \"api-key\"?: string;\n name: string;\n value: string;\n branch: string;\n \"is-secret\"?: boolean;\n }\n) {\n const yargsInstance = yargs([])\n .command(variableCommand)\n .help(false)\n .version(false)\n .exitProcess(false);\n\n // Build command line arguments\n const commandArgs = [\"variable\", subcommand];\n\n if (args.account) {\n commandArgs.push(\"--account\", args.account);\n }\n\n if (args.project) {\n commandArgs.push(\"--project\", args.project);\n }\n\n if (args[\"api-key\"]) {\n commandArgs.push(\"--api-key\", args[\"api-key\"]);\n }\n\n commandArgs.push(\"--name\", args.name);\n commandArgs.push(\"--value\", args.value);\n commandArgs.push(\"--branch\", args.branch);\n\n if (subcommand === \"create\") {\n // is-secret is required for create command\n if (args[\"is-secret\"]) {\n commandArgs.push(\"--is-secret\");\n } else {\n commandArgs.push(\"--is-secret\", \"false\");\n }\n }\n\n // Parse and execute the command\n return await yargsInstance.parse(commandArgs);\n}\n\n// Get the mocked functions\nconst mockPrintResult = jest.mocked(\n require(\"../../common/output.js\").printResultToConsole\n);\nconst mockPrintDiagnostics = jest.mocked(\n require(\"../../common/output.js\").printDiagnosticsToConsole\n);\n\ndescribe(\"Variable Command Integration Tests\", () => {\n let requestCapture: RequestCapture;\n\n beforeEach(() => {\n setupTestEnvironment();\n requestCapture = new RequestCapture();\n\n // Disable real HTTP requests\n nock.disableNetConnect();\n\n // Clear mock calls from previous tests\n jest.clearAllMocks();\n });\n\n afterEach(() => {\n cleanupTest();\n requestCapture.clear();\n });\n\n describe(\"Variable Create Command\", () => {\n it(\"should intercept POST request to create variable\", async () => {\n const testBranch = \"main\";\n const testVariableName = \"API_URL\";\n const testValue = \"https://api.example.com\";\n const mockResponse = {\n name: testVariableName,\n \"is-secret\": false,\n value: testValue,\n branch: testBranch,\n createdOn: \"2024-01-01T00:00:00Z\",\n updatedOn: \"2024-01-01T00:00:00Z\",\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .post(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/branches/${encodeURIComponent(testBranch)}/variables`\n )\n .reply(201, mockResponse);\n\n // Capture requests for snapshot testing\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n // Execute the variable create command through yargs\n await executeVariableCommand(\"create\", {\n account: TEST_ACCOUNT_NAME,\n project: TEST_PROJECT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n name: testVariableName,\n value: testValue,\n branch: testBranch,\n \"is-secret\": false,\n });\n\n // Verify the request was made\n expect(scope.isDone()).toBe(true);\n\n // Verify the output function was called\n expect(mockPrintResult).toHaveBeenCalledWith(\n `${testVariableName} created successfully`\n );\n\n // Snapshot test for captured requests\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\"variable-create-requests\");\n\n // Verify request body\n const request = capturedRequests[0];\n expect(request.method).toBe(\"POST\");\n expect(request.body).toEqual({\n name: testVariableName,\n isSecret: false,\n value: testValue,\n });\n });\n\n it(\"should handle secret variable creation\", async () => {\n const testBranch = \"production\";\n const testVariableName = \"DATABASE_PASSWORD\";\n const testValue = \"super-secret-password\";\n const mockResponse = {\n name: testVariableName,\n \"is-secret\": true,\n value: \"[REDACTED]\",\n branch: testBranch,\n createdOn: \"2024-01-01T00:00:00Z\",\n updatedOn: \"2024-01-01T00:00:00Z\",\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .post(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/branches/${encodeURIComponent(testBranch)}/variables`\n )\n .reply(201, mockResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeVariableCommand(\"create\", {\n account: TEST_ACCOUNT_NAME,\n project: TEST_PROJECT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n name: testVariableName,\n value: testValue,\n branch: testBranch,\n \"is-secret\": true,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintResult).toHaveBeenCalledWith(\n `${testVariableName} created successfully`\n );\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"variable-create-secret-requests\"\n );\n\n // Verify secret flag is set correctly\n const request = capturedRequests[0];\n expect(request.body).toEqual({\n name: testVariableName,\n isSecret: true,\n value: testValue,\n });\n });\n\n it(\"should handle variable creation error\", async () => {\n const testBranch = \"main\";\n const testVariableName = \"INVALID_VAR\";\n const testValue = \"test-value\";\n const errorResponse = {\n error: \"Bad Request\",\n message: \"Variable name already exists\",\n statusCode: 400,\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .post(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/branches/${encodeURIComponent(testBranch)}/variables`\n )\n .reply(400, errorResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeVariableCommand(\"create\", {\n account: TEST_ACCOUNT_NAME,\n project: TEST_PROJECT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n name: testVariableName,\n value: testValue,\n branch: testBranch,\n \"is-secret\": false,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintDiagnostics).toHaveBeenCalled();\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"variable-create-error-requests\"\n );\n });\n });\n\n describe(\"Variable Update Command\", () => {\n it(\"should intercept PATCH request to update variable\", async () => {\n const testBranch = \"main\";\n const testVariableName = \"API_URL\";\n const testValue = \"https://api-v2.example.com\";\n const mockResponse = {\n name: testVariableName,\n \"is-secret\": false,\n value: testValue,\n branch: testBranch,\n createdOn: \"2024-01-01T00:00:00Z\",\n updatedOn: \"2024-01-02T00:00:00Z\",\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .patch(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/branches/${encodeURIComponent(testBranch)}/variables/${encodeURIComponent(testVariableName)}`\n )\n .reply(200, mockResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeVariableCommand(\"update\", {\n account: TEST_ACCOUNT_NAME,\n project: TEST_PROJECT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n name: testVariableName,\n value: testValue,\n branch: testBranch,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintResult).toHaveBeenCalledWith(\n `${testVariableName} updated successfully`\n );\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\"variable-update-requests\");\n\n // Verify request body contains only value for update\n const request = capturedRequests[0];\n expect(request.method).toBe(\"PATCH\");\n expect(request.body).toEqual({\n value: testValue,\n });\n });\n\n it(\"should handle variable not found error\", async () => {\n const testBranch = \"main\";\n const testVariableName = \"NONEXISTENT_VAR\";\n const testValue = \"new-value\";\n const errorResponse = {\n error: \"Not Found\",\n message: \"Variable not found\",\n statusCode: 404,\n };\n\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .patch(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/branches/${encodeURIComponent(testBranch)}/variables/${encodeURIComponent(testVariableName)}`\n )\n .reply(404, errorResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeVariableCommand(\"update\", {\n account: TEST_ACCOUNT_NAME,\n project: TEST_PROJECT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n name: testVariableName,\n value: testValue,\n branch: testBranch,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintDiagnostics).toHaveBeenCalled();\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"variable-update-error-requests\"\n );\n });\n });\n\n describe(\"Request validation\", () => {\n it(\"should include correct headers and content-type\", async () => {\n const testBranch = \"main\";\n const testVariableName = \"TEST_VAR\";\n const testValue = \"test-value\";\n const mockResponse = {\n name: testVariableName,\n \"is-secret\": false,\n value: testValue,\n branch: testBranch,\n createdOn: \"2024-01-01T00:00:00Z\",\n updatedOn: \"2024-01-01T00:00:00Z\",\n };\n\n const scope = nock(TEST_API_BASE)\n .post(\n `/v1/accounts/${TEST_ACCOUNT_NAME}/projects/${TEST_PROJECT_NAME}/branches/${encodeURIComponent(testBranch)}/variables`\n )\n .matchHeader(\"authorization\", `Bearer ${TEST_AUTH_TOKEN}`)\n .matchHeader(\"content-type\", \"application/json\")\n .reply(201, mockResponse);\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeVariableCommand(\"create\", {\n account: TEST_ACCOUNT_NAME,\n project: TEST_PROJECT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n name: testVariableName,\n value: testValue,\n branch: testBranch,\n \"is-secret\": false,\n });\n\n expect(scope.isDone()).toBe(true);\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\"variable-headers-validation\");\n });\n });\n});\n"]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { mkdir, readFile, rm } from "node:fs/promises";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
1
4
|
import { beforeEach, describe, it } from "node:test";
|
|
2
5
|
import { assert } from "chai";
|
|
3
|
-
import { MockAgent, setGlobalDispatcher } from "undici";
|
|
4
|
-
import { readFile, rm, mkdir } from "node:fs/promises";
|
|
5
|
-
import { join } from "node:path";
|
|
6
|
-
import { tmpdir } from "node:os";
|
|
7
6
|
import { parse as dotenvParse } from "dotenv";
|
|
7
|
+
import { MockAgent, setGlobalDispatcher } from "undici";
|
|
8
8
|
const TEST_ENVIRONMENT = "test-env-123";
|
|
9
9
|
const TEST_AUTH_TOKEN = "test-auth-token-456";
|
|
10
10
|
const TEST_API_ENDPOINT = "https://dev.zuplo.com";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"populate.test.js","sourceRoot":"","sources":["../../src/__tests__/populate.test.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Unit tests for the pullSystemConfig function\n * Focuses on testing the parsing logic and environment file generation\n */\n\nimport { beforeEach, describe, it } from \"node:test\";\nimport { assert } from \"chai\";\nimport { MockAgent, setGlobalDispatcher } from \"undici\";\nimport { readFile, rm, mkdir } from \"node:fs/promises\";\n// biome-ignore lint/correctness/noUnusedImports: Migrated from ESLint\nimport { join, parse } from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport { parse as dotenvParse } from \"dotenv\";\n\n// Test constants\nconst TEST_ENVIRONMENT = \"test-env-123\";\nconst TEST_AUTH_TOKEN = \"test-auth-token-456\";\nconst TEST_API_ENDPOINT = \"https://dev.zuplo.com\";\n\ndescribe(\"pullSystemConfig\", () => {\n let mockAgent: MockAgent;\n let testDir: string;\n\n beforeEach(async () => {\n // Setup HTTP mocking\n mockAgent = new MockAgent();\n mockAgent.disableNetConnect();\n setGlobalDispatcher(mockAgent);\n\n // Create a temporary directory for testing\n testDir = join(tmpdir(), `zuplo-test-${Date.now()}`);\n await mkdir(testDir, { recursive: true });\n });\n\n it(\"should generate correct .env.zuplo file with system variables\", async () => {\n const mockPayload = {\n accountName: \"test-account\",\n projectName: \"test-project\",\n environmentType: \"development\",\n systemConfigurations: \"config-123\",\n };\n\n // Mock successful API response\n mockAgent\n .get(TEST_API_ENDPOINT)\n .intercept({\n path: `/v1/environments/${TEST_ENVIRONMENT}/local-configurations`,\n method: \"GET\",\n headers: {\n authorization: `Bearer ${TEST_AUTH_TOKEN}`,\n },\n })\n .reply(200, mockPayload);\n\n const { pullLocalConfig: pullSystemConfig } = await import(\n \"../common/populate.js\"\n );\n\n await pullSystemConfig({\n dir: testDir,\n environment: TEST_ENVIRONMENT,\n authToken: TEST_AUTH_TOKEN,\n });\n\n // Verify the .env.zuplo file was created\n const envFilePath = join(testDir, \".env.zuplo\");\n const content = await readFile(envFilePath, \"utf-8\");\n\n // Verify file header\n assert.include(\n content,\n \"# This file is auto-generated from zuplo link. Please do not edit it manually.\"\n );\n assert.include(\n content,\n \"# It will be auto-generated afresh the next time you run zuplo link.\"\n );\n assert.include(\n content,\n \"# If you wish to add your own environment variables, create a separate .env file.\"\n );\n\n // Verify system variables are present\n assert.include(content, \"ZUPLO_ACCOUNT_NAME=test-account\");\n assert.include(content, \"ZUPLO_PROJECT_NAME=test-project\");\n assert.include(content, \"ZUPLO_ENVIRONMENT_TYPE=development\");\n assert.include(content, \"ZUPLO_SYSTEM_CONFIGURATIONS=config-123\");\n\n // Verify sections are NOT present when there are no variables for them\n assert.notInclude(content, \"# Public Zuplo environment variables\");\n assert.notInclude(\n content,\n \"# Environment variables defined in the Zuplo UI for the environment\"\n );\n\n // Clean up\n await rm(testDir, { recursive: true, force: true });\n });\n\n it(\"should handle payload with public and user environment variables\", async () => {\n const mockPayload = {\n accountName: \"my-account\",\n projectName: \"my-project\",\n environmentType: \"production\",\n systemConfigurations: \"prod-config-456\",\n // Public variables (should be in public section)\n ZUPLO_PUBLIC_API_URL: \"https://api.example.com\",\n ZUPLO_PUBLIC_DOCS_URL: \"https://docs.example.com\",\n // User variables (should be in user section)\n DATABASE_URL: \"postgres://localhost:5432/db\",\n API_KEY: \"secret-key-123\",\n REDIS_URL: \"redis://localhost:6379\",\n };\n\n // Mock successful API response\n mockAgent\n .get(TEST_API_ENDPOINT)\n .intercept({\n path: `/v1/environments/${TEST_ENVIRONMENT}/local-configurations`,\n method: \"GET\",\n headers: {\n authorization: `Bearer ${TEST_AUTH_TOKEN}`,\n },\n })\n .reply(200, mockPayload);\n\n const { pullLocalConfig: pullSystemConfig } = await import(\n \"../common/populate.js\"\n );\n\n await pullSystemConfig({\n dir: testDir,\n environment: TEST_ENVIRONMENT,\n authToken: TEST_AUTH_TOKEN,\n });\n\n // Read the generated file\n const envFilePath = join(testDir, \".env.zuplo\");\n const content = await readFile(envFilePath, \"utf-8\");\n\n // Verify system variables\n assert.include(content, \"ZUPLO_ACCOUNT_NAME=my-account\");\n assert.include(content, \"ZUPLO_PROJECT_NAME=my-project\");\n assert.include(content, \"ZUPLO_ENVIRONMENT_TYPE=production\");\n assert.include(content, \"ZUPLO_SYSTEM_CONFIGURATIONS=prod-config-456\");\n\n // Verify public variables are in the public section\n const publicSectionRegex =\n /# Public Zuplo environment variables[\\s\\S]*?(?=# Environment variables defined in the Zuplo UI|$)/;\n const publicSection = content.match(publicSectionRegex)?.[0] || \"\";\n assert.include(\n publicSection,\n 'ZUPLO_PUBLIC_API_URL=\"https://api.example.com\"'\n );\n assert.include(\n publicSection,\n 'ZUPLO_PUBLIC_DOCS_URL=\"https://docs.example.com\"'\n );\n\n // Verify user variables are in the user section\n const userSectionRegex =\n /# Environment variables defined in the Zuplo UI[\\s\\S]*$/;\n const userSection = content.match(userSectionRegex)?.[0] || \"\";\n assert.include(userSection, 'DATABASE_URL=\"postgres://localhost:5432/db\"');\n assert.include(userSection, 'API_KEY=\"secret-key-123\"');\n assert.include(userSection, 'REDIS_URL=\"redis://localhost:6379\"');\n\n // Verify system variables are NOT in user section\n assert.notInclude(userSection, \"accountName=\");\n assert.notInclude(userSection, \"projectName=\");\n assert.notInclude(userSection, \"environmentType=\");\n assert.notInclude(userSection, \"systemConfigurations=\");\n\n // Clean up\n await rm(testDir, { recursive: true, force: true });\n });\n\n it(\"should handle empty environment variables gracefully\", async () => {\n const mockPayload = {\n accountName: \"test-account\",\n projectName: \"test-project\",\n environmentType: \"development\",\n systemConfigurations: \"config-789\",\n // No additional environment variables\n };\n\n // Mock successful API response\n mockAgent\n .get(TEST_API_ENDPOINT)\n .intercept({\n path: `/v1/environments/${TEST_ENVIRONMENT}/local-configurations`,\n method: \"GET\",\n headers: {\n authorization: `Bearer ${TEST_AUTH_TOKEN}`,\n },\n })\n .reply(200, mockPayload);\n\n const { pullLocalConfig: pullSystemConfig } = await import(\n \"../common/populate.js\"\n );\n\n await pullSystemConfig({\n dir: testDir,\n environment: TEST_ENVIRONMENT,\n authToken: TEST_AUTH_TOKEN,\n });\n\n // Read the generated file\n const envFilePath = join(testDir, \".env.zuplo\");\n const content = await readFile(envFilePath, \"utf-8\");\n\n // Verify system variables are still present\n assert.include(content, \"ZUPLO_ACCOUNT_NAME=test-account\");\n assert.include(content, \"ZUPLO_PROJECT_NAME=test-project\");\n assert.include(content, \"ZUPLO_ENVIRONMENT_TYPE=development\");\n assert.include(content, \"ZUPLO_SYSTEM_CONFIGURATIONS=config-789\");\n\n // Verify sections are NOT present when there are no variables for them\n assert.notInclude(content, \"# Public Zuplo environment variables\");\n assert.notInclude(\n content,\n \"# Environment variables defined in the Zuplo UI for the environment\"\n );\n\n // Clean up\n await rm(testDir, { recursive: true, force: true });\n });\n\n it(\"should handle special characters in environment variable values\", async () => {\n const mockPayload = {\n accountName: \"test-account\",\n projectName: \"test-project\",\n environmentType: \"development\",\n systemConfigurations: \"config-123\",\n DATABASE_URL: \"postgres://user:p@ssw0rd!@localhost:5432/db?ssl=true\",\n API_SECRET: \"secret-with-special-chars!@#$%^&*()\",\n JSON_CONFIG: '{\"key\": \"value\", \"nested\": {\"array\": [1, 2, 3]}}',\n };\n\n // Mock successful API response\n mockAgent\n .get(TEST_API_ENDPOINT)\n .intercept({\n path: `/v1/environments/${TEST_ENVIRONMENT}/local-configurations`,\n method: \"GET\",\n headers: {\n authorization: `Bearer ${TEST_AUTH_TOKEN}`,\n },\n })\n .reply(200, mockPayload);\n\n const { pullLocalConfig: pullSystemConfig } = await import(\n \"../common/populate.js\"\n );\n\n await pullSystemConfig({\n dir: testDir,\n environment: TEST_ENVIRONMENT,\n authToken: TEST_AUTH_TOKEN,\n });\n\n // Read the generated file\n const envFilePath = join(testDir, \".env.zuplo\");\n const content = await readFile(envFilePath, \"utf-8\");\n\n // Verify special characters are preserved in environment variable values\n assert.include(\n content,\n 'DATABASE_URL=\"postgres://user:p@ssw0rd!@localhost:5432/db?ssl=true\"'\n );\n assert.include(content, 'API_SECRET=\"secret-with-special-chars!@#$%^&*()\"');\n assert.include(\n content,\n 'JSON_CONFIG=\"{\\\\\"key\\\\\": \\\\\"value\\\\\", \\\\\"nested\\\\\": {\\\\\"array\\\\\": [1, 2, 3]}}\"'\n );\n\n // Verify these are in the user section (not public section)\n const userSectionRegex =\n /# Environment variables defined in the Zuplo UI[\\s\\S]*$/;\n const userSection = content.match(userSectionRegex)?.[0] || \"\";\n assert.include(\n userSection,\n 'DATABASE_URL=\"postgres://user:p@ssw0rd!@localhost:5432/db?ssl=true\"'\n );\n assert.include(\n userSection,\n 'API_SECRET=\"secret-with-special-chars!@#$%^&*()\"'\n );\n assert.include(\n userSection,\n 'JSON_CONFIG=\"{\\\\\"key\\\\\": \\\\\"value\\\\\", \\\\\"nested\\\\\": {\\\\\"array\\\\\": [1, 2, 3]}}\"'\n );\n\n // Clean up\n await rm(testDir, { recursive: true, force: true });\n });\n\n it(\"should only include public variables section when public variables exist\", async () => {\n const mockPayload = {\n accountName: \"test-account\",\n projectName: \"test-project\",\n environmentType: \"development\",\n systemConfigurations: \"config-123\",\n // Only public variables, no user variables\n ZUPLO_PUBLIC_API_URL: \"https://api.example.com\",\n ZUPLO_PUBLIC_DOCS_URL: \"https://docs.example.com\",\n };\n\n // Mock successful API response\n mockAgent\n .get(TEST_API_ENDPOINT)\n .intercept({\n path: `/v1/environments/${TEST_ENVIRONMENT}/local-configurations`,\n method: \"GET\",\n headers: {\n authorization: `Bearer ${TEST_AUTH_TOKEN}`,\n },\n })\n .reply(200, mockPayload);\n\n const { pullLocalConfig: pullSystemConfig } = await import(\n \"../common/populate.js\"\n );\n\n await pullSystemConfig({\n dir: testDir,\n environment: TEST_ENVIRONMENT,\n authToken: TEST_AUTH_TOKEN,\n });\n\n // Read the generated file\n const envFilePath = join(testDir, \".env.zuplo\");\n const content = await readFile(envFilePath, \"utf-8\");\n\n // Verify system variables are present\n assert.include(content, \"ZUPLO_ACCOUNT_NAME=test-account\");\n assert.include(content, \"ZUPLO_PROJECT_NAME=test-project\");\n assert.include(content, \"ZUPLO_ENVIRONMENT_TYPE=development\");\n assert.include(content, \"ZUPLO_SYSTEM_CONFIGURATIONS=config-123\");\n\n // Verify public section is present with variables\n assert.include(content, \"# Public Zuplo environment variables\");\n assert.include(content, 'ZUPLO_PUBLIC_API_URL=\"https://api.example.com\"');\n assert.include(content, 'ZUPLO_PUBLIC_DOCS_URL=\"https://docs.example.com\"');\n\n // Verify user section is NOT present since there are no user variables\n assert.notInclude(\n content,\n \"# Environment variables defined in the Zuplo UI for the environment\"\n );\n\n // Clean up\n await rm(testDir, { recursive: true, force: true });\n });\n\n it(\"should only include user variables section when user variables exist\", async () => {\n const mockPayload = {\n accountName: \"test-account\",\n projectName: \"test-project\",\n environmentType: \"development\",\n systemConfigurations: \"config-123\",\n // Only user variables, no public variables\n DATABASE_URL: \"postgres://localhost:5432/db\",\n API_KEY: \"secret-key-123\",\n };\n\n // Mock successful API response\n mockAgent\n .get(TEST_API_ENDPOINT)\n .intercept({\n path: `/v1/environments/${TEST_ENVIRONMENT}/local-configurations`,\n method: \"GET\",\n headers: {\n authorization: `Bearer ${TEST_AUTH_TOKEN}`,\n },\n })\n .reply(200, mockPayload);\n\n const { pullLocalConfig: pullSystemConfig } = await import(\n \"../common/populate.js\"\n );\n\n await pullSystemConfig({\n dir: testDir,\n environment: TEST_ENVIRONMENT,\n authToken: TEST_AUTH_TOKEN,\n });\n\n // Read the generated file\n const envFilePath = join(testDir, \".env.zuplo\");\n const content = await readFile(envFilePath, \"utf-8\");\n\n // Verify system variables are present\n assert.include(content, \"ZUPLO_ACCOUNT_NAME=test-account\");\n assert.include(content, \"ZUPLO_PROJECT_NAME=test-project\");\n assert.include(content, \"ZUPLO_ENVIRONMENT_TYPE=development\");\n assert.include(content, \"ZUPLO_SYSTEM_CONFIGURATIONS=config-123\");\n\n // Verify public section is NOT present since there are no public variables\n assert.notInclude(content, \"# Public Zuplo environment variables\");\n\n // Verify user section is present with variables\n assert.include(\n content,\n \"# Environment variables defined in the Zuplo UI for the environment\"\n );\n assert.include(content, 'DATABASE_URL=\"postgres://localhost:5432/db\"');\n assert.include(content, 'API_KEY=\"secret-key-123\"');\n\n // Clean up\n await rm(testDir, { recursive: true, force: true });\n });\n\n it(\"should properly escape double quotes in environment variable values for dotenv parsing\", async () => {\n const mockPayload = {\n accountName: \"test-account\",\n projectName: \"test-project\",\n environmentType: \"development\",\n systemConfigurations: \"config-123\",\n // Environment variables with double quotes that need escaping\n DATABASE_URL: \"postgres://user:p'assw'ord@localhost:5432/db\",\n API_KEY: \"secret'with'quotes\",\n JSON_CONFIG:\n '{\"message\": \"Hello \\'world\\'\", \"nested\": {\"value\": \"test\\'s\"}}',\n ZUPLO_PUBLIC_MESSAGE: \"Welcome to Zuplo's platform!\",\n COMPLEX_VALUE: \"?\\\\\\\"!##==A_special_chars'''\",\n // Additional special character test cases\n EDGE_CASE_1: \"value with 'single' and \\\"double\\\" quotes\",\n EDGE_CASE_2: \"path\\\\to\\\\file's location\",\n EDGE_CASE_3: \"it's a $pecial @#$%^&*() value!\",\n EDGE_CASE_4: \"multi\\nline\\nwith'quotes\",\n EDGE_CASE_5: \"tabs\\tand\\tspaces and 'quotes'\",\n };\n\n // Mock successful API response\n mockAgent\n .get(TEST_API_ENDPOINT)\n .intercept({\n path: `/v1/environments/${TEST_ENVIRONMENT}/local-configurations`,\n method: \"GET\",\n headers: {\n authorization: `Bearer ${TEST_AUTH_TOKEN}`,\n },\n })\n .reply(200, mockPayload);\n\n const { pullLocalConfig: pullSystemConfig } = await import(\n \"../common/populate.js\"\n );\n\n await pullSystemConfig({\n dir: testDir,\n environment: TEST_ENVIRONMENT,\n authToken: TEST_AUTH_TOKEN,\n });\n\n // Read the generated file\n const envFilePath = join(testDir, \".env.zuplo\");\n const content = await readFile(envFilePath, \"utf-8\");\n\n // Verify that all values use double quotes with escaped double quotes\n assert.include(\n content,\n \"DATABASE_URL=\\\"postgres://user:p'assw'ord@localhost:5432/db\\\"\"\n );\n assert.include(content, \"API_KEY=\\\"secret'with'quotes\\\"\");\n assert.include(\n content,\n 'JSON_CONFIG=\"{\\\\\"message\\\\\": \\\\\"Hello \\'world\\'\\\\\", \\\\\"nested\\\\\": {\\\\\"value\\\\\": \\\\\"test\\'s\\\\\"}}\"'\n );\n assert.include(\n content,\n 'ZUPLO_PUBLIC_MESSAGE=\"Welcome to Zuplo\\'s platform!\"'\n );\n assert.include(content, `COMPLEX_VALUE=\"?\\\\\\\\\"!##==A_special_chars'''\"`);\n\n // Verify additional edge cases use double quotes with escaped double quotes\n assert.include(\n content,\n 'EDGE_CASE_1=\"value with \\'single\\' and \\\\\"double\\\\\" quotes\"'\n );\n assert.include(content, 'EDGE_CASE_2=\"path\\\\to\\\\file\\'s location\"');\n assert.include(content, 'EDGE_CASE_3=\"it\\'s a $pecial @#$%^&*() value!\"');\n assert.include(content, 'EDGE_CASE_4=\"multi\\nline\\nwith\\'quotes\"');\n assert.include(content, \"EDGE_CASE_5=\\\"tabs\\tand\\tspaces and 'quotes'\\\"\");\n\n // Test that dotenv can properly parse the generated file\n const fileContent = await readFile(envFilePath, \"utf-8\");\n const parsedEnv = dotenvParse(fileContent);\n\n // Verify that dotenv successfully parsed the file without errors\n assert.isUndefined(\n parsedEnv.error,\n \"dotenv should parse the file without errors\"\n );\n\n // Verify that the parsed values match the original values from the mock payload\n // Note: dotenv may not perfectly unescape all values, but should parse without errors\n assert.equal(parsedEnv.DATABASE_URL, mockPayload.DATABASE_URL);\n assert.equal(parsedEnv.API_KEY, mockPayload.API_KEY);\n // For JSON_CONFIG, dotenv doesn't unescape the quotes, so we check that it contains the escaped version\n assert.isString(parsedEnv.JSON_CONFIG);\n assert.include(parsedEnv.JSON_CONFIG, '\\\\\"message\\\\\"');\n assert.equal(\n parsedEnv.ZUPLO_PUBLIC_MESSAGE,\n mockPayload.ZUPLO_PUBLIC_MESSAGE\n );\n // For COMPLEX_VALUE, dotenv doesn't unescape the backslash-escaped quotes properly\n assert.isString(parsedEnv.COMPLEX_VALUE);\n assert.include(parsedEnv.COMPLEX_VALUE, \"special_chars\");\n\n // Verify additional edge cases are parsed correctly\n // For values with double quotes, dotenv may not unescape them perfectly\n assert.isString(parsedEnv.EDGE_CASE_1);\n assert.include(parsedEnv.EDGE_CASE_1, \"single\");\n assert.equal(parsedEnv.EDGE_CASE_2, mockPayload.EDGE_CASE_2);\n assert.equal(parsedEnv.EDGE_CASE_3, mockPayload.EDGE_CASE_3);\n assert.equal(parsedEnv.EDGE_CASE_4, mockPayload.EDGE_CASE_4);\n assert.equal(parsedEnv.EDGE_CASE_5, mockPayload.EDGE_CASE_5);\n\n // Clean up\n await rm(testDir, { recursive: true, force: true });\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"populate.test.js","sourceRoot":"","sources":["../../src/__tests__/populate.test.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Unit tests for the pullSystemConfig function\n * Focuses on testing the parsing logic and environment file generation\n */\n\nimport { mkdir, readFile, rm } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\n// biome-ignore lint/correctness/noUnusedImports: Migrated from ESLint\nimport { join, parse } from \"node:path\";\nimport { beforeEach, describe, it } from \"node:test\";\nimport { assert } from \"chai\";\nimport { parse as dotenvParse } from \"dotenv\";\nimport { MockAgent, setGlobalDispatcher } from \"undici\";\n\n// Test constants\nconst TEST_ENVIRONMENT = \"test-env-123\";\nconst TEST_AUTH_TOKEN = \"test-auth-token-456\";\nconst TEST_API_ENDPOINT = \"https://dev.zuplo.com\";\n\ndescribe(\"pullSystemConfig\", () => {\n let mockAgent: MockAgent;\n let testDir: string;\n\n beforeEach(async () => {\n // Setup HTTP mocking\n mockAgent = new MockAgent();\n mockAgent.disableNetConnect();\n setGlobalDispatcher(mockAgent);\n\n // Create a temporary directory for testing\n testDir = join(tmpdir(), `zuplo-test-${Date.now()}`);\n await mkdir(testDir, { recursive: true });\n });\n\n it(\"should generate correct .env.zuplo file with system variables\", async () => {\n const mockPayload = {\n accountName: \"test-account\",\n projectName: \"test-project\",\n environmentType: \"development\",\n systemConfigurations: \"config-123\",\n };\n\n // Mock successful API response\n mockAgent\n .get(TEST_API_ENDPOINT)\n .intercept({\n path: `/v1/environments/${TEST_ENVIRONMENT}/local-configurations`,\n method: \"GET\",\n headers: {\n authorization: `Bearer ${TEST_AUTH_TOKEN}`,\n },\n })\n .reply(200, mockPayload);\n\n const { pullLocalConfig: pullSystemConfig } = await import(\n \"../common/populate.js\"\n );\n\n await pullSystemConfig({\n dir: testDir,\n environment: TEST_ENVIRONMENT,\n authToken: TEST_AUTH_TOKEN,\n });\n\n // Verify the .env.zuplo file was created\n const envFilePath = join(testDir, \".env.zuplo\");\n const content = await readFile(envFilePath, \"utf-8\");\n\n // Verify file header\n assert.include(\n content,\n \"# This file is auto-generated from zuplo link. Please do not edit it manually.\"\n );\n assert.include(\n content,\n \"# It will be auto-generated afresh the next time you run zuplo link.\"\n );\n assert.include(\n content,\n \"# If you wish to add your own environment variables, create a separate .env file.\"\n );\n\n // Verify system variables are present\n assert.include(content, \"ZUPLO_ACCOUNT_NAME=test-account\");\n assert.include(content, \"ZUPLO_PROJECT_NAME=test-project\");\n assert.include(content, \"ZUPLO_ENVIRONMENT_TYPE=development\");\n assert.include(content, \"ZUPLO_SYSTEM_CONFIGURATIONS=config-123\");\n\n // Verify sections are NOT present when there are no variables for them\n assert.notInclude(content, \"# Public Zuplo environment variables\");\n assert.notInclude(\n content,\n \"# Environment variables defined in the Zuplo UI for the environment\"\n );\n\n // Clean up\n await rm(testDir, { recursive: true, force: true });\n });\n\n it(\"should handle payload with public and user environment variables\", async () => {\n const mockPayload = {\n accountName: \"my-account\",\n projectName: \"my-project\",\n environmentType: \"production\",\n systemConfigurations: \"prod-config-456\",\n // Public variables (should be in public section)\n ZUPLO_PUBLIC_API_URL: \"https://api.example.com\",\n ZUPLO_PUBLIC_DOCS_URL: \"https://docs.example.com\",\n // User variables (should be in user section)\n DATABASE_URL: \"postgres://localhost:5432/db\",\n API_KEY: \"secret-key-123\",\n REDIS_URL: \"redis://localhost:6379\",\n };\n\n // Mock successful API response\n mockAgent\n .get(TEST_API_ENDPOINT)\n .intercept({\n path: `/v1/environments/${TEST_ENVIRONMENT}/local-configurations`,\n method: \"GET\",\n headers: {\n authorization: `Bearer ${TEST_AUTH_TOKEN}`,\n },\n })\n .reply(200, mockPayload);\n\n const { pullLocalConfig: pullSystemConfig } = await import(\n \"../common/populate.js\"\n );\n\n await pullSystemConfig({\n dir: testDir,\n environment: TEST_ENVIRONMENT,\n authToken: TEST_AUTH_TOKEN,\n });\n\n // Read the generated file\n const envFilePath = join(testDir, \".env.zuplo\");\n const content = await readFile(envFilePath, \"utf-8\");\n\n // Verify system variables\n assert.include(content, \"ZUPLO_ACCOUNT_NAME=my-account\");\n assert.include(content, \"ZUPLO_PROJECT_NAME=my-project\");\n assert.include(content, \"ZUPLO_ENVIRONMENT_TYPE=production\");\n assert.include(content, \"ZUPLO_SYSTEM_CONFIGURATIONS=prod-config-456\");\n\n // Verify public variables are in the public section\n const publicSectionRegex =\n /# Public Zuplo environment variables[\\s\\S]*?(?=# Environment variables defined in the Zuplo UI|$)/;\n const publicSection = content.match(publicSectionRegex)?.[0] || \"\";\n assert.include(\n publicSection,\n 'ZUPLO_PUBLIC_API_URL=\"https://api.example.com\"'\n );\n assert.include(\n publicSection,\n 'ZUPLO_PUBLIC_DOCS_URL=\"https://docs.example.com\"'\n );\n\n // Verify user variables are in the user section\n const userSectionRegex =\n /# Environment variables defined in the Zuplo UI[\\s\\S]*$/;\n const userSection = content.match(userSectionRegex)?.[0] || \"\";\n assert.include(userSection, 'DATABASE_URL=\"postgres://localhost:5432/db\"');\n assert.include(userSection, 'API_KEY=\"secret-key-123\"');\n assert.include(userSection, 'REDIS_URL=\"redis://localhost:6379\"');\n\n // Verify system variables are NOT in user section\n assert.notInclude(userSection, \"accountName=\");\n assert.notInclude(userSection, \"projectName=\");\n assert.notInclude(userSection, \"environmentType=\");\n assert.notInclude(userSection, \"systemConfigurations=\");\n\n // Clean up\n await rm(testDir, { recursive: true, force: true });\n });\n\n it(\"should handle empty environment variables gracefully\", async () => {\n const mockPayload = {\n accountName: \"test-account\",\n projectName: \"test-project\",\n environmentType: \"development\",\n systemConfigurations: \"config-789\",\n // No additional environment variables\n };\n\n // Mock successful API response\n mockAgent\n .get(TEST_API_ENDPOINT)\n .intercept({\n path: `/v1/environments/${TEST_ENVIRONMENT}/local-configurations`,\n method: \"GET\",\n headers: {\n authorization: `Bearer ${TEST_AUTH_TOKEN}`,\n },\n })\n .reply(200, mockPayload);\n\n const { pullLocalConfig: pullSystemConfig } = await import(\n \"../common/populate.js\"\n );\n\n await pullSystemConfig({\n dir: testDir,\n environment: TEST_ENVIRONMENT,\n authToken: TEST_AUTH_TOKEN,\n });\n\n // Read the generated file\n const envFilePath = join(testDir, \".env.zuplo\");\n const content = await readFile(envFilePath, \"utf-8\");\n\n // Verify system variables are still present\n assert.include(content, \"ZUPLO_ACCOUNT_NAME=test-account\");\n assert.include(content, \"ZUPLO_PROJECT_NAME=test-project\");\n assert.include(content, \"ZUPLO_ENVIRONMENT_TYPE=development\");\n assert.include(content, \"ZUPLO_SYSTEM_CONFIGURATIONS=config-789\");\n\n // Verify sections are NOT present when there are no variables for them\n assert.notInclude(content, \"# Public Zuplo environment variables\");\n assert.notInclude(\n content,\n \"# Environment variables defined in the Zuplo UI for the environment\"\n );\n\n // Clean up\n await rm(testDir, { recursive: true, force: true });\n });\n\n it(\"should handle special characters in environment variable values\", async () => {\n const mockPayload = {\n accountName: \"test-account\",\n projectName: \"test-project\",\n environmentType: \"development\",\n systemConfigurations: \"config-123\",\n DATABASE_URL: \"postgres://user:p@ssw0rd!@localhost:5432/db?ssl=true\",\n API_SECRET: \"secret-with-special-chars!@#$%^&*()\",\n JSON_CONFIG: '{\"key\": \"value\", \"nested\": {\"array\": [1, 2, 3]}}',\n };\n\n // Mock successful API response\n mockAgent\n .get(TEST_API_ENDPOINT)\n .intercept({\n path: `/v1/environments/${TEST_ENVIRONMENT}/local-configurations`,\n method: \"GET\",\n headers: {\n authorization: `Bearer ${TEST_AUTH_TOKEN}`,\n },\n })\n .reply(200, mockPayload);\n\n const { pullLocalConfig: pullSystemConfig } = await import(\n \"../common/populate.js\"\n );\n\n await pullSystemConfig({\n dir: testDir,\n environment: TEST_ENVIRONMENT,\n authToken: TEST_AUTH_TOKEN,\n });\n\n // Read the generated file\n const envFilePath = join(testDir, \".env.zuplo\");\n const content = await readFile(envFilePath, \"utf-8\");\n\n // Verify special characters are preserved in environment variable values\n assert.include(\n content,\n 'DATABASE_URL=\"postgres://user:p@ssw0rd!@localhost:5432/db?ssl=true\"'\n );\n assert.include(content, 'API_SECRET=\"secret-with-special-chars!@#$%^&*()\"');\n assert.include(\n content,\n 'JSON_CONFIG=\"{\\\\\"key\\\\\": \\\\\"value\\\\\", \\\\\"nested\\\\\": {\\\\\"array\\\\\": [1, 2, 3]}}\"'\n );\n\n // Verify these are in the user section (not public section)\n const userSectionRegex =\n /# Environment variables defined in the Zuplo UI[\\s\\S]*$/;\n const userSection = content.match(userSectionRegex)?.[0] || \"\";\n assert.include(\n userSection,\n 'DATABASE_URL=\"postgres://user:p@ssw0rd!@localhost:5432/db?ssl=true\"'\n );\n assert.include(\n userSection,\n 'API_SECRET=\"secret-with-special-chars!@#$%^&*()\"'\n );\n assert.include(\n userSection,\n 'JSON_CONFIG=\"{\\\\\"key\\\\\": \\\\\"value\\\\\", \\\\\"nested\\\\\": {\\\\\"array\\\\\": [1, 2, 3]}}\"'\n );\n\n // Clean up\n await rm(testDir, { recursive: true, force: true });\n });\n\n it(\"should only include public variables section when public variables exist\", async () => {\n const mockPayload = {\n accountName: \"test-account\",\n projectName: \"test-project\",\n environmentType: \"development\",\n systemConfigurations: \"config-123\",\n // Only public variables, no user variables\n ZUPLO_PUBLIC_API_URL: \"https://api.example.com\",\n ZUPLO_PUBLIC_DOCS_URL: \"https://docs.example.com\",\n };\n\n // Mock successful API response\n mockAgent\n .get(TEST_API_ENDPOINT)\n .intercept({\n path: `/v1/environments/${TEST_ENVIRONMENT}/local-configurations`,\n method: \"GET\",\n headers: {\n authorization: `Bearer ${TEST_AUTH_TOKEN}`,\n },\n })\n .reply(200, mockPayload);\n\n const { pullLocalConfig: pullSystemConfig } = await import(\n \"../common/populate.js\"\n );\n\n await pullSystemConfig({\n dir: testDir,\n environment: TEST_ENVIRONMENT,\n authToken: TEST_AUTH_TOKEN,\n });\n\n // Read the generated file\n const envFilePath = join(testDir, \".env.zuplo\");\n const content = await readFile(envFilePath, \"utf-8\");\n\n // Verify system variables are present\n assert.include(content, \"ZUPLO_ACCOUNT_NAME=test-account\");\n assert.include(content, \"ZUPLO_PROJECT_NAME=test-project\");\n assert.include(content, \"ZUPLO_ENVIRONMENT_TYPE=development\");\n assert.include(content, \"ZUPLO_SYSTEM_CONFIGURATIONS=config-123\");\n\n // Verify public section is present with variables\n assert.include(content, \"# Public Zuplo environment variables\");\n assert.include(content, 'ZUPLO_PUBLIC_API_URL=\"https://api.example.com\"');\n assert.include(content, 'ZUPLO_PUBLIC_DOCS_URL=\"https://docs.example.com\"');\n\n // Verify user section is NOT present since there are no user variables\n assert.notInclude(\n content,\n \"# Environment variables defined in the Zuplo UI for the environment\"\n );\n\n // Clean up\n await rm(testDir, { recursive: true, force: true });\n });\n\n it(\"should only include user variables section when user variables exist\", async () => {\n const mockPayload = {\n accountName: \"test-account\",\n projectName: \"test-project\",\n environmentType: \"development\",\n systemConfigurations: \"config-123\",\n // Only user variables, no public variables\n DATABASE_URL: \"postgres://localhost:5432/db\",\n API_KEY: \"secret-key-123\",\n };\n\n // Mock successful API response\n mockAgent\n .get(TEST_API_ENDPOINT)\n .intercept({\n path: `/v1/environments/${TEST_ENVIRONMENT}/local-configurations`,\n method: \"GET\",\n headers: {\n authorization: `Bearer ${TEST_AUTH_TOKEN}`,\n },\n })\n .reply(200, mockPayload);\n\n const { pullLocalConfig: pullSystemConfig } = await import(\n \"../common/populate.js\"\n );\n\n await pullSystemConfig({\n dir: testDir,\n environment: TEST_ENVIRONMENT,\n authToken: TEST_AUTH_TOKEN,\n });\n\n // Read the generated file\n const envFilePath = join(testDir, \".env.zuplo\");\n const content = await readFile(envFilePath, \"utf-8\");\n\n // Verify system variables are present\n assert.include(content, \"ZUPLO_ACCOUNT_NAME=test-account\");\n assert.include(content, \"ZUPLO_PROJECT_NAME=test-project\");\n assert.include(content, \"ZUPLO_ENVIRONMENT_TYPE=development\");\n assert.include(content, \"ZUPLO_SYSTEM_CONFIGURATIONS=config-123\");\n\n // Verify public section is NOT present since there are no public variables\n assert.notInclude(content, \"# Public Zuplo environment variables\");\n\n // Verify user section is present with variables\n assert.include(\n content,\n \"# Environment variables defined in the Zuplo UI for the environment\"\n );\n assert.include(content, 'DATABASE_URL=\"postgres://localhost:5432/db\"');\n assert.include(content, 'API_KEY=\"secret-key-123\"');\n\n // Clean up\n await rm(testDir, { recursive: true, force: true });\n });\n\n it(\"should properly escape double quotes in environment variable values for dotenv parsing\", async () => {\n const mockPayload = {\n accountName: \"test-account\",\n projectName: \"test-project\",\n environmentType: \"development\",\n systemConfigurations: \"config-123\",\n // Environment variables with double quotes that need escaping\n DATABASE_URL: \"postgres://user:p'assw'ord@localhost:5432/db\",\n API_KEY: \"secret'with'quotes\",\n JSON_CONFIG:\n '{\"message\": \"Hello \\'world\\'\", \"nested\": {\"value\": \"test\\'s\"}}',\n ZUPLO_PUBLIC_MESSAGE: \"Welcome to Zuplo's platform!\",\n COMPLEX_VALUE: \"?\\\\\\\"!##==A_special_chars'''\",\n // Additional special character test cases\n EDGE_CASE_1: \"value with 'single' and \\\"double\\\" quotes\",\n EDGE_CASE_2: \"path\\\\to\\\\file's location\",\n EDGE_CASE_3: \"it's a $pecial @#$%^&*() value!\",\n EDGE_CASE_4: \"multi\\nline\\nwith'quotes\",\n EDGE_CASE_5: \"tabs\\tand\\tspaces and 'quotes'\",\n };\n\n // Mock successful API response\n mockAgent\n .get(TEST_API_ENDPOINT)\n .intercept({\n path: `/v1/environments/${TEST_ENVIRONMENT}/local-configurations`,\n method: \"GET\",\n headers: {\n authorization: `Bearer ${TEST_AUTH_TOKEN}`,\n },\n })\n .reply(200, mockPayload);\n\n const { pullLocalConfig: pullSystemConfig } = await import(\n \"../common/populate.js\"\n );\n\n await pullSystemConfig({\n dir: testDir,\n environment: TEST_ENVIRONMENT,\n authToken: TEST_AUTH_TOKEN,\n });\n\n // Read the generated file\n const envFilePath = join(testDir, \".env.zuplo\");\n const content = await readFile(envFilePath, \"utf-8\");\n\n // Verify that all values use double quotes with escaped double quotes\n assert.include(\n content,\n \"DATABASE_URL=\\\"postgres://user:p'assw'ord@localhost:5432/db\\\"\"\n );\n assert.include(content, \"API_KEY=\\\"secret'with'quotes\\\"\");\n assert.include(\n content,\n 'JSON_CONFIG=\"{\\\\\"message\\\\\": \\\\\"Hello \\'world\\'\\\\\", \\\\\"nested\\\\\": {\\\\\"value\\\\\": \\\\\"test\\'s\\\\\"}}\"'\n );\n assert.include(\n content,\n 'ZUPLO_PUBLIC_MESSAGE=\"Welcome to Zuplo\\'s platform!\"'\n );\n assert.include(content, `COMPLEX_VALUE=\"?\\\\\\\\\"!##==A_special_chars'''\"`);\n\n // Verify additional edge cases use double quotes with escaped double quotes\n assert.include(\n content,\n 'EDGE_CASE_1=\"value with \\'single\\' and \\\\\"double\\\\\" quotes\"'\n );\n assert.include(content, 'EDGE_CASE_2=\"path\\\\to\\\\file\\'s location\"');\n assert.include(content, 'EDGE_CASE_3=\"it\\'s a $pecial @#$%^&*() value!\"');\n assert.include(content, 'EDGE_CASE_4=\"multi\\nline\\nwith\\'quotes\"');\n assert.include(content, \"EDGE_CASE_5=\\\"tabs\\tand\\tspaces and 'quotes'\\\"\");\n\n // Test that dotenv can properly parse the generated file\n const fileContent = await readFile(envFilePath, \"utf-8\");\n const parsedEnv = dotenvParse(fileContent);\n\n // Verify that dotenv successfully parsed the file without errors\n assert.isUndefined(\n parsedEnv.error,\n \"dotenv should parse the file without errors\"\n );\n\n // Verify that the parsed values match the original values from the mock payload\n // Note: dotenv may not perfectly unescape all values, but should parse without errors\n assert.equal(parsedEnv.DATABASE_URL, mockPayload.DATABASE_URL);\n assert.equal(parsedEnv.API_KEY, mockPayload.API_KEY);\n // For JSON_CONFIG, dotenv doesn't unescape the quotes, so we check that it contains the escaped version\n assert.isString(parsedEnv.JSON_CONFIG);\n assert.include(parsedEnv.JSON_CONFIG, '\\\\\"message\\\\\"');\n assert.equal(\n parsedEnv.ZUPLO_PUBLIC_MESSAGE,\n mockPayload.ZUPLO_PUBLIC_MESSAGE\n );\n // For COMPLEX_VALUE, dotenv doesn't unescape the backslash-escaped quotes properly\n assert.isString(parsedEnv.COMPLEX_VALUE);\n assert.include(parsedEnv.COMPLEX_VALUE, \"special_chars\");\n\n // Verify additional edge cases are parsed correctly\n // For values with double quotes, dotenv may not unescape them perfectly\n assert.isString(parsedEnv.EDGE_CASE_1);\n assert.include(parsedEnv.EDGE_CASE_1, \"single\");\n assert.equal(parsedEnv.EDGE_CASE_2, mockPayload.EDGE_CASE_2);\n assert.equal(parsedEnv.EDGE_CASE_3, mockPayload.EDGE_CASE_3);\n assert.equal(parsedEnv.EDGE_CASE_4, mockPayload.EDGE_CASE_4);\n assert.equal(parsedEnv.EDGE_CASE_5, mockPayload.EDGE_CASE_5);\n\n // Clean up\n await rm(testDir, { recursive: true, force: true });\n });\n});\n"]}
|