@zuplo/cli 6.69.5 → 6.69.8
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__/integration/confirm-production-deploy.integration.test.d.ts +2 -0
- package/dist/__tests__/integration/confirm-production-deploy.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/confirm-production-deploy.integration.test.js +184 -0
- package/dist/__tests__/integration/confirm-production-deploy.integration.test.js.map +1 -0
- package/dist/__tests__/integration/custom-domain.integration.test.js +4 -4
- package/dist/__tests__/integration/custom-domain.integration.test.js.map +1 -1
- package/dist/__tests__/integration/deploy.integration.test.js +1 -0
- package/dist/__tests__/integration/deploy.integration.test.js.map +1 -1
- package/dist/__tests__/integration/jest-mocks-setup.js +4 -0
- package/dist/__tests__/integration/jest-mocks-setup.js.map +1 -1
- package/dist/__tests__/integration/list.integration.test.js +2 -2
- package/dist/__tests__/integration/list.integration.test.js.map +1 -1
- package/dist/__tests__/integration/tunnel.integration.test.js +14 -14
- package/dist/__tests__/integration/tunnel.integration.test.js.map +1 -1
- package/dist/__tests__/integration/variable.integration.test.js +4 -4
- package/dist/__tests__/integration/variable.integration.test.js.map +1 -1
- package/dist/__tests__/integration/whoami.integration.test.js +29 -5
- package/dist/__tests__/integration/whoami.integration.test.js.map +1 -1
- package/dist/bucket/list/handler.d.ts +8 -0
- package/dist/bucket/list/handler.d.ts.map +1 -0
- package/dist/bucket/list/handler.js +54 -0
- package/dist/bucket/list/handler.js.map +1 -0
- package/dist/bucket/models.d.ts +23 -0
- package/dist/bucket/models.d.ts.map +1 -0
- package/dist/bucket/models.js +2 -0
- package/dist/bucket/models.js.map +1 -0
- package/dist/cli.js +16 -6
- package/dist/cli.js.map +1 -1
- package/dist/cmds/bucket/index.d.ts +4 -0
- package/dist/cmds/bucket/index.d.ts.map +1 -0
- package/dist/cmds/bucket/index.js +9 -0
- package/dist/cmds/bucket/index.js.map +1 -0
- package/dist/cmds/bucket/list.d.ts +9 -0
- package/dist/cmds/bucket/list.d.ts.map +1 -0
- package/dist/cmds/bucket/list.js +60 -0
- package/dist/cmds/bucket/list.js.map +1 -0
- package/dist/cmds/deploy.d.ts.map +1 -1
- package/dist/cmds/deploy.js +4 -1
- package/dist/cmds/deploy.js.map +1 -1
- package/dist/cmds/logout.d.ts +9 -0
- package/dist/cmds/logout.d.ts.map +1 -0
- package/dist/cmds/logout.js +23 -0
- package/dist/cmds/logout.js.map +1 -0
- package/dist/cmds/whoami.d.ts.map +1 -1
- package/dist/cmds/whoami.js +1 -2
- package/dist/cmds/whoami.js.map +1 -1
- package/dist/common/api/client.d.ts +40 -0
- package/dist/common/api/client.d.ts.map +1 -0
- package/dist/common/api/client.js +92 -0
- package/dist/common/api/client.js.map +1 -0
- package/dist/common/middleware/confirm-production-deploy.d.ts +4 -0
- package/dist/common/middleware/confirm-production-deploy.d.ts.map +1 -0
- package/dist/common/middleware/confirm-production-deploy.js +49 -0
- package/dist/common/middleware/confirm-production-deploy.js.map +1 -0
- package/dist/common/middleware/get-environment-param.d.ts +6 -0
- package/dist/common/middleware/get-environment-param.d.ts.map +1 -1
- package/dist/common/middleware/get-environment-param.js +15 -0
- package/dist/common/middleware/get-environment-param.js.map +1 -1
- package/dist/common/middleware/get-environment-param.test.d.ts +2 -0
- package/dist/common/middleware/get-environment-param.test.d.ts.map +1 -0
- package/dist/common/middleware/get-environment-param.test.js +33 -0
- package/dist/common/middleware/get-environment-param.test.js.map +1 -0
- package/dist/common/output.d.ts +7 -0
- package/dist/common/output.d.ts.map +1 -1
- package/dist/common/output.js +15 -1
- package/dist/common/output.js.map +1 -1
- package/dist/common/read-linked-config.d.ts +6 -1
- package/dist/common/read-linked-config.d.ts.map +1 -1
- package/dist/common/read-linked-config.js +14 -4
- package/dist/common/read-linked-config.js.map +1 -1
- package/dist/common/read-linked-config.test.js +97 -0
- package/dist/common/read-linked-config.test.js.map +1 -1
- package/dist/custom-domain/create/handler.d.ts.map +1 -1
- package/dist/custom-domain/create/handler.js +12 -27
- package/dist/custom-domain/create/handler.js.map +1 -1
- package/dist/custom-domain/delete/handler.d.ts.map +1 -1
- package/dist/custom-domain/delete/handler.js +25 -54
- package/dist/custom-domain/delete/handler.js.map +1 -1
- package/dist/custom-domain/list/handler.d.ts.map +1 -1
- package/dist/custom-domain/list/handler.js +15 -29
- package/dist/custom-domain/list/handler.js.map +1 -1
- package/dist/custom-domain/update/handler.d.ts.map +1 -1
- package/dist/custom-domain/update/handler.js +12 -27
- package/dist/custom-domain/update/handler.js.map +1 -1
- package/dist/deploy/environments.d.ts +1 -0
- package/dist/deploy/environments.d.ts.map +1 -1
- package/dist/deploy/environments.js +11 -7
- package/dist/deploy/environments.js.map +1 -1
- package/dist/list/handler.d.ts.map +1 -1
- package/dist/list/handler.js +41 -59
- package/dist/list/handler.js.map +1 -1
- package/dist/login/logout.d.ts +5 -0
- package/dist/login/logout.d.ts.map +1 -0
- package/dist/login/logout.js +6 -0
- package/dist/login/logout.js.map +1 -0
- package/dist/login/tokens.d.ts +1 -0
- package/dist/login/tokens.d.ts.map +1 -1
- package/dist/login/tokens.js +16 -1
- package/dist/login/tokens.js.map +1 -1
- package/dist/mtls-certificates/create/handler.d.ts.map +1 -1
- package/dist/mtls-certificates/create/handler.js +9 -23
- package/dist/mtls-certificates/create/handler.js.map +1 -1
- package/dist/mtls-certificates/delete/handler.d.ts.map +1 -1
- package/dist/mtls-certificates/delete/handler.js +8 -20
- package/dist/mtls-certificates/delete/handler.js.map +1 -1
- package/dist/mtls-certificates/describe/handler.d.ts.map +1 -1
- package/dist/mtls-certificates/describe/handler.js +17 -31
- package/dist/mtls-certificates/describe/handler.js.map +1 -1
- package/dist/mtls-certificates/disable/handler.d.ts.map +1 -1
- package/dist/mtls-certificates/disable/handler.js +9 -26
- package/dist/mtls-certificates/disable/handler.js.map +1 -1
- package/dist/mtls-certificates/list/handler.d.ts.map +1 -1
- package/dist/mtls-certificates/list/handler.js +22 -36
- package/dist/mtls-certificates/list/handler.js.map +1 -1
- package/dist/mtls-certificates/update/handler.d.ts.map +1 -1
- package/dist/mtls-certificates/update/handler.js +14 -29
- package/dist/mtls-certificates/update/handler.js.map +1 -1
- package/dist/proxies/create/handler.d.ts.map +1 -1
- package/dist/proxies/create/handler.js +9 -22
- package/dist/proxies/create/handler.js.map +1 -1
- package/dist/proxies/delete/handler.d.ts.map +1 -1
- package/dist/proxies/delete/handler.js +8 -21
- package/dist/proxies/delete/handler.js.map +1 -1
- package/dist/proxies/describe/handler.d.ts.map +1 -1
- package/dist/proxies/describe/handler.js +7 -22
- package/dist/proxies/describe/handler.js.map +1 -1
- package/dist/proxies/update/handler.d.ts.map +1 -1
- package/dist/proxies/update/handler.js +9 -22
- package/dist/proxies/update/handler.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/tunnel/create/handler.d.ts.map +1 -1
- package/dist/tunnel/create/handler.js +8 -22
- package/dist/tunnel/create/handler.js.map +1 -1
- package/dist/tunnel/delete/handler.d.ts.map +1 -1
- package/dist/tunnel/delete/handler.js +16 -30
- package/dist/tunnel/delete/handler.js.map +1 -1
- package/dist/tunnel/describe/handler.d.ts.map +1 -1
- package/dist/tunnel/describe/handler.js +7 -21
- package/dist/tunnel/describe/handler.js.map +1 -1
- package/dist/tunnel/list/handler.d.ts.map +1 -1
- package/dist/tunnel/list/handler.js +13 -28
- package/dist/tunnel/list/handler.js.map +1 -1
- package/dist/tunnel/rotate-token/handler.d.ts.map +1 -1
- package/dist/tunnel/rotate-token/handler.js +7 -21
- package/dist/tunnel/rotate-token/handler.js.map +1 -1
- package/dist/tunnel/services/describe/handler.d.ts.map +1 -1
- package/dist/tunnel/services/describe/handler.js +7 -21
- package/dist/tunnel/services/describe/handler.js.map +1 -1
- package/dist/tunnel/services/update/handler.d.ts.map +1 -1
- package/dist/tunnel/services/update/handler.js +18 -32
- package/dist/tunnel/services/update/handler.js.map +1 -1
- package/dist/variable/create/handler.d.ts.map +1 -1
- package/dist/variable/create/handler.js +9 -24
- package/dist/variable/create/handler.js.map +1 -1
- package/dist/variable/update/handler.d.ts.map +1 -1
- package/dist/variable/update/handler.js +9 -24
- package/dist/variable/update/handler.js.map +1 -1
- package/dist/whoami/handler.d.ts +1 -1
- package/dist/whoami/handler.d.ts.map +1 -1
- package/dist/whoami/handler.js +12 -17
- package/dist/whoami/handler.js.map +1 -1
- package/node_modules/@zuplo/core/customer.cli.minified.js +225 -211
- package/node_modules/@zuplo/core/index.minified.js +237 -223
- package/node_modules/@zuplo/core/package.json +1 -1
- package/node_modules/@zuplo/editor/node_modules/find-my-way/.github/workflows/node.js.yml +1 -1
- package/node_modules/@zuplo/editor/node_modules/find-my-way/README.md +10 -0
- package/node_modules/@zuplo/editor/node_modules/find-my-way/index.d.ts +6 -0
- package/node_modules/@zuplo/editor/node_modules/find-my-way/index.js +37 -4
- package/node_modules/@zuplo/editor/node_modules/find-my-way/lib/handler-storage.js +2 -2
- package/node_modules/@zuplo/editor/node_modules/find-my-way/package.json +3 -3
- package/node_modules/@zuplo/editor/node_modules/find-my-way/test/repro-issue-414.test.js +57 -0
- package/node_modules/@zuplo/editor/node_modules/find-my-way/test/types/router.test-d.ts +1 -0
- package/node_modules/@zuplo/graphql/package.json +1 -1
- package/node_modules/@zuplo/openapi-tools/package.json +1 -1
- package/node_modules/@zuplo/otel/package.json +1 -1
- package/node_modules/@zuplo/runtime/package.json +1 -1
- package/node_modules/graphql/index.d.ts +1 -0
- package/node_modules/graphql/language/ast.d.ts +10 -1
- package/node_modules/graphql/language/ast.js +8 -1
- package/node_modules/graphql/language/ast.mjs +8 -1
- package/node_modules/graphql/language/directiveLocation.d.ts +1 -0
- package/node_modules/graphql/language/directiveLocation.js +1 -0
- package/node_modules/graphql/language/directiveLocation.mjs +1 -0
- package/node_modules/graphql/language/index.d.ts +1 -0
- package/node_modules/graphql/language/kinds.d.ts +1 -0
- package/node_modules/graphql/language/kinds.js +1 -0
- package/node_modules/graphql/language/kinds.mjs +1 -0
- package/node_modules/graphql/language/parser.d.ts +14 -0
- package/node_modules/graphql/language/parser.js +33 -0
- package/node_modules/graphql/language/parser.mjs +33 -0
- package/node_modules/graphql/language/predicates.js +3 -1
- package/node_modules/graphql/language/predicates.mjs +5 -1
- package/node_modules/graphql/language/printer.js +13 -1
- package/node_modules/graphql/language/printer.mjs +13 -1
- package/node_modules/graphql/package.json +1 -1
- package/node_modules/graphql/type/directives.d.ts +9 -1
- package/node_modules/graphql/type/directives.js +10 -1
- package/node_modules/graphql/type/directives.mjs +10 -1
- package/node_modules/graphql/type/introspection.js +24 -1
- package/node_modules/graphql/type/introspection.mjs +24 -1
- package/node_modules/graphql/utilities/buildASTSchema.js +4 -0
- package/node_modules/graphql/utilities/buildASTSchema.mjs +4 -0
- package/node_modules/graphql/utilities/buildClientSchema.js +1 -0
- package/node_modules/graphql/utilities/buildClientSchema.mjs +1 -0
- package/node_modules/graphql/utilities/extendSchema.js +58 -3
- package/node_modules/graphql/utilities/extendSchema.mjs +58 -3
- package/node_modules/graphql/utilities/getIntrospectionQuery.d.ts +16 -0
- package/node_modules/graphql/utilities/getIntrospectionQuery.js +31 -38
- package/node_modules/graphql/utilities/getIntrospectionQuery.mjs +31 -38
- package/node_modules/graphql/utilities/introspectionFromSchema.js +1 -0
- package/node_modules/graphql/utilities/introspectionFromSchema.mjs +1 -0
- package/node_modules/graphql/utilities/printSchema.js +1 -0
- package/node_modules/graphql/utilities/printSchema.mjs +1 -0
- package/node_modules/graphql/utilities/valueFromAST.js +12 -2
- package/node_modules/graphql/utilities/valueFromAST.mjs +12 -2
- package/node_modules/graphql/validation/rules/KnownDirectivesRule.js +4 -0
- package/node_modules/graphql/validation/rules/KnownDirectivesRule.mjs +4 -0
- package/node_modules/graphql/validation/rules/UniqueDirectivesPerLocationRule.js +12 -0
- package/node_modules/graphql/validation/rules/UniqueDirectivesPerLocationRule.mjs +12 -0
- package/node_modules/graphql/version.js +3 -3
- package/node_modules/graphql/version.mjs +3 -3
- package/package.json +6 -6
|
@@ -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\" />\n\nimport nock from \"nock\";\nimport tmp from \"tmp\";\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 not found\", async () => {\n const tunnelId = \"test-tunnel-123\";\n const configFile = \"/nonexistent/config.json\";\n\n // This test will fail during argument validation when file doesn't exist\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(\"--configuration-file: File not found:\");\n });\n\n it(\"should handle services update API error\", async () => {\n const tunnelId = \"test-tunnel-123\";\n // Create a secure temporary config file for testing\n const fs = require(\"node:fs\");\n const tmpFile = tmp.fileSync({ postfix: \".json\" });\n fs.writeFileSync(tmpFile.fd, '{\"services\": []}');\n const tempConfigFile = tmpFile.name;\n\n try {\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 const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"tunnel-services-update-error-requests\"\n );\n } finally {\n // Clean up temp file\n try {\n if (tmpFile && typeof tmpFile.removeCallback === \"function\") {\n tmpFile.removeCallback();\n }\n } catch {\n // Ignore cleanup errors\n }\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\" />\n\nimport nock from \"nock\";\nimport tmp from \"tmp\";\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 expect(\n executeTunnelCommand(\"create\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-name\": testTunnelName,\n })\n ).rejects.toThrow(\"Failed to create tunnel for account\");\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 expect(\n executeTunnelCommand(\"list\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n })\n ).rejects.toThrow(\"Failed to list tunnels for account\");\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 expect(\n executeTunnelCommand(\"delete\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-id\": tunnelId,\n })\n ).rejects.toThrow(\"Failed to delete tunnel for account\");\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 expect(\n executeTunnelCommand(\"describe\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-id\": tunnelId,\n })\n ).rejects.toThrow(\"Failed to describe tunnel for account\");\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 expect(\n executeTunnelCommand(\"rotate-token\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-id\": tunnelId,\n })\n ).rejects.toThrow(\"Failed to rotate token for tunnel\");\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 expect(\n executeTunnelServicesCommand(\"describe\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-id\": tunnelId,\n })\n ).rejects.toThrow(\"Failed to describe services for tunnel\");\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 not found\", async () => {\n const tunnelId = \"test-tunnel-123\";\n const configFile = \"/nonexistent/config.json\";\n\n // This test will fail during argument validation when file doesn't exist\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(\"--configuration-file: File not found:\");\n });\n\n it(\"should handle services update API error\", async () => {\n const tunnelId = \"test-tunnel-123\";\n // Create a secure temporary config file for testing\n const fs = require(\"node:fs\");\n const tmpFile = tmp.fileSync({ postfix: \".json\" });\n fs.writeFileSync(tmpFile.fd, '{\"services\": []}');\n const tempConfigFile = tmpFile.name;\n\n try {\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 expect(\n executeTunnelServicesCommand(\"update\", {\n account: TEST_ACCOUNT_NAME,\n \"api-key\": TEST_AUTH_TOKEN,\n \"tunnel-id\": tunnelId,\n \"configuration-file\": tempConfigFile,\n })\n ).rejects.toThrow(\"Failed to update tunnel for account\");\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintDiagnostics).toHaveBeenCalled();\n\n const capturedRequests = requestCapture.getRequests();\n expect(capturedRequests).toMatchSnapshot(\n \"tunnel-services-update-error-requests\"\n );\n } finally {\n // Clean up temp file\n try {\n if (tmpFile && typeof tmpFile.removeCallback === \"function\") {\n tmpFile.removeCallback();\n }\n } catch {\n // Ignore cleanup errors\n }\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"]}
|
|
@@ -138,7 +138,7 @@ describe("Variable Command Integration Tests", () => {
|
|
|
138
138
|
scope.on("request", (req, interceptor, body) => {
|
|
139
139
|
requestCapture.capture(req, interceptor, body);
|
|
140
140
|
});
|
|
141
|
-
await executeVariableCommand("create", {
|
|
141
|
+
await expect(executeVariableCommand("create", {
|
|
142
142
|
account: TEST_ACCOUNT_NAME,
|
|
143
143
|
project: TEST_PROJECT_NAME,
|
|
144
144
|
"api-key": TEST_AUTH_TOKEN,
|
|
@@ -146,7 +146,7 @@ describe("Variable Command Integration Tests", () => {
|
|
|
146
146
|
value: testValue,
|
|
147
147
|
branch: testBranch,
|
|
148
148
|
"is-secret": false,
|
|
149
|
-
});
|
|
149
|
+
})).rejects.toThrow("Failed to create variable");
|
|
150
150
|
expect(scope.isDone()).toBe(true);
|
|
151
151
|
expect(mockPrintDiagnostics).toHaveBeenCalled();
|
|
152
152
|
const capturedRequests = requestCapture.getRequests();
|
|
@@ -205,14 +205,14 @@ describe("Variable Command Integration Tests", () => {
|
|
|
205
205
|
scope.on("request", (req, interceptor, body) => {
|
|
206
206
|
requestCapture.capture(req, interceptor, body);
|
|
207
207
|
});
|
|
208
|
-
await executeVariableCommand("update", {
|
|
208
|
+
await expect(executeVariableCommand("update", {
|
|
209
209
|
account: TEST_ACCOUNT_NAME,
|
|
210
210
|
project: TEST_PROJECT_NAME,
|
|
211
211
|
"api-key": TEST_AUTH_TOKEN,
|
|
212
212
|
name: testVariableName,
|
|
213
213
|
value: testValue,
|
|
214
214
|
branch: testBranch,
|
|
215
|
-
});
|
|
215
|
+
})).rejects.toThrow("Failed to update variable");
|
|
216
216
|
expect(scope.isDone()).toBe(true);
|
|
217
217
|
expect(mockPrintDiagnostics).toHaveBeenCalled();
|
|
218
218
|
const capturedRequests = requestCapture.getRequests();
|
|
@@ -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 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
|
+
{"version":3,"file":"variable.integration.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/variable.integration.test.ts"],"names":[],"mappings":"AAIA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,KAAK,MAAM,aAAa,CAAC;AAChC,OAAO,eAAe,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EACL,WAAW,EACX,cAAc,EACd,sBAAsB,EACtB,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AAKzB,KAAK,UAAU,sBAAsB,CACnC,UAA+B,EAC/B,IAQC;IAED,MAAM,aAAa,GAAG,KAAK,CAAC,EAAE,CAAC;SAC5B,OAAO,CAAC,eAAe,CAAC;SACxB,IAAI,CAAC,KAAK,CAAC;SACX,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,KAAK,CAAC,CAAC;IAGtB,MAAM,WAAW,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IAE7C,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,WAAW,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC;IAED,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,WAAW,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC;IAED,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QACpB,WAAW,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IACjD,CAAC;IAED,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IACxC,WAAW,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAE1C,IAAI,UAAU,KAAK,QAAQ,EAAE,CAAC;QAE5B,IAAI,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YACtB,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAClC,CAAC;aAAM,CAAC;YACN,WAAW,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAGD,OAAO,MAAM,aAAa,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;AAChD,CAAC;AAGD,MAAM,eAAe,GAAG,IAAI,CAAC,MAAM,CACjC,OAAO,CAAC,wBAAwB,CAAC,CAAC,oBAAoB,CACvD,CAAC;AACF,MAAM,oBAAoB,GAAG,IAAI,CAAC,MAAM,CACtC,OAAO,CAAC,wBAAwB,CAAC,CAAC,yBAAyB,CAC5D,CAAC;AAEF,QAAQ,CAAC,oCAAoC,EAAE,GAAG,EAAE;IAClD,IAAI,cAA8B,CAAC;IAEnC,UAAU,CAAC,GAAG,EAAE;QACd,oBAAoB,EAAE,CAAC;QACvB,cAAc,GAAG,IAAI,cAAc,EAAE,CAAC;QAGtC,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAGzB,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,WAAW,EAAE,CAAC;QACd,cAAc,CAAC,KAAK,EAAE,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACvC,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;YAChE,MAAM,UAAU,GAAG,MAAM,CAAC;YAC1B,MAAM,gBAAgB,GAAG,SAAS,CAAC;YACnC,MAAM,SAAS,GAAG,yBAAyB,CAAC;YAC5C,MAAM,YAAY,GAAG;gBACnB,IAAI,EAAE,gBAAgB;gBACtB,WAAW,EAAE,KAAK;gBAClB,KAAK,EAAE,SAAS;gBAChB,MAAM,EAAE,UAAU;gBAClB,SAAS,EAAE,sBAAsB;gBACjC,SAAS,EAAE,sBAAsB;aAClC,CAAC;YAEF,MAAM,KAAK,GAAG,sBAAsB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;iBACtD,IAAI,CACH,gBAAgB,iBAAiB,aAAa,iBAAiB,aAAa,kBAAkB,CAAC,UAAU,CAAC,YAAY,CACvH;iBACA,KAAK,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;YAG5B,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE;gBAC7C,cAAc,CAAC,OAAO,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;YACjD,CAAC,CAAC,CAAC;YAGH,MAAM,sBAAsB,CAAC,QAAQ,EAAE;gBACrC,OAAO,EAAE,iBAAiB;gBAC1B,OAAO,EAAE,iBAAiB;gBAC1B,SAAS,EAAE,eAAe;gBAC1B,IAAI,EAAE,gBAAgB;gBACtB,KAAK,EAAE,SAAS;gBAChB,MAAM,EAAE,UAAU;gBAClB,WAAW,EAAE,KAAK;aACnB,CAAC,CAAC;YAGH,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAGlC,MAAM,CAAC,eAAe,CAAC,CAAC,oBAAoB,CAC1C,GAAG,gBAAgB,uBAAuB,CAC3C,CAAC;YAGF,MAAM,gBAAgB,GAAG,cAAc,CAAC,WAAW,EAAE,CAAC;YACtD,MAAM,CAAC,gBAAgB,CAAC,CAAC,eAAe,CAAC,0BAA0B,CAAC,CAAC;YAGrE,MAAM,OAAO,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;YACpC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACpC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;gBAC3B,IAAI,EAAE,gBAAgB;gBACtB,QAAQ,EAAE,KAAK;gBACf,KAAK,EAAE,SAAS;aACjB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;YACtD,MAAM,UAAU,GAAG,YAAY,CAAC;YAChC,MAAM,gBAAgB,GAAG,mBAAmB,CAAC;YAC7C,MAAM,SAAS,GAAG,uBAAuB,CAAC;YAC1C,MAAM,YAAY,GAAG;gBACnB,IAAI,EAAE,gBAAgB;gBACtB,WAAW,EAAE,IAAI;gBACjB,KAAK,EAAE,YAAY;gBACnB,MAAM,EAAE,UAAU;gBAClB,SAAS,EAAE,sBAAsB;gBACjC,SAAS,EAAE,sBAAsB;aAClC,CAAC;YAEF,MAAM,KAAK,GAAG,sBAAsB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;iBACtD,IAAI,CACH,gBAAgB,iBAAiB,aAAa,iBAAiB,aAAa,kBAAkB,CAAC,UAAU,CAAC,YAAY,CACvH;iBACA,KAAK,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;YAE5B,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE;gBAC7C,cAAc,CAAC,OAAO,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;YACjD,CAAC,CAAC,CAAC;YAEH,MAAM,sBAAsB,CAAC,QAAQ,EAAE;gBACrC,OAAO,EAAE,iBAAiB;gBAC1B,OAAO,EAAE,iBAAiB;gBAC1B,SAAS,EAAE,eAAe;gBAC1B,IAAI,EAAE,gBAAgB;gBACtB,KAAK,EAAE,SAAS;gBAChB,MAAM,EAAE,UAAU;gBAClB,WAAW,EAAE,IAAI;aAClB,CAAC,CAAC;YAEH,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM,CAAC,eAAe,CAAC,CAAC,oBAAoB,CAC1C,GAAG,gBAAgB,uBAAuB,CAC3C,CAAC;YAEF,MAAM,gBAAgB,GAAG,cAAc,CAAC,WAAW,EAAE,CAAC;YACtD,MAAM,CAAC,gBAAgB,CAAC,CAAC,eAAe,CACtC,iCAAiC,CAClC,CAAC;YAGF,MAAM,OAAO,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;YACpC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;gBAC3B,IAAI,EAAE,gBAAgB;gBACtB,QAAQ,EAAE,IAAI;gBACd,KAAK,EAAE,SAAS;aACjB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;YACrD,MAAM,UAAU,GAAG,MAAM,CAAC;YAC1B,MAAM,gBAAgB,GAAG,aAAa,CAAC;YACvC,MAAM,SAAS,GAAG,YAAY,CAAC;YAC/B,MAAM,aAAa,GAAG;gBACpB,KAAK,EAAE,aAAa;gBACpB,OAAO,EAAE,8BAA8B;gBACvC,UAAU,EAAE,GAAG;aAChB,CAAC;YAEF,MAAM,KAAK,GAAG,sBAAsB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;iBACtD,IAAI,CACH,gBAAgB,iBAAiB,aAAa,iBAAiB,aAAa,kBAAkB,CAAC,UAAU,CAAC,YAAY,CACvH;iBACA,KAAK,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;YAE7B,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE;gBAC7C,cAAc,CAAC,OAAO,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;YACjD,CAAC,CAAC,CAAC;YAEH,MAAM,MAAM,CACV,sBAAsB,CAAC,QAAQ,EAAE;gBAC/B,OAAO,EAAE,iBAAiB;gBAC1B,OAAO,EAAE,iBAAiB;gBAC1B,SAAS,EAAE,eAAe;gBAC1B,IAAI,EAAE,gBAAgB;gBACtB,KAAK,EAAE,SAAS;gBAChB,MAAM,EAAE,UAAU;gBAClB,WAAW,EAAE,KAAK;aACnB,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;YAE/C,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM,CAAC,oBAAoB,CAAC,CAAC,gBAAgB,EAAE,CAAC;YAEhD,MAAM,gBAAgB,GAAG,cAAc,CAAC,WAAW,EAAE,CAAC;YACtD,MAAM,CAAC,gBAAgB,CAAC,CAAC,eAAe,CACtC,gCAAgC,CACjC,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACvC,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;YACjE,MAAM,UAAU,GAAG,MAAM,CAAC;YAC1B,MAAM,gBAAgB,GAAG,SAAS,CAAC;YACnC,MAAM,SAAS,GAAG,4BAA4B,CAAC;YAC/C,MAAM,YAAY,GAAG;gBACnB,IAAI,EAAE,gBAAgB;gBACtB,WAAW,EAAE,KAAK;gBAClB,KAAK,EAAE,SAAS;gBAChB,MAAM,EAAE,UAAU;gBAClB,SAAS,EAAE,sBAAsB;gBACjC,SAAS,EAAE,sBAAsB;aAClC,CAAC;YAEF,MAAM,KAAK,GAAG,sBAAsB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;iBACtD,KAAK,CACJ,gBAAgB,iBAAiB,aAAa,iBAAiB,aAAa,kBAAkB,CAAC,UAAU,CAAC,cAAc,kBAAkB,CAAC,gBAAgB,CAAC,EAAE,CAC/J;iBACA,KAAK,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;YAE5B,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE;gBAC7C,cAAc,CAAC,OAAO,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;YACjD,CAAC,CAAC,CAAC;YAEH,MAAM,sBAAsB,CAAC,QAAQ,EAAE;gBACrC,OAAO,EAAE,iBAAiB;gBAC1B,OAAO,EAAE,iBAAiB;gBAC1B,SAAS,EAAE,eAAe;gBAC1B,IAAI,EAAE,gBAAgB;gBACtB,KAAK,EAAE,SAAS;gBAChB,MAAM,EAAE,UAAU;aACnB,CAAC,CAAC;YAEH,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM,CAAC,eAAe,CAAC,CAAC,oBAAoB,CAC1C,GAAG,gBAAgB,uBAAuB,CAC3C,CAAC;YAEF,MAAM,gBAAgB,GAAG,cAAc,CAAC,WAAW,EAAE,CAAC;YACtD,MAAM,CAAC,gBAAgB,CAAC,CAAC,eAAe,CAAC,0BAA0B,CAAC,CAAC;YAGrE,MAAM,OAAO,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;YACpC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACrC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;gBAC3B,KAAK,EAAE,SAAS;aACjB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;YACtD,MAAM,UAAU,GAAG,MAAM,CAAC;YAC1B,MAAM,gBAAgB,GAAG,iBAAiB,CAAC;YAC3C,MAAM,SAAS,GAAG,WAAW,CAAC;YAC9B,MAAM,aAAa,GAAG;gBACpB,KAAK,EAAE,WAAW;gBAClB,OAAO,EAAE,oBAAoB;gBAC7B,UAAU,EAAE,GAAG;aAChB,CAAC;YAEF,MAAM,KAAK,GAAG,sBAAsB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;iBACtD,KAAK,CACJ,gBAAgB,iBAAiB,aAAa,iBAAiB,aAAa,kBAAkB,CAAC,UAAU,CAAC,cAAc,kBAAkB,CAAC,gBAAgB,CAAC,EAAE,CAC/J;iBACA,KAAK,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;YAE7B,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE;gBAC7C,cAAc,CAAC,OAAO,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;YACjD,CAAC,CAAC,CAAC;YAEH,MAAM,MAAM,CACV,sBAAsB,CAAC,QAAQ,EAAE;gBAC/B,OAAO,EAAE,iBAAiB;gBAC1B,OAAO,EAAE,iBAAiB;gBAC1B,SAAS,EAAE,eAAe;gBAC1B,IAAI,EAAE,gBAAgB;gBACtB,KAAK,EAAE,SAAS;gBAChB,MAAM,EAAE,UAAU;aACnB,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;YAE/C,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM,CAAC,oBAAoB,CAAC,CAAC,gBAAgB,EAAE,CAAC;YAEhD,MAAM,gBAAgB,GAAG,cAAc,CAAC,WAAW,EAAE,CAAC;YACtD,MAAM,CAAC,gBAAgB,CAAC,CAAC,eAAe,CACtC,gCAAgC,CACjC,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAClC,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;YAC/D,MAAM,UAAU,GAAG,MAAM,CAAC;YAC1B,MAAM,gBAAgB,GAAG,UAAU,CAAC;YACpC,MAAM,SAAS,GAAG,YAAY,CAAC;YAC/B,MAAM,YAAY,GAAG;gBACnB,IAAI,EAAE,gBAAgB;gBACtB,WAAW,EAAE,KAAK;gBAClB,KAAK,EAAE,SAAS;gBAChB,MAAM,EAAE,UAAU;gBAClB,SAAS,EAAE,sBAAsB;gBACjC,SAAS,EAAE,sBAAsB;aAClC,CAAC;YAEF,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC;iBAC9B,IAAI,CACH,gBAAgB,iBAAiB,aAAa,iBAAiB,aAAa,kBAAkB,CAAC,UAAU,CAAC,YAAY,CACvH;iBACA,WAAW,CAAC,eAAe,EAAE,UAAU,eAAe,EAAE,CAAC;iBACzD,WAAW,CAAC,cAAc,EAAE,kBAAkB,CAAC;iBAC/C,KAAK,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;YAE5B,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE;gBAC7C,cAAc,CAAC,OAAO,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;YACjD,CAAC,CAAC,CAAC;YAEH,MAAM,sBAAsB,CAAC,QAAQ,EAAE;gBACrC,OAAO,EAAE,iBAAiB;gBAC1B,OAAO,EAAE,iBAAiB;gBAC1B,SAAS,EAAE,eAAe;gBAC1B,IAAI,EAAE,gBAAgB;gBACtB,KAAK,EAAE,SAAS;gBAChB,MAAM,EAAE,UAAU;gBAClB,WAAW,EAAE,KAAK;aACnB,CAAC,CAAC;YAEH,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAElC,MAAM,gBAAgB,GAAG,cAAc,CAAC,WAAW,EAAE,CAAC;YACtD,MAAM,CAAC,gBAAgB,CAAC,CAAC,eAAe,CAAC,6BAA6B,CAAC,CAAC;QAC1E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","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 expect(\n 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 ).rejects.toThrow(\"Failed to create variable\");\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 expect(\n 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 ).rejects.toThrow(\"Failed to update variable\");\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,6 +1,7 @@
|
|
|
1
1
|
import nock from "nock";
|
|
2
2
|
import yargs from "yargs/yargs";
|
|
3
3
|
import whoamiCommand from "../../cmds/whoami.js";
|
|
4
|
+
import { getAuthToken } from "../../login/tokens.js";
|
|
4
5
|
import { cleanupTest, RequestCapture, setupAuthenticatedNock, setupTestEnvironment, TEST_API_BASE, TEST_AUTH_TOKEN, } from "./test-utils.js";
|
|
5
6
|
const TEST_SUB = "google-oauth2|123456789";
|
|
6
7
|
const TEST_EMAIL = "user@example.com";
|
|
@@ -75,18 +76,41 @@ describe("Whoami Command Integration Tests", () => {
|
|
|
75
76
|
expect(scope.isDone()).toBe(true);
|
|
76
77
|
expect(mockPrintResult).toHaveBeenCalledWith(`Authenticated as ${TEST_SUB}`);
|
|
77
78
|
});
|
|
79
|
+
it("should fall back to the stored auth token when --api-key is omitted", async () => {
|
|
80
|
+
const scope = setupAuthenticatedNock(nock(TEST_API_BASE))
|
|
81
|
+
.get("/v1/who-am-i")
|
|
82
|
+
.matchHeader("authorization", `Bearer ${TEST_AUTH_TOKEN}`)
|
|
83
|
+
.reply(200, { sub: TEST_SUB, email: TEST_EMAIL });
|
|
84
|
+
await executeWhoamiCommand({});
|
|
85
|
+
expect(scope.isDone()).toBe(true);
|
|
86
|
+
expect(jest.mocked(getAuthToken)).toHaveBeenCalled();
|
|
87
|
+
expect(mockPrintResult).toHaveBeenCalledWith(`Authenticated as ${TEST_EMAIL} (${TEST_SUB})`);
|
|
88
|
+
});
|
|
89
|
+
it("should fall back to the stored auth token when --api-key is empty", async () => {
|
|
90
|
+
const scope = setupAuthenticatedNock(nock(TEST_API_BASE))
|
|
91
|
+
.get("/v1/who-am-i")
|
|
92
|
+
.matchHeader("authorization", `Bearer ${TEST_AUTH_TOKEN}`)
|
|
93
|
+
.reply(200, { sub: TEST_SUB });
|
|
94
|
+
await executeWhoamiCommand({ "api-key": " " });
|
|
95
|
+
expect(scope.isDone()).toBe(true);
|
|
96
|
+
expect(jest.mocked(getAuthToken)).toHaveBeenCalled();
|
|
97
|
+
expect(mockPrintResult).toHaveBeenCalledWith(`Authenticated as ${TEST_SUB}`);
|
|
98
|
+
});
|
|
99
|
+
it("should report logged out when no auth token is available", async () => {
|
|
100
|
+
jest.mocked(getAuthToken).mockResolvedValueOnce(undefined);
|
|
101
|
+
await executeWhoamiCommand({});
|
|
102
|
+
expect(mockPrintResult).toHaveBeenCalledWith("You are logged out");
|
|
103
|
+
expect(mockPrintCriticalFailure).not.toHaveBeenCalled();
|
|
104
|
+
});
|
|
78
105
|
it("should fail when the API returns an error", async () => {
|
|
79
106
|
const scope = setupAuthenticatedNock(nock(TEST_API_BASE))
|
|
80
107
|
.get("/v1/who-am-i")
|
|
81
108
|
.reply(401, { error: "Unauthorized" });
|
|
82
|
-
mockPrintCriticalFailure.mockImplementationOnce(() => {
|
|
83
|
-
throw new Error("Process would exit");
|
|
84
|
-
});
|
|
85
109
|
await expect(executeWhoamiCommand({
|
|
86
110
|
"api-key": TEST_AUTH_TOKEN,
|
|
87
|
-
})).rejects.toThrow("
|
|
111
|
+
})).rejects.toThrow("Failed to determine current user");
|
|
88
112
|
expect(scope.isDone()).toBe(true);
|
|
89
|
-
expect(mockPrintCriticalFailure).toHaveBeenCalled();
|
|
113
|
+
expect(mockPrintCriticalFailure).not.toHaveBeenCalled();
|
|
90
114
|
});
|
|
91
115
|
});
|
|
92
116
|
//# sourceMappingURL=whoami.integration.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"whoami.integration.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/whoami.integration.test.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Integration tests for the whoami command\n */\n/// <reference types=\"jest\" />\nimport nock from \"nock\";\nimport yargs from \"yargs/yargs\";\nimport whoamiCommand from \"../../cmds/whoami.js\";\nimport {\n cleanupTest,\n RequestCapture,\n setupAuthenticatedNock,\n setupTestEnvironment,\n TEST_API_BASE,\n TEST_AUTH_TOKEN,\n} from \"./test-utils.js\";\n\nconst TEST_SUB = \"google-oauth2|123456789\";\nconst TEST_EMAIL = \"user@example.com\";\nconst TEST_ACCOUNT = \"chocolate-blizzard\";\n\nasync function executeWhoamiCommand(args: { \"api-key\"?: string }) {\n const yargsInstance = yargs([])\n .command(whoamiCommand)\n .help(false)\n .version(false)\n .exitProcess(false);\n\n const commandArgs = [\"whoami\"];\n\n if (args[\"api-key\"]) {\n commandArgs.push(\"--api-key\", args[\"api-key\"]);\n }\n\n return await yargsInstance.parse(commandArgs);\n}\n\nconst mockPrintResult = jest.mocked(\n require(\"../../common/output.js\").printResultToConsoleAndExitGracefully\n);\nconst mockPrintCriticalFailure = jest.mocked(\n require(\"../../common/output.js\").printCriticalFailureToConsoleAndExit\n);\n\ndescribe(\"Whoami Command Integration Tests\", () => {\n let requestCapture: RequestCapture;\n\n beforeEach(() => {\n setupTestEnvironment();\n nock.cleanAll();\n requestCapture = new RequestCapture();\n\n nock.disableNetConnect();\n\n jest.clearAllMocks();\n });\n\n afterEach(() => {\n cleanupTest();\n requestCapture.clear();\n });\n\n it(\"should print sub when only sub is returned\", async () => {\n setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\"/v1/who-am-i\")\n .reply(200, { sub: TEST_SUB });\n\n await executeWhoamiCommand({\n \"api-key\": TEST_AUTH_TOKEN,\n });\n\n expect(mockPrintResult).toHaveBeenCalledWith(\n `Authenticated as ${TEST_SUB}`\n );\n });\n\n it(\"should include email and account when returned\", async () => {\n setupAuthenticatedNock(nock(TEST_API_BASE)).get(\"/v1/who-am-i\").reply(200, {\n sub: TEST_SUB,\n email: TEST_EMAIL,\n account: TEST_ACCOUNT,\n });\n\n await executeWhoamiCommand({\n \"api-key\": TEST_AUTH_TOKEN,\n });\n\n expect(mockPrintResult).toHaveBeenCalledWith(\n `Authenticated as ${TEST_EMAIL} (${TEST_SUB})\\nAccount: ${TEST_ACCOUNT}`\n );\n });\n\n it(\"should include account without email when only account is returned\", async () => {\n setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\"/v1/who-am-i\")\n .reply(200, { sub: TEST_SUB, account: TEST_ACCOUNT });\n\n await executeWhoamiCommand({\n \"api-key\": TEST_AUTH_TOKEN,\n });\n\n expect(mockPrintResult).toHaveBeenCalledWith(\n `Authenticated as ${TEST_SUB}\\nAccount: ${TEST_ACCOUNT}`\n );\n });\n\n it(\"should include the authorization header\", async () => {\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\"/v1/who-am-i\")\n .matchHeader(\"authorization\", `Bearer ${TEST_AUTH_TOKEN}`)\n .reply(200, { sub: TEST_SUB });\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeWhoamiCommand({\n \"api-key\": TEST_AUTH_TOKEN,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintResult).toHaveBeenCalledWith(\n `Authenticated as ${TEST_SUB}`\n );\n });\n\n it(\"should fail when the API returns an error\", async () => {\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\"/v1/who-am-i\")\n .reply(401, { error: \"Unauthorized\" });\n\n mockPrintCriticalFailure.mockImplementationOnce(() => {\n throw new Error(\"Process would exit\");\n });\n\n await expect(\n executeWhoamiCommand({\n \"api-key\": TEST_AUTH_TOKEN,\n })\n ).rejects.toThrow(\"Process would exit\");\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintCriticalFailure).toHaveBeenCalled();\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"whoami.integration.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/whoami.integration.test.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Integration tests for the whoami command\n */\n/// <reference types=\"jest\" />\nimport nock from \"nock\";\nimport yargs from \"yargs/yargs\";\nimport whoamiCommand from \"../../cmds/whoami.js\";\nimport { getAuthToken } from \"../../login/tokens.js\";\nimport {\n cleanupTest,\n RequestCapture,\n setupAuthenticatedNock,\n setupTestEnvironment,\n TEST_API_BASE,\n TEST_AUTH_TOKEN,\n} from \"./test-utils.js\";\n\nconst TEST_SUB = \"google-oauth2|123456789\";\nconst TEST_EMAIL = \"user@example.com\";\nconst TEST_ACCOUNT = \"chocolate-blizzard\";\n\nasync function executeWhoamiCommand(args: { \"api-key\"?: string }) {\n const yargsInstance = yargs([])\n .command(whoamiCommand)\n .help(false)\n .version(false)\n .exitProcess(false);\n\n const commandArgs = [\"whoami\"];\n\n if (args[\"api-key\"]) {\n commandArgs.push(\"--api-key\", args[\"api-key\"]);\n }\n\n return await yargsInstance.parse(commandArgs);\n}\n\nconst mockPrintResult = jest.mocked(\n require(\"../../common/output.js\").printResultToConsoleAndExitGracefully\n);\nconst mockPrintCriticalFailure = jest.mocked(\n require(\"../../common/output.js\").printCriticalFailureToConsoleAndExit\n);\n\ndescribe(\"Whoami Command Integration Tests\", () => {\n let requestCapture: RequestCapture;\n\n beforeEach(() => {\n setupTestEnvironment();\n nock.cleanAll();\n requestCapture = new RequestCapture();\n\n nock.disableNetConnect();\n\n jest.clearAllMocks();\n });\n\n afterEach(() => {\n cleanupTest();\n requestCapture.clear();\n });\n\n it(\"should print sub when only sub is returned\", async () => {\n setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\"/v1/who-am-i\")\n .reply(200, { sub: TEST_SUB });\n\n await executeWhoamiCommand({\n \"api-key\": TEST_AUTH_TOKEN,\n });\n\n expect(mockPrintResult).toHaveBeenCalledWith(\n `Authenticated as ${TEST_SUB}`\n );\n });\n\n it(\"should include email and account when returned\", async () => {\n setupAuthenticatedNock(nock(TEST_API_BASE)).get(\"/v1/who-am-i\").reply(200, {\n sub: TEST_SUB,\n email: TEST_EMAIL,\n account: TEST_ACCOUNT,\n });\n\n await executeWhoamiCommand({\n \"api-key\": TEST_AUTH_TOKEN,\n });\n\n expect(mockPrintResult).toHaveBeenCalledWith(\n `Authenticated as ${TEST_EMAIL} (${TEST_SUB})\\nAccount: ${TEST_ACCOUNT}`\n );\n });\n\n it(\"should include account without email when only account is returned\", async () => {\n setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\"/v1/who-am-i\")\n .reply(200, { sub: TEST_SUB, account: TEST_ACCOUNT });\n\n await executeWhoamiCommand({\n \"api-key\": TEST_AUTH_TOKEN,\n });\n\n expect(mockPrintResult).toHaveBeenCalledWith(\n `Authenticated as ${TEST_SUB}\\nAccount: ${TEST_ACCOUNT}`\n );\n });\n\n it(\"should include the authorization header\", async () => {\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\"/v1/who-am-i\")\n .matchHeader(\"authorization\", `Bearer ${TEST_AUTH_TOKEN}`)\n .reply(200, { sub: TEST_SUB });\n\n scope.on(\"request\", (req, interceptor, body) => {\n requestCapture.capture(req, interceptor, body);\n });\n\n await executeWhoamiCommand({\n \"api-key\": TEST_AUTH_TOKEN,\n });\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintResult).toHaveBeenCalledWith(\n `Authenticated as ${TEST_SUB}`\n );\n });\n\n it(\"should fall back to the stored auth token when --api-key is omitted\", async () => {\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\"/v1/who-am-i\")\n .matchHeader(\"authorization\", `Bearer ${TEST_AUTH_TOKEN}`)\n .reply(200, { sub: TEST_SUB, email: TEST_EMAIL });\n\n await executeWhoamiCommand({});\n\n expect(scope.isDone()).toBe(true);\n expect(jest.mocked(getAuthToken)).toHaveBeenCalled();\n expect(mockPrintResult).toHaveBeenCalledWith(\n `Authenticated as ${TEST_EMAIL} (${TEST_SUB})`\n );\n });\n\n it(\"should fall back to the stored auth token when --api-key is empty\", async () => {\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\"/v1/who-am-i\")\n .matchHeader(\"authorization\", `Bearer ${TEST_AUTH_TOKEN}`)\n .reply(200, { sub: TEST_SUB });\n\n await executeWhoamiCommand({ \"api-key\": \" \" });\n\n expect(scope.isDone()).toBe(true);\n expect(jest.mocked(getAuthToken)).toHaveBeenCalled();\n expect(mockPrintResult).toHaveBeenCalledWith(\n `Authenticated as ${TEST_SUB}`\n );\n });\n\n it(\"should report logged out when no auth token is available\", async () => {\n jest.mocked(getAuthToken).mockResolvedValueOnce(undefined);\n\n await executeWhoamiCommand({});\n\n expect(mockPrintResult).toHaveBeenCalledWith(\"You are logged out\");\n expect(mockPrintCriticalFailure).not.toHaveBeenCalled();\n });\n\n it(\"should fail when the API returns an error\", async () => {\n const scope = setupAuthenticatedNock(nock(TEST_API_BASE))\n .get(\"/v1/who-am-i\")\n .reply(401, { error: \"Unauthorized\" });\n\n await expect(\n executeWhoamiCommand({\n \"api-key\": TEST_AUTH_TOKEN,\n })\n ).rejects.toThrow(\"Failed to determine current user\");\n\n expect(scope.isDone()).toBe(true);\n expect(mockPrintCriticalFailure).not.toHaveBeenCalled();\n });\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/bucket/list/handler.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;CAC7B;AAsBD,wBAAsB,IAAI,CAAC,IAAI,EAAE,SAAS,iBAuDzC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { logger } from "../../common/logger.js";
|
|
2
|
+
import { printDiagnosticsToConsole, printJsonToConsoleAndExitGracefully, printResultToConsoleAndExitGracefully, printTableToConsoleAndExitGracefully, textOrJson, } from "../../common/output.js";
|
|
3
|
+
import settings from "../../common/settings.js";
|
|
4
|
+
function toTableRows(buckets) {
|
|
5
|
+
return buckets.map((bucket) => ({
|
|
6
|
+
id: bucket.id,
|
|
7
|
+
name: bucket.name,
|
|
8
|
+
"project-name": bucket.tags?.project ?? "",
|
|
9
|
+
"environment-type": bucket.tags?.environmentType ?? "",
|
|
10
|
+
"is-retrievable": bucket.isRetrievable,
|
|
11
|
+
"created-on": bucket.createdOn,
|
|
12
|
+
}));
|
|
13
|
+
}
|
|
14
|
+
export async function list(argv) {
|
|
15
|
+
const { account, project } = argv;
|
|
16
|
+
const url = new URL(`${settings.ZUPLO_DEVELOPER_API_ENDPOINT}/v1/accounts/${account}/key-buckets`);
|
|
17
|
+
const listResponse = await fetch(url, {
|
|
18
|
+
method: "GET",
|
|
19
|
+
headers: {
|
|
20
|
+
Authorization: `Bearer ${argv.authToken}`,
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
if (listResponse.ok) {
|
|
24
|
+
const buckets = await listResponse.json();
|
|
25
|
+
if (project) {
|
|
26
|
+
buckets.data = buckets.data.filter((bucket) => bucket.tags?.project === project);
|
|
27
|
+
}
|
|
28
|
+
if (buckets.data.length === 0) {
|
|
29
|
+
if (argv.output === "json") {
|
|
30
|
+
await printJsonToConsoleAndExitGracefully([]);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
await printResultToConsoleAndExitGracefully("No buckets found");
|
|
34
|
+
}
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (argv.output === "json") {
|
|
38
|
+
await printJsonToConsoleAndExitGracefully(buckets.data);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
await printTableToConsoleAndExitGracefully(toTableRows(buckets.data));
|
|
42
|
+
}
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const response = textOrJson(await listResponse.text());
|
|
46
|
+
logger.error({
|
|
47
|
+
status: listResponse.status,
|
|
48
|
+
statusText: listResponse.statusText,
|
|
49
|
+
response,
|
|
50
|
+
}, "Failed to list buckets for account");
|
|
51
|
+
printDiagnosticsToConsole("Error: Failed to list buckets for your account. Try again later.", response);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/bucket/list/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EACL,yBAAyB,EACzB,mCAAmC,EACnC,qCAAqC,EACrC,oCAAoC,EACpC,UAAU,GACX,MAAM,wBAAwB,CAAC;AAChC,OAAO,QAAQ,MAAM,0BAA0B,CAAC;AAmBhD,SAAS,WAAW,CAAC,OAAiB;IACpC,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC9B,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,cAAc,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE;QAC1C,kBAAkB,EAAE,MAAM,CAAC,IAAI,EAAE,eAAe,IAAI,EAAE;QACtD,gBAAgB,EAAE,MAAM,CAAC,aAAa;QACtC,YAAY,EAAE,MAAM,CAAC,SAAS;KAC/B,CAAC,CAAC,CAAC;AACN,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,IAAe;IACxC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAElC,MAAM,GAAG,GAAG,IAAI,GAAG,CACjB,GAAG,QAAQ,CAAC,4BAA4B,gBAAgB,OAAO,cAAc,CAC9E,CAAC;IAEF,MAAM,YAAY,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QACpC,MAAM,EAAE,KAAK;QACb,OAAO,EAAE;YAEP,aAAa,EAAE,UAAU,IAAI,CAAC,SAAS,EAAE;SAC1C;KACF,CAAC,CAAC;IAEH,IAAI,YAAY,CAAC,EAAE,EAAE,CAAC;QACpB,MAAM,OAAO,GAAuB,MAAM,YAAY,CAAC,IAAI,EAAE,CAAC;QAE9D,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAChC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAC7C,CAAC;QACJ,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9B,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;gBAC3B,MAAM,mCAAmC,CAAC,EAAE,CAAC,CAAC;YAChD,CAAC;iBAAM,CAAC;gBACN,MAAM,qCAAqC,CAAC,kBAAkB,CAAC,CAAC;YAClE,CAAC;YACD,OAAO;QACT,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC3B,MAAM,mCAAmC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1D,CAAC;aAAM,CAAC;YACN,MAAM,oCAAoC,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACxE,CAAC;QACD,OAAO;IACT,CAAC;IAED,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC;IACvD,MAAM,CAAC,KAAK,CACV;QACE,MAAM,EAAE,YAAY,CAAC,MAAM;QAC3B,UAAU,EAAE,YAAY,CAAC,UAAU;QACnC,QAAQ;KACT,EACD,oCAAoC,CACrC,CAAC;IACF,yBAAyB,CACvB,kEAAkE,EAClE,QAAQ,CACT,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC","sourcesContent":["import { logger } from \"../../common/logger.js\";\nimport {\n printDiagnosticsToConsole,\n printJsonToConsoleAndExitGracefully,\n printResultToConsoleAndExitGracefully,\n printTableToConsoleAndExitGracefully,\n textOrJson,\n} from \"../../common/output.js\";\nimport settings from \"../../common/settings.js\";\nimport { Bucket, BucketListResponse } from \"../models.js\";\n\nexport interface Arguments {\n account: string;\n project?: string;\n authToken: string;\n output?: \"default\" | \"json\";\n}\n\ninterface BucketTableRow {\n id: string;\n name: string;\n \"project-name\": string;\n \"environment-type\": string;\n \"is-retrievable\": boolean;\n \"created-on\": string;\n}\n\nfunction toTableRows(buckets: Bucket[]): BucketTableRow[] {\n return buckets.map((bucket) => ({\n id: bucket.id,\n name: bucket.name,\n \"project-name\": bucket.tags?.project ?? \"\",\n \"environment-type\": bucket.tags?.environmentType ?? \"\",\n \"is-retrievable\": bucket.isRetrievable,\n \"created-on\": bucket.createdOn,\n }));\n}\n\nexport async function list(argv: Arguments) {\n const { account, project } = argv;\n\n const url = new URL(\n `${settings.ZUPLO_DEVELOPER_API_ENDPOINT}/v1/accounts/${account}/key-buckets`\n );\n\n const listResponse = await fetch(url, {\n method: \"GET\",\n headers: {\n // biome-ignore lint/style/useNamingConvention: External API property\n Authorization: `Bearer ${argv.authToken}`,\n },\n });\n\n if (listResponse.ok) {\n const buckets: BucketListResponse = await listResponse.json();\n\n if (project) {\n buckets.data = buckets.data.filter(\n (bucket) => bucket.tags?.project === project\n );\n }\n\n if (buckets.data.length === 0) {\n if (argv.output === \"json\") {\n await printJsonToConsoleAndExitGracefully([]);\n } else {\n await printResultToConsoleAndExitGracefully(\"No buckets found\");\n }\n return;\n }\n\n if (argv.output === \"json\") {\n await printJsonToConsoleAndExitGracefully(buckets.data);\n } else {\n await printTableToConsoleAndExitGracefully(toTableRows(buckets.data));\n }\n return;\n }\n\n const response = textOrJson(await listResponse.text());\n logger.error(\n {\n status: listResponse.status,\n statusText: listResponse.statusText,\n response,\n },\n \"Failed to list buckets for account\"\n );\n printDiagnosticsToConsole(\n \"Error: Failed to list buckets for your account. Try again later.\",\n response\n );\n process.exit(1);\n}\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type BucketEnvironmentType = "PRODUCTION" | "PREVIEW" | "WORKING_COPY";
|
|
2
|
+
export interface BucketTags {
|
|
3
|
+
account: string;
|
|
4
|
+
project: string;
|
|
5
|
+
environmentType: BucketEnvironmentType;
|
|
6
|
+
[key: string]: string | undefined;
|
|
7
|
+
}
|
|
8
|
+
export interface Bucket {
|
|
9
|
+
id: string;
|
|
10
|
+
name: string;
|
|
11
|
+
description: string | null;
|
|
12
|
+
isRetrievable: boolean;
|
|
13
|
+
tags: BucketTags;
|
|
14
|
+
createdOn: string;
|
|
15
|
+
updatedOn: string;
|
|
16
|
+
}
|
|
17
|
+
export interface BucketListResponse {
|
|
18
|
+
data: Bucket[];
|
|
19
|
+
total?: number;
|
|
20
|
+
limit?: number;
|
|
21
|
+
offset?: number;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=models.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/bucket/models.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,GAAG,YAAY,GAAG,SAAS,GAAG,cAAc,CAAC;AAE9E,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,qBAAqB,CAAC;IACvC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACnC;AAED,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,OAAO,CAAC;IACvB,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/bucket/models.ts"],"names":[],"mappings":"","sourcesContent":["export type BucketEnvironmentType = \"PRODUCTION\" | \"PREVIEW\" | \"WORKING_COPY\";\n\nexport interface BucketTags {\n account: string;\n project: string;\n environmentType: BucketEnvironmentType;\n [key: string]: string | undefined;\n}\n\nexport interface Bucket {\n id: string;\n name: string;\n description: string | null;\n isRetrievable: boolean;\n tags: BucketTags;\n createdOn: string;\n updatedOn: string;\n}\n\nexport interface BucketListResponse {\n data: Bucket[];\n total?: number;\n limit?: number;\n offset?: number;\n}\n"]}
|