@pagopa/dx-cli 0.22.4 → 0.23.1

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.
Files changed (104) hide show
  1. package/README.md +18 -0
  2. package/dist/adapters/commander/commands/add.d.ts +2 -6
  3. package/dist/adapters/commander/commands/add.js +4 -8
  4. package/dist/adapters/commander/commands/init.d.ts +2 -6
  5. package/dist/adapters/commander/commands/init.js +6 -5
  6. package/dist/adapters/commander/commands/savemoney.d.ts +11 -0
  7. package/dist/adapters/commander/commands/savemoney.js +30 -5
  8. package/dist/adapters/commander/commands/spec.d.ts +10 -0
  9. package/dist/adapters/commander/commands/spec.js +13 -0
  10. package/dist/adapters/commander/index.js +6 -2
  11. package/dist/adapters/commander/spec.d.ts +16 -0
  12. package/dist/adapters/commander/spec.js +54 -0
  13. package/dist/adapters/plop/generators/environment/actions.js +3 -3
  14. package/dist/adapters/plop/index.js +3 -5
  15. package/dist/adapters/plop/templates-path.d.ts +5 -0
  16. package/dist/adapters/plop/templates-path.js +6 -0
  17. package/dist/domain/dependencies.d.ts +15 -2
  18. package/dist/domain/spec.d.ts +50 -0
  19. package/dist/domain/spec.js +8 -0
  20. package/dist/index.js +15 -12
  21. package/package.json +5 -5
  22. package/templates/monorepo/nx.json +0 -1
  23. package/dist/adapters/azure/__tests__/cloud-account-repository.test.d.ts +0 -1
  24. package/dist/adapters/azure/__tests__/cloud-account-repository.test.js +0 -95
  25. package/dist/adapters/azure/__tests__/cloud-account-service.test.d.ts +0 -1
  26. package/dist/adapters/azure/__tests__/cloud-account-service.test.js +0 -378
  27. package/dist/adapters/codemods/__tests__/registry.test.d.ts +0 -1
  28. package/dist/adapters/codemods/__tests__/registry.test.js +0 -56
  29. package/dist/adapters/codemods/__tests__/use-azure-appsvc.test.d.ts +0 -1
  30. package/dist/adapters/codemods/__tests__/use-azure-appsvc.test.js +0 -77
  31. package/dist/adapters/codemods/__tests__/use-pnpm.test.d.ts +0 -1
  32. package/dist/adapters/codemods/__tests__/use-pnpm.test.js +0 -148
  33. package/dist/adapters/commander/__tests__/env.test.d.ts +0 -1
  34. package/dist/adapters/commander/__tests__/env.test.js +0 -45
  35. package/dist/adapters/commander/__tests__/error-reporting.test.d.ts +0 -1
  36. package/dist/adapters/commander/__tests__/error-reporting.test.js +0 -63
  37. package/dist/adapters/commander/__tests__/exit-with-error.test.d.ts +0 -1
  38. package/dist/adapters/commander/__tests__/exit-with-error.test.js +0 -92
  39. package/dist/adapters/commander/__tests__/global-options.test.d.ts +0 -1
  40. package/dist/adapters/commander/__tests__/global-options.test.js +0 -33
  41. package/dist/adapters/commander/commands/__tests__/add.test.d.ts +0 -4
  42. package/dist/adapters/commander/commands/__tests__/add.test.js +0 -167
  43. package/dist/adapters/commander/commands/__tests__/init.test.d.ts +0 -4
  44. package/dist/adapters/commander/commands/__tests__/init.test.js +0 -48
  45. package/dist/adapters/commander/commands/__tests__/preconditions.test.d.ts +0 -1
  46. package/dist/adapters/commander/commands/__tests__/preconditions.test.js +0 -32
  47. package/dist/adapters/commander/presenters/__tests__/index.test.d.ts +0 -1
  48. package/dist/adapters/commander/presenters/__tests__/index.test.js +0 -23
  49. package/dist/adapters/commander/presenters/__tests__/json.test.d.ts +0 -1
  50. package/dist/adapters/commander/presenters/__tests__/json.test.js +0 -108
  51. package/dist/adapters/commander/presenters/__tests__/text.test.d.ts +0 -1
  52. package/dist/adapters/commander/presenters/__tests__/text.test.js +0 -60
  53. package/dist/adapters/github/__tests__/github-repo.spec.d.ts +0 -1
  54. package/dist/adapters/github/__tests__/github-repo.spec.js +0 -67
  55. package/dist/adapters/node/__tests__/data.d.ts +0 -18
  56. package/dist/adapters/node/__tests__/data.js +0 -22
  57. package/dist/adapters/node/__tests__/package-json.test.d.ts +0 -1
  58. package/dist/adapters/node/__tests__/package-json.test.js +0 -86
  59. package/dist/adapters/node/__tests__/repository.test.d.ts +0 -1
  60. package/dist/adapters/node/__tests__/repository.test.js +0 -77
  61. package/dist/adapters/node/fs/__tests__/file-reader.test.d.ts +0 -1
  62. package/dist/adapters/node/fs/__tests__/file-reader.test.js +0 -80
  63. package/dist/adapters/node/json/__tests__/index.test.d.ts +0 -1
  64. package/dist/adapters/node/json/__tests__/index.test.js +0 -14
  65. package/dist/adapters/octokit/__tests__/index.test.d.ts +0 -1
  66. package/dist/adapters/octokit/__tests__/index.test.js +0 -414
  67. package/dist/adapters/pagopa-technology/__tests__/authorization.test.d.ts +0 -4
  68. package/dist/adapters/pagopa-technology/__tests__/authorization.test.js +0 -548
  69. package/dist/adapters/plop/__tests__/run-actions.test.d.ts +0 -1
  70. package/dist/adapters/plop/__tests__/run-actions.test.js +0 -68
  71. package/dist/adapters/plop/actions/__tests__/init-cloud-accounts.test.d.ts +0 -1
  72. package/dist/adapters/plop/actions/__tests__/init-cloud-accounts.test.js +0 -171
  73. package/dist/adapters/plop/actions/__tests__/provision-terraform-backend.test.d.ts +0 -1
  74. package/dist/adapters/plop/actions/__tests__/provision-terraform-backend.test.js +0 -134
  75. package/dist/adapters/plop/generators/environment/__tests__/actions.test.d.ts +0 -2
  76. package/dist/adapters/plop/generators/environment/__tests__/actions.test.js +0 -92
  77. package/dist/adapters/plop/generators/environment/__tests__/prompts.test.d.ts +0 -1
  78. package/dist/adapters/plop/generators/environment/__tests__/prompts.test.js +0 -182
  79. package/dist/adapters/plop/helpers/__tests__/resource-prefix.test.d.ts +0 -1
  80. package/dist/adapters/plop/helpers/__tests__/resource-prefix.test.js +0 -113
  81. package/dist/adapters/plop/helpers/__tests__/terraform-state-key.test.d.ts +0 -1
  82. package/dist/adapters/plop/helpers/__tests__/terraform-state-key.test.js +0 -35
  83. package/dist/adapters/plop/helpers/__tests__/validate-prompt.test.d.ts +0 -1
  84. package/dist/adapters/plop/helpers/__tests__/validate-prompt.test.js +0 -60
  85. package/dist/adapters/yaml/__tests__/index.test.d.ts +0 -1
  86. package/dist/adapters/yaml/__tests__/index.test.js +0 -53
  87. package/dist/domain/__tests__/data.d.ts +0 -19
  88. package/dist/domain/__tests__/data.js +0 -28
  89. package/dist/domain/__tests__/environment.test.d.ts +0 -1
  90. package/dist/domain/__tests__/environment.test.js +0 -332
  91. package/dist/domain/__tests__/info.test.d.ts +0 -1
  92. package/dist/domain/__tests__/info.test.js +0 -77
  93. package/dist/domain/__tests__/package-json.test.d.ts +0 -1
  94. package/dist/domain/__tests__/package-json.test.js +0 -39
  95. package/dist/domain/__tests__/repository.test.d.ts +0 -1
  96. package/dist/domain/__tests__/repository.test.js +0 -111
  97. package/dist/domain/__tests__/workspace.test.d.ts +0 -1
  98. package/dist/domain/__tests__/workspace.test.js +0 -57
  99. package/dist/use-cases/__tests__/apply-codemod.test.d.ts +0 -1
  100. package/dist/use-cases/__tests__/apply-codemod.test.js +0 -71
  101. package/dist/use-cases/__tests__/list-codemods.test.d.ts +0 -1
  102. package/dist/use-cases/__tests__/list-codemods.test.js +0 -37
  103. package/dist/use-cases/__tests__/request-authorization.test.d.ts +0 -4
  104. package/dist/use-cases/__tests__/request-authorization.test.js +0 -43
@@ -1,171 +0,0 @@
1
- import { describe, expect, it, vi } from "vitest";
2
- import { initCloudAccounts } from "../init-cloud-accounts.js";
3
- const createMockGitHubService = () => ({
4
- createBranch: vi.fn(),
5
- createOrUpdateEnvironmentSecret: vi.fn().mockResolvedValue(undefined),
6
- createPullRequest: vi.fn(),
7
- getFileContent: vi.fn(),
8
- getRepository: vi.fn(),
9
- updateFile: vi.fn(),
10
- });
11
- const createMockCloudAccountService = (overrides = {}) => ({
12
- getTerraformBackend: vi.fn().mockResolvedValue(undefined),
13
- hasUserPermissionToInitialize: vi.fn().mockResolvedValue(true),
14
- initialize: vi.fn().mockResolvedValue(undefined),
15
- isInitialized: vi.fn().mockResolvedValue(true),
16
- provisionTerraformBackend: vi.fn().mockResolvedValue(undefined),
17
- ...overrides,
18
- });
19
- const createMockCloudAccount = (overrides = {}) => ({
20
- csp: "azure",
21
- defaultLocation: "westeurope",
22
- displayName: "Test-Account",
23
- id: "test-subscription-id",
24
- ...overrides,
25
- });
26
- const createMockPayload = (overrides = {}) => ({
27
- env: {
28
- cloudAccounts: [createMockCloudAccount()],
29
- name: "dev",
30
- prefix: "dx",
31
- },
32
- github: {
33
- owner: "pagopa",
34
- repo: "dx",
35
- },
36
- init: {
37
- cloudAccountsToInitialize: [],
38
- runnerAppCredentials: {
39
- clientId: "test-app-client-id",
40
- id: "test-app-id",
41
- installationId: "test-installation-id",
42
- key: "test-private-key",
43
- },
44
- terraformBackend: {
45
- cloudAccount: createMockCloudAccount(),
46
- },
47
- },
48
- tags: {},
49
- workspace: {
50
- domain: "test",
51
- },
52
- ...overrides,
53
- });
54
- describe("initCloudAccounts", () => {
55
- it("should initialize all cloud accounts in cloudAccountsToInitialize", async () => {
56
- const cloudAccount1 = createMockCloudAccount({ id: "account-1" });
57
- const cloudAccount2 = createMockCloudAccount({ id: "account-2" });
58
- const initializeMock = vi.fn().mockResolvedValue(undefined);
59
- const mockService = createMockCloudAccountService({
60
- initialize: initializeMock,
61
- });
62
- const payload = createMockPayload({
63
- env: {
64
- cloudAccounts: [],
65
- name: "prod",
66
- prefix: "io",
67
- },
68
- init: {
69
- cloudAccountsToInitialize: [cloudAccount1, cloudAccount2],
70
- runnerAppCredentials: {
71
- clientId: "test-app-client-id",
72
- id: "test-app-id",
73
- installationId: "test-installation-id",
74
- key: "test-private-key",
75
- },
76
- terraformBackend: {
77
- cloudAccount: createMockCloudAccount(),
78
- },
79
- },
80
- });
81
- await initCloudAccounts(payload, mockService, createMockGitHubService());
82
- expect(initializeMock).toHaveBeenCalledTimes(2);
83
- expect(initializeMock).toHaveBeenCalledWith(cloudAccount1, expect.objectContaining({ name: "prod", prefix: "io" }), {
84
- clientId: "test-app-client-id",
85
- id: "test-app-id",
86
- installationId: "test-installation-id",
87
- key: "test-private-key",
88
- }, {
89
- owner: "pagopa",
90
- repo: "dx",
91
- }, expect.any(Object), {});
92
- expect(initializeMock).toHaveBeenCalledWith(cloudAccount2, expect.objectContaining({ name: "prod", prefix: "io" }), {
93
- clientId: "test-app-client-id",
94
- id: "test-app-id",
95
- installationId: "test-installation-id",
96
- key: "test-private-key",
97
- }, {
98
- owner: "pagopa",
99
- repo: "dx",
100
- }, expect.any(Object), {});
101
- });
102
- it("should not call initialize when cloudAccountsToInitialize is empty", async () => {
103
- const initializeMock = vi.fn().mockResolvedValue(undefined);
104
- const mockService = createMockCloudAccountService({
105
- initialize: initializeMock,
106
- });
107
- const payload = createMockPayload({
108
- init: {
109
- cloudAccountsToInitialize: [],
110
- runnerAppCredentials: {
111
- clientId: "test-app-client-id",
112
- id: "test-app-id",
113
- installationId: "test-installation-id",
114
- key: "test-private-key",
115
- },
116
- terraformBackend: {
117
- cloudAccount: createMockCloudAccount(),
118
- },
119
- },
120
- });
121
- await initCloudAccounts(payload, mockService, createMockGitHubService());
122
- expect(initializeMock).not.toHaveBeenCalled();
123
- });
124
- it("should not call initialize when payload.init is undefined", async () => {
125
- const initializeMock = vi.fn().mockResolvedValue(undefined);
126
- const mockService = createMockCloudAccountService({
127
- initialize: initializeMock,
128
- });
129
- const payload = createMockPayload({
130
- init: undefined,
131
- });
132
- await initCloudAccounts(payload, mockService, createMockGitHubService());
133
- expect(initializeMock).not.toHaveBeenCalled();
134
- });
135
- it("should use prefix and environment name from payload.env", async () => {
136
- const cloudAccount = createMockCloudAccount();
137
- const initializeMock = vi.fn().mockResolvedValue(undefined);
138
- const mockService = createMockCloudAccountService({
139
- initialize: initializeMock,
140
- });
141
- const payload = createMockPayload({
142
- env: {
143
- cloudAccounts: [],
144
- name: "uat",
145
- prefix: "pagopa",
146
- },
147
- init: {
148
- cloudAccountsToInitialize: [cloudAccount],
149
- runnerAppCredentials: {
150
- clientId: "test-app-client-id",
151
- id: "test-app-id",
152
- installationId: "test-installation-id",
153
- key: "test-private-key",
154
- },
155
- terraformBackend: {
156
- cloudAccount: createMockCloudAccount(),
157
- },
158
- },
159
- });
160
- await initCloudAccounts(payload, mockService, createMockGitHubService());
161
- expect(initializeMock).toHaveBeenCalledWith(cloudAccount, expect.objectContaining({ name: "uat", prefix: "pagopa" }), {
162
- clientId: "test-app-client-id",
163
- id: "test-app-id",
164
- installationId: "test-installation-id",
165
- key: "test-private-key",
166
- }, {
167
- owner: "pagopa",
168
- repo: "dx",
169
- }, expect.any(Object), {});
170
- });
171
- });
@@ -1,134 +0,0 @@
1
- import { describe, expect, it, vi } from "vitest";
2
- import { provisionTerraformBackend } from "../provision-terraform-backend.js";
3
- const createMockCloudAccountService = (overrides = {}) => ({
4
- getTerraformBackend: vi.fn().mockResolvedValue(undefined),
5
- hasUserPermissionToInitialize: vi.fn().mockResolvedValue(true),
6
- initialize: vi.fn().mockResolvedValue(undefined),
7
- isInitialized: vi.fn().mockResolvedValue(true),
8
- provisionTerraformBackend: vi.fn().mockResolvedValue(undefined),
9
- ...overrides,
10
- });
11
- const createMockCloudAccount = (overrides = {}) => ({
12
- csp: "azure",
13
- defaultLocation: "westeurope",
14
- displayName: "Test-Account",
15
- id: "test-subscription-id",
16
- ...overrides,
17
- });
18
- const createMockTerraformBackend = (overrides = {}) => ({
19
- resourceGroupName: "dx-d-itn-tf-rg",
20
- storageAccountName: "dxditntfst",
21
- subscriptionId: "00000000-0000-0000-0000-000000000000",
22
- type: "azurerm",
23
- ...overrides,
24
- });
25
- const createMockPayload = (overrides = {}) => ({
26
- env: {
27
- cloudAccounts: [createMockCloudAccount()],
28
- name: "dev",
29
- prefix: "dx",
30
- },
31
- github: {
32
- owner: "pagopa",
33
- repo: "dx",
34
- },
35
- init: {
36
- cloudAccountsToInitialize: [],
37
- runnerAppCredentials: {
38
- clientId: "test-app-client-id",
39
- id: "test-app-id",
40
- installationId: "test-installation-id",
41
- key: "test-private-key",
42
- },
43
- terraformBackend: {
44
- cloudAccount: createMockCloudAccount(),
45
- },
46
- },
47
- tags: {},
48
- workspace: {
49
- domain: "test",
50
- },
51
- ...overrides,
52
- });
53
- describe("provisionTerraformBackend", () => {
54
- it("should provision terraform backend and return it", async () => {
55
- const mockBackend = createMockTerraformBackend();
56
- const provisionMock = vi.fn().mockResolvedValue(mockBackend);
57
- const mockService = createMockCloudAccountService({
58
- provisionTerraformBackend: provisionMock,
59
- });
60
- const payload = createMockPayload();
61
- const result = await provisionTerraformBackend(payload, mockService);
62
- expect(result).toEqual(mockBackend);
63
- });
64
- it("should call provisionTerraformBackend with correct parameters", async () => {
65
- const cloudAccount = createMockCloudAccount({ id: "my-subscription" });
66
- const provisionMock = vi
67
- .fn()
68
- .mockResolvedValue(createMockTerraformBackend());
69
- const mockService = createMockCloudAccountService({
70
- provisionTerraformBackend: provisionMock,
71
- });
72
- const payload = createMockPayload({
73
- env: {
74
- cloudAccounts: [cloudAccount],
75
- name: "prod",
76
- prefix: "io",
77
- },
78
- init: {
79
- cloudAccountsToInitialize: [],
80
- runnerAppCredentials: {
81
- clientId: "test-app-client-id",
82
- id: "test-app-id",
83
- installationId: "test-installation-id",
84
- key: "test-private-key",
85
- },
86
- terraformBackend: {
87
- cloudAccount,
88
- },
89
- },
90
- });
91
- await provisionTerraformBackend(payload, mockService);
92
- expect(provisionMock).toHaveBeenCalledWith(cloudAccount, expect.objectContaining({ name: "prod", prefix: "io" }), {});
93
- });
94
- it("should throw an error when payload.init is undefined", async () => {
95
- const mockService = createMockCloudAccountService();
96
- const payload = createMockPayload({
97
- init: undefined,
98
- });
99
- await expect(provisionTerraformBackend(payload, mockService)).rejects.toThrow("This action requires initialization data in the payload");
100
- });
101
- it("should use the terraformBackend cloudAccount from init", async () => {
102
- const envCloudAccount = createMockCloudAccount({ id: "env-account" });
103
- const backendCloudAccount = createMockCloudAccount({
104
- id: "backend-account",
105
- });
106
- const provisionMock = vi
107
- .fn()
108
- .mockResolvedValue(createMockTerraformBackend());
109
- const mockService = createMockCloudAccountService({
110
- provisionTerraformBackend: provisionMock,
111
- });
112
- const payload = createMockPayload({
113
- env: {
114
- cloudAccounts: [envCloudAccount],
115
- name: "uat",
116
- prefix: "dx",
117
- },
118
- init: {
119
- cloudAccountsToInitialize: [],
120
- runnerAppCredentials: {
121
- clientId: "test-app-client-id",
122
- id: "test-app-id",
123
- installationId: "test-installation-id",
124
- key: "test-private-key",
125
- },
126
- terraformBackend: {
127
- cloudAccount: backendCloudAccount,
128
- },
129
- },
130
- });
131
- await provisionTerraformBackend(payload, mockService);
132
- expect(provisionMock).toHaveBeenCalledWith(backendCloudAccount, expect.objectContaining({ name: "uat", prefix: "dx" }), {});
133
- });
134
- });
@@ -1,2 +0,0 @@
1
- import { Payload } from "../prompts.js";
2
- export declare const getPayload: (includeInit?: boolean) => Payload;
@@ -1,92 +0,0 @@
1
- import { describe, expect, test } from "vitest";
2
- import { z } from "zod";
3
- import getActions from "../actions.js";
4
- const terraformBackendActionSchema = z.object({
5
- data: z.object({
6
- terraformBackendKey: z.string(),
7
- }),
8
- type: z.literal("addMany"),
9
- });
10
- export const getPayload = (includeInit = false) => {
11
- const cloudAccount = {
12
- csp: "azure",
13
- defaultLocation: "westeurope",
14
- displayName: "Test-Account",
15
- id: "test-subscription-id",
16
- };
17
- const payload = {
18
- env: {
19
- cloudAccounts: [cloudAccount],
20
- name: "dev",
21
- prefix: "dx",
22
- },
23
- github: {
24
- owner: "pagopa",
25
- repo: "dx",
26
- },
27
- tags: {},
28
- workspace: {
29
- domain: "mytest",
30
- },
31
- };
32
- if (includeInit) {
33
- payload.init = {
34
- cloudAccountsToInitialize: [cloudAccount],
35
- runnerAppCredentials: {
36
- clientId: "test-app-client-id",
37
- id: "test-app-id",
38
- installationId: "test-installation-id",
39
- key: "test-private-key",
40
- },
41
- terraformBackend: {
42
- cloudAccount,
43
- },
44
- };
45
- }
46
- return payload;
47
- };
48
- describe("actions", () => {
49
- test.each([
50
- {
51
- payload: getPayload(true),
52
- },
53
- {
54
- payload: getPayload(false),
55
- },
56
- ])("correct order of actions", ({ payload }) => {
57
- const actionsOrder = [
58
- "getTerraformBackend",
59
- "addMany",
60
- "addMany",
61
- "addMany",
62
- ];
63
- if (payload.init) {
64
- actionsOrder.unshift("initCloudAccounts", "provisionTerraformBackend");
65
- actionsOrder.push("addMany", "addMany");
66
- }
67
- const actions = getActions("/templates/path")(payload);
68
- const actionTypes = actions
69
- .filter((action) => typeof action === "object" && Object.hasOwn(action, "type"))
70
- .map((action) => action.type);
71
- expect(actionTypes).toEqual(actionsOrder);
72
- });
73
- test.each([
74
- {
75
- expectedKeys: [
76
- "dx/mytest/bootstrapper.tfstate",
77
- "dx/mytest/core.tfstate",
78
- ],
79
- payload: getPayload(true),
80
- },
81
- {
82
- expectedKeys: ["dx/mytest/bootstrapper.tfstate"],
83
- payload: getPayload(false),
84
- },
85
- ])("uses prefix/domain/scope state keys in shared backend actions", ({ expectedKeys, payload }) => {
86
- const actions = getActions("/templates/path")(payload);
87
- const terraformBackendKeys = actions
88
- .filter((action) => terraformBackendActionSchema.safeParse(action).success)
89
- .map((action) => action.data.terraformBackendKey);
90
- expect(terraformBackendKeys).toEqual(expectedKeys);
91
- });
92
- });
@@ -1,182 +0,0 @@
1
- // Tests for workspaceSchema transforms (lowercase and trim on domain).
2
- import inquirer from "inquirer";
3
- import { describe, expect, it, vi } from "vitest";
4
- import prompts, { formatInitializationDetails, workspaceSchema, } from "../prompts.js";
5
- describe("workspaceSchema — domain transforms", () => {
6
- it("lowercases an uppercase domain", () => {
7
- const result = workspaceSchema.safeParse({ domain: "API" });
8
- expect(result.success).toBe(true);
9
- expect(result.success && result.data.domain).toBe("api");
10
- });
11
- it("lowercases a mixed-case domain", () => {
12
- const result = workspaceSchema.safeParse({ domain: "MyDomain" });
13
- expect(result.success).toBe(true);
14
- expect(result.success && result.data.domain).toBe("mydomain");
15
- });
16
- it("trims leading and trailing whitespace from domain", () => {
17
- const result = workspaceSchema.safeParse({ domain: " aPi " });
18
- expect(result.success).toBe(true);
19
- expect(result.success && result.data.domain).toBe("api");
20
- });
21
- it("requires domain to be provided", () => {
22
- const result = workspaceSchema.safeParse({});
23
- expect(result.success).toBe(false);
24
- });
25
- it("rejects domains that would create nested paths", () => {
26
- const result = workspaceSchema.safeParse({ domain: "core/platform" });
27
- expect(result.success).toBe(false);
28
- });
29
- });
30
- describe("formatInitializationDetails", () => {
31
- const account = (overrides = {}) => ({
32
- csp: "azure",
33
- defaultLocation: "italynorth",
34
- displayName: "DEV-FooBar",
35
- id: "sub-123",
36
- ...overrides,
37
- });
38
- const notInitializedStatus = (issues) => ({
39
- initialized: false,
40
- issues,
41
- });
42
- it("lists each uninitialized cloud account by displayName", () => {
43
- const status = notInitializedStatus([
44
- {
45
- cloudAccount: account({ displayName: "DEV-A" }),
46
- type: "CLOUD_ACCOUNT_NOT_INITIALIZED",
47
- },
48
- {
49
- cloudAccount: account({ displayName: "DEV-B" }),
50
- type: "CLOUD_ACCOUNT_NOT_INITIALIZED",
51
- },
52
- ]);
53
- const output = formatInitializationDetails(status);
54
- expect(output).toContain('Azure subscription "DEV-A"');
55
- expect(output).toContain('Azure subscription "DEV-B"');
56
- expect(output).toContain("managed identity");
57
- expect(output).toContain("OIDC");
58
- expect(output).toContain("ARM_CLIENT_ID");
59
- expect(output).toContain("ARM_SUBSCRIPTION_ID");
60
- expect(output).not.toContain("ARM_TENANT_ID");
61
- expect(output).toContain("Key Vault");
62
- });
63
- it("includes the Terraform backend section when MISSING_REMOTE_BACKEND issue is present", () => {
64
- const status = notInitializedStatus([
65
- { cloudAccount: account(), type: "CLOUD_ACCOUNT_NOT_INITIALIZED" },
66
- { type: "MISSING_REMOTE_BACKEND" },
67
- ]);
68
- const output = formatInitializationDetails(status);
69
- expect(output).toContain("Terraform remote backend");
70
- expect(output).toContain("Storage Account");
71
- });
72
- it("omits the Terraform backend section when no MISSING_REMOTE_BACKEND issue is present", () => {
73
- const status = notInitializedStatus([
74
- { cloudAccount: account(), type: "CLOUD_ACCOUNT_NOT_INITIALIZED" },
75
- ]);
76
- const output = formatInitializationDetails(status);
77
- expect(output).not.toContain("Terraform remote backend");
78
- });
79
- it("omits the cloud account section when no CLOUD_ACCOUNT_NOT_INITIALIZED issues are present", () => {
80
- const status = notInitializedStatus([{ type: "MISSING_REMOTE_BACKEND" }]);
81
- const output = formatInitializationDetails(status);
82
- expect(output).not.toContain("Azure subscription");
83
- expect(output).toContain("Terraform remote backend");
84
- });
85
- it("returns an empty string when there are no relevant issues", () => {
86
- const status = notInitializedStatus([]);
87
- expect(formatInitializationDetails(status)).toBe("");
88
- });
89
- });
90
- describe("prompts", () => {
91
- it("prompts for the GitHub runner app client ID when initialization is required", async () => {
92
- const cloudAccount = {
93
- csp: "azure",
94
- defaultLocation: "italynorth",
95
- displayName: "DEV-FooBar",
96
- id: "sub-123",
97
- };
98
- const cloudAccountRepository = {
99
- list: vi.fn().mockResolvedValue([cloudAccount]),
100
- };
101
- const cloudAccountService = {
102
- getTerraformBackend: vi.fn().mockResolvedValue(undefined),
103
- hasUserPermissionToInitialize: vi.fn().mockResolvedValue(true),
104
- initialize: vi.fn().mockResolvedValue(undefined),
105
- isInitialized: vi.fn().mockResolvedValue(false),
106
- provisionTerraformBackend: vi.fn().mockResolvedValue(undefined),
107
- };
108
- const promptSpy = vi.spyOn(inquirer, "prompt");
109
- const consoleLogSpy = vi
110
- .spyOn(console, "log")
111
- .mockImplementation(() => undefined);
112
- promptSpy
113
- .mockResolvedValueOnce({
114
- env: {
115
- cloudAccounts: [cloudAccount],
116
- name: "dev",
117
- prefix: "dx",
118
- },
119
- tags: {
120
- BusinessUnit: "Platform",
121
- CostCenter: "TS000",
122
- ManagementTeam: "Engineering",
123
- },
124
- workspace: {
125
- domain: "payments",
126
- },
127
- })
128
- .mockResolvedValueOnce({
129
- [cloudAccount.id]: "italynorth",
130
- })
131
- .mockResolvedValueOnce({
132
- init: true,
133
- })
134
- .mockResolvedValueOnce({
135
- runnerAppCredentials: {
136
- clientId: "app-client-id",
137
- id: "app-id",
138
- installationId: "installation-id",
139
- key: "private-key",
140
- },
141
- });
142
- try {
143
- const result = await prompts({
144
- cloudAccountRepository,
145
- cloudAccountService,
146
- github: {
147
- owner: "pagopa",
148
- repo: "dx",
149
- },
150
- })(inquirer);
151
- const runnerCredentialQuestions = promptSpy.mock.calls[3]?.[0];
152
- expect(runnerCredentialQuestions).toEqual(expect.arrayContaining([
153
- expect.objectContaining({
154
- message: "GitHub Runner App ID",
155
- name: "runnerAppCredentials.id",
156
- }),
157
- expect.objectContaining({
158
- message: "GitHub Runner App Client ID",
159
- name: "runnerAppCredentials.clientId",
160
- }),
161
- expect.objectContaining({
162
- message: "GitHub Runner App Installation ID",
163
- name: "runnerAppCredentials.installationId",
164
- }),
165
- expect.objectContaining({
166
- message: "GitHub Runner App Private Key",
167
- name: "runnerAppCredentials.key",
168
- }),
169
- ]));
170
- expect(result.init?.runnerAppCredentials).toEqual({
171
- clientId: "app-client-id",
172
- id: "app-id",
173
- installationId: "installation-id",
174
- key: "private-key",
175
- });
176
- }
177
- finally {
178
- promptSpy.mockRestore();
179
- consoleLogSpy.mockRestore();
180
- }
181
- });
182
- });