@lightdash/cli 2.228.0 → 2.229.0

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 (177) hide show
  1. package/dist/.tsbuildinfo.build +1 -0
  2. package/package.json +4 -4
  3. package/dist/.tsbuildinfo +0 -1
  4. package/dist/config.test.d.ts +0 -2
  5. package/dist/config.test.d.ts.map +0 -1
  6. package/dist/config.test.js +0 -72
  7. package/dist/dbt/context.test.d.ts +0 -2
  8. package/dist/dbt/context.test.d.ts.map +0 -1
  9. package/dist/dbt/context.test.js +0 -152
  10. package/dist/dbt/manifest.test.d.ts +0 -2
  11. package/dist/dbt/manifest.test.d.ts.map +0 -1
  12. package/dist/dbt/manifest.test.js +0 -170
  13. package/dist/dbt/models.test.d.ts +0 -2
  14. package/dist/dbt/models.test.d.ts.map +0 -1
  15. package/dist/dbt/models.test.js +0 -139
  16. package/dist/dbt/profiles.test.d.ts +0 -2
  17. package/dist/dbt/profiles.test.d.ts.map +0 -1
  18. package/dist/dbt/profiles.test.js +0 -50
  19. package/dist/dbt/targets/athena.test.d.ts +0 -2
  20. package/dist/dbt/targets/athena.test.d.ts.map +0 -1
  21. package/dist/dbt/targets/athena.test.js +0 -78
  22. package/dist/dbt/targets/duckdb.test.d.ts +0 -2
  23. package/dist/dbt/targets/duckdb.test.d.ts.map +0 -1
  24. package/dist/dbt/targets/duckdb.test.js +0 -149
  25. package/dist/dbt/targets/redshift.test.d.ts +0 -2
  26. package/dist/dbt/targets/redshift.test.d.ts.map +0 -1
  27. package/dist/dbt/targets/redshift.test.js +0 -198
  28. package/dist/dbt/templating.test.d.ts +0 -2
  29. package/dist/dbt/templating.test.d.ts.map +0 -1
  30. package/dist/dbt/templating.test.js +0 -51
  31. package/dist/dbt/validation.test.d.ts +0 -2
  32. package/dist/dbt/validation.test.d.ts.map +0 -1
  33. package/dist/dbt/validation.test.js +0 -67
  34. package/dist/handlers/apps/appCodeFiles.test.d.ts +0 -2
  35. package/dist/handlers/apps/appCodeFiles.test.d.ts.map +0 -1
  36. package/dist/handlers/apps/appCodeFiles.test.js +0 -391
  37. package/dist/handlers/apps/appsDownload.test.d.ts +0 -2
  38. package/dist/handlers/apps/appsDownload.test.d.ts.map +0 -1
  39. package/dist/handlers/apps/appsDownload.test.js +0 -639
  40. package/dist/handlers/apps/build.test.d.ts +0 -2
  41. package/dist/handlers/apps/build.test.d.ts.map +0 -1
  42. package/dist/handlers/apps/build.test.js +0 -252
  43. package/dist/handlers/apps/createApp.test.d.ts +0 -2
  44. package/dist/handlers/apps/createApp.test.d.ts.map +0 -1
  45. package/dist/handlers/apps/createApp.test.js +0 -340
  46. package/dist/handlers/apps/pathContainment.test.d.ts +0 -2
  47. package/dist/handlers/apps/pathContainment.test.d.ts.map +0 -1
  48. package/dist/handlers/apps/pathContainment.test.js +0 -66
  49. package/dist/handlers/apps/preview.test.d.ts +0 -2
  50. package/dist/handlers/apps/preview.test.d.ts.map +0 -1
  51. package/dist/handlers/apps/preview.test.js +0 -353
  52. package/dist/handlers/apps/previewProxy.test.d.ts +0 -2
  53. package/dist/handlers/apps/previewProxy.test.d.ts.map +0 -1
  54. package/dist/handlers/apps/previewProxy.test.js +0 -178
  55. package/dist/handlers/apps/scaffolding.test.d.ts +0 -2
  56. package/dist/handlers/apps/scaffolding.test.d.ts.map +0 -1
  57. package/dist/handlers/apps/scaffolding.test.js +0 -151
  58. package/dist/handlers/apps/uploadRetry.test.d.ts +0 -2
  59. package/dist/handlers/apps/uploadRetry.test.d.ts.map +0 -1
  60. package/dist/handlers/apps/uploadRetry.test.js +0 -103
  61. package/dist/handlers/apps/validate.test.d.ts +0 -2
  62. package/dist/handlers/apps/validate.test.d.ts.map +0 -1
  63. package/dist/handlers/apps/validate.test.js +0 -526
  64. package/dist/handlers/compile.test.d.ts +0 -2
  65. package/dist/handlers/compile.test.d.ts.map +0 -1
  66. package/dist/handlers/compile.test.js +0 -151
  67. package/dist/handlers/compileProject.test.d.ts +0 -2
  68. package/dist/handlers/compileProject.test.d.ts.map +0 -1
  69. package/dist/handlers/compileProject.test.js +0 -637
  70. package/dist/handlers/compileWarehouseColumnValidation.test.d.ts +0 -2
  71. package/dist/handlers/compileWarehouseColumnValidation.test.d.ts.map +0 -1
  72. package/dist/handlers/compileWarehouseColumnValidation.test.js +0 -493
  73. package/dist/handlers/connectSnowflake.test.d.ts +0 -2
  74. package/dist/handlers/connectSnowflake.test.d.ts.map +0 -1
  75. package/dist/handlers/connectSnowflake.test.js +0 -320
  76. package/dist/handlers/contentAsCode/fileNames.test.d.ts +0 -2
  77. package/dist/handlers/contentAsCode/fileNames.test.d.ts.map +0 -1
  78. package/dist/handlers/contentAsCode/fileNames.test.js +0 -79
  79. package/dist/handlers/contentAsCode/registry.test.d.ts +0 -2
  80. package/dist/handlers/contentAsCode/registry.test.d.ts.map +0 -1
  81. package/dist/handlers/contentAsCode/registry.test.js +0 -18
  82. package/dist/handlers/contentAsCode/resource.test.d.ts +0 -2
  83. package/dist/handlers/contentAsCode/resource.test.d.ts.map +0 -1
  84. package/dist/handlers/contentAsCode/resource.test.js +0 -121
  85. package/dist/handlers/dbt/getDbtVersion.test.d.ts +0 -2
  86. package/dist/handlers/dbt/getDbtVersion.test.d.ts.map +0 -1
  87. package/dist/handlers/dbt/getDbtVersion.test.js +0 -106
  88. package/dist/handlers/deploy.test.d.ts +0 -2
  89. package/dist/handlers/deploy.test.d.ts.map +0 -1
  90. package/dist/handlers/deploy.test.js +0 -244
  91. package/dist/handlers/download.test.d.ts +0 -2
  92. package/dist/handlers/download.test.d.ts.map +0 -1
  93. package/dist/handlers/download.test.js +0 -1739
  94. package/dist/handlers/exportChartImage.test.d.ts +0 -2
  95. package/dist/handlers/exportChartImage.test.d.ts.map +0 -1
  96. package/dist/handlers/exportChartImage.test.js +0 -55
  97. package/dist/handlers/homepagesAsCode.test.d.ts +0 -2
  98. package/dist/handlers/homepagesAsCode.test.d.ts.map +0 -1
  99. package/dist/handlers/homepagesAsCode.test.js +0 -72
  100. package/dist/handlers/lint.test.d.ts +0 -2
  101. package/dist/handlers/lint.test.d.ts.map +0 -1
  102. package/dist/handlers/lint.test.js +0 -221
  103. package/dist/handlers/login.test.d.ts +0 -2
  104. package/dist/handlers/login.test.d.ts.map +0 -1
  105. package/dist/handlers/login.test.js +0 -24
  106. package/dist/handlers/metadataFile.test.d.ts +0 -2
  107. package/dist/handlers/metadataFile.test.d.ts.map +0 -1
  108. package/dist/handlers/metadataFile.test.js +0 -46
  109. package/dist/handlers/organizationContent/customRoles.test.d.ts +0 -2
  110. package/dist/handlers/organizationContent/customRoles.test.d.ts.map +0 -1
  111. package/dist/handlers/organizationContent/customRoles.test.js +0 -179
  112. package/dist/handlers/organizationContent/groups.test.d.ts +0 -2
  113. package/dist/handlers/organizationContent/groups.test.d.ts.map +0 -1
  114. package/dist/handlers/organizationContent/groups.test.js +0 -135
  115. package/dist/handlers/organizationContent/index.test.d.ts +0 -2
  116. package/dist/handlers/organizationContent/index.test.d.ts.map +0 -1
  117. package/dist/handlers/organizationContent/index.test.js +0 -212
  118. package/dist/handlers/organizationContent/themes.test.d.ts +0 -2
  119. package/dist/handlers/organizationContent/themes.test.d.ts.map +0 -1
  120. package/dist/handlers/organizationContent/themes.test.js +0 -180
  121. package/dist/handlers/organizationContent/users.test.d.ts +0 -2
  122. package/dist/handlers/organizationContent/users.test.d.ts.map +0 -1
  123. package/dist/handlers/organizationContent/users.test.js +0 -155
  124. package/dist/handlers/preAggregateAudit.test.d.ts +0 -2
  125. package/dist/handlers/preAggregateAudit.test.d.ts.map +0 -1
  126. package/dist/handlers/preAggregateAudit.test.js +0 -102
  127. package/dist/handlers/renameHandler.test.d.ts +0 -2
  128. package/dist/handlers/renameHandler.test.d.ts.map +0 -1
  129. package/dist/handlers/renameHandler.test.js +0 -189
  130. package/dist/handlers/resolveProjectFlag.test.d.ts +0 -2
  131. package/dist/handlers/resolveProjectFlag.test.d.ts.map +0 -1
  132. package/dist/handlers/resolveProjectFlag.test.js +0 -48
  133. package/dist/handlers/selectProject.test.d.ts +0 -2
  134. package/dist/handlers/selectProject.test.d.ts.map +0 -1
  135. package/dist/handlers/selectProject.test.js +0 -224
  136. package/dist/handlers/setProject.test.d.ts +0 -2
  137. package/dist/handlers/setProject.test.d.ts.map +0 -1
  138. package/dist/handlers/setProject.test.js +0 -63
  139. package/dist/handlers/slugUpdate.test.d.ts +0 -2
  140. package/dist/handlers/slugUpdate.test.d.ts.map +0 -1
  141. package/dist/handlers/slugUpdate.test.js +0 -265
  142. package/dist/handlers/timestampConversion.test.d.ts +0 -2
  143. package/dist/handlers/timestampConversion.test.d.ts.map +0 -1
  144. package/dist/handlers/timestampConversion.test.js +0 -87
  145. package/dist/handlers/upgradeCheck.test.d.ts +0 -2
  146. package/dist/handlers/upgradeCheck.test.d.ts.map +0 -1
  147. package/dist/handlers/upgradeCheck.test.js +0 -227
  148. package/dist/handlers/validate.test.d.ts +0 -2
  149. package/dist/handlers/validate.test.d.ts.map +0 -1
  150. package/dist/handlers/validate.test.js +0 -318
  151. package/dist/handlers/validateSpaceFilter.test.d.ts +0 -2
  152. package/dist/handlers/validateSpaceFilter.test.d.ts.map +0 -1
  153. package/dist/handlers/validateSpaceFilter.test.js +0 -79
  154. package/dist/handlers/warehouseConnection.test.d.ts +0 -2
  155. package/dist/handlers/warehouseConnection.test.d.ts.map +0 -1
  156. package/dist/handlers/warehouseConnection.test.js +0 -75
  157. package/dist/lightdash-config/lightdash-config.test.d.ts +0 -2
  158. package/dist/lightdash-config/lightdash-config.test.d.ts.map +0 -1
  159. package/dist/lightdash-config/lightdash-config.test.js +0 -69
  160. package/dist/prompts/fuzzySearchPrompt.test.d.ts +0 -2
  161. package/dist/prompts/fuzzySearchPrompt.test.d.ts.map +0 -1
  162. package/dist/prompts/fuzzySearchPrompt.test.js +0 -53
  163. package/dist/refsArgument.test.d.ts +0 -2
  164. package/dist/refsArgument.test.d.ts.map +0 -1
  165. package/dist/refsArgument.test.js +0 -42
  166. package/dist/releaseSafety/index.test.d.ts +0 -2
  167. package/dist/releaseSafety/index.test.d.ts.map +0 -1
  168. package/dist/releaseSafety/index.test.js +0 -154
  169. package/dist/releaseSafety/version.test.d.ts +0 -2
  170. package/dist/releaseSafety/version.test.d.ts.map +0 -1
  171. package/dist/releaseSafety/version.test.js +0 -22
  172. package/dist/skills.test.d.ts +0 -2
  173. package/dist/skills.test.d.ts.map +0 -1
  174. package/dist/skills.test.js +0 -112
  175. package/dist/terminal/contentAsCodeOutput.test.d.ts +0 -2
  176. package/dist/terminal/contentAsCodeOutput.test.d.ts.map +0 -1
  177. package/dist/terminal/contentAsCodeOutput.test.js +0 -231
@@ -1,155 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const tslib_1 = require("tslib");
4
- const common_1 = require("@lightdash/common");
5
- const fs_1 = require("fs");
6
- const yaml = tslib_1.__importStar(require("js-yaml"));
7
- const os = tslib_1.__importStar(require("os"));
8
- const path = tslib_1.__importStar(require("path"));
9
- const vitest_1 = require("vitest");
10
- const apiClient_1 = require("../dbt/apiClient");
11
- const users_1 = require("./users");
12
- vitest_1.vi.mock('../dbt/apiClient', async (importOriginal) => ({
13
- ...(await importOriginal()),
14
- lightdashApi: vitest_1.vi.fn(),
15
- }));
16
- describe('users as code', () => {
17
- let tmpDir;
18
- const user = (email, overrides = {}) => ({
19
- version: 1,
20
- email,
21
- disabled: false,
22
- role: { type: 'system', name: common_1.OrganizationMemberRole.EDITOR },
23
- ...overrides,
24
- });
25
- const writeUser = async (filename, value) => {
26
- const folder = (0, users_1.getUsersFolder)(tmpDir);
27
- await fs_1.promises.mkdir(folder, { recursive: true });
28
- await fs_1.promises.writeFile(path.join(folder, filename), yaml.dump(value, { sortKeys: true }));
29
- };
30
- beforeEach(async () => {
31
- vitest_1.vi.mocked(apiClient_1.lightdashApi).mockReset();
32
- tmpDir = await fs_1.promises.mkdtemp(path.join(os.tmpdir(), 'users-test-'));
33
- });
34
- afterEach(async () => {
35
- vitest_1.vi.restoreAllMocks();
36
- await fs_1.promises.rm(tmpDir, { recursive: true, force: true });
37
- });
38
- it('formats upload results using CRUD statuses only', () => {
39
- expect((0, users_1.formatUserUploadSummary)({
40
- created: 1,
41
- updated: 2,
42
- unchanged: 3,
43
- awaitingAuthentication: 4,
44
- invited: 5,
45
- skippedAuthenticated: 6,
46
- skippedDisabled: 7,
47
- skippedValidInvite: 8,
48
- failed: 9,
49
- failures: [],
50
- })).toBe('1 created, 2 updated, 3 unchanged, 9 failed');
51
- });
52
- it('downloads deterministic portable users and preserves unknown YAML', async () => {
53
- const folder = (0, users_1.getUsersFolder)(tmpDir);
54
- await fs_1.promises.mkdir(folder, { recursive: true });
55
- await fs_1.promises.writeFile(path.join(folder, 'stale.yml'), 'stale: true');
56
- vitest_1.vi.mocked(apiClient_1.lightdashApi).mockResolvedValueOnce({
57
- users: [
58
- user('z@example.com', {
59
- disabled: true,
60
- role: { type: 'custom', name: 'Data steward' },
61
- }),
62
- user('a@example.com'),
63
- ],
64
- });
65
- await expect((0, users_1.downloadUsers)('organization-uuid', tmpDir)).resolves.toBe(2);
66
- expect((await fs_1.promises.readdir(folder)).sort()).toStrictEqual([
67
- 'a-example-com.yml',
68
- 'stale.yml',
69
- 'z-example-com.yml',
70
- ]);
71
- expect(yaml.load(await fs_1.promises.readFile(path.join(folder, 'z-example-com.yml'), 'utf8'))).toStrictEqual({
72
- disabled: true,
73
- email: 'z@example.com',
74
- role: { name: 'Data steward', type: 'custom' },
75
- version: 1,
76
- });
77
- });
78
- it('rejects case-insensitive duplicate emails before upload', async () => {
79
- await writeUser('one.yml', user('duplicate@example.com'));
80
- await writeUser('two.yml', user('DUPLICATE@example.com'));
81
- await expect((0, users_1.readUserFiles)(tmpDir)).rejects.toThrow('Duplicate user email "duplicate@example.com"');
82
- expect(apiClient_1.lightdashApi).not.toHaveBeenCalled();
83
- });
84
- it('is a backward-compatible no-op when the users folder is missing', async () => {
85
- await expect((0, users_1.uploadUsers)('organization-uuid', tmpDir)).resolves.toMatchObject({
86
- created: 0,
87
- updated: 0,
88
- unchanged: 0,
89
- failed: 0,
90
- });
91
- expect(apiClient_1.lightdashApi).not.toHaveBeenCalled();
92
- });
93
- it('does not request invitations by default', async () => {
94
- await writeUser('user.yml', user('person@example.com'));
95
- vitest_1.vi.mocked(apiClient_1.lightdashApi)
96
- .mockResolvedValueOnce({ users: [] })
97
- .mockResolvedValueOnce({
98
- action: common_1.PromotionAction.CREATE,
99
- lifecycle: common_1.UserAsCodeLifecycleStatus.AWAITING_AUTHENTICATION,
100
- invitation: common_1.UserAsCodeInvitationStatus.NOT_REQUESTED,
101
- });
102
- const summary = await (0, users_1.uploadUsers)('organization-uuid', tmpDir);
103
- expect(summary).toMatchObject({
104
- created: 1,
105
- awaitingAuthentication: 1,
106
- invited: 0,
107
- failed: 0,
108
- });
109
- expect(apiClient_1.lightdashApi).toHaveBeenNthCalledWith(2, {
110
- method: 'POST',
111
- url: '/api/v2/orgs/organization-uuid/code/users',
112
- body: expect.any(String),
113
- });
114
- });
115
- it('passes sendInvite and reports invitation outcomes', async () => {
116
- await writeUser('user.yml', user('person@example.com'));
117
- vitest_1.vi.mocked(apiClient_1.lightdashApi)
118
- .mockResolvedValueOnce({ users: [] })
119
- .mockResolvedValueOnce({
120
- action: common_1.PromotionAction.CREATE,
121
- lifecycle: common_1.UserAsCodeLifecycleStatus.AWAITING_AUTHENTICATION,
122
- invitation: common_1.UserAsCodeInvitationStatus.SENT,
123
- });
124
- const summary = await (0, users_1.uploadUsers)('organization-uuid', tmpDir, true);
125
- expect(summary.invited).toBe(1);
126
- expect(apiClient_1.lightdashApi).toHaveBeenNthCalledWith(2, {
127
- method: 'POST',
128
- url: '/api/v2/orgs/organization-uuid/code/users?sendInvite=true',
129
- body: expect.any(String),
130
- });
131
- });
132
- it('promotes an enabled admin before demoting the current admin', async () => {
133
- const currentAdmin = user('current@example.com', {
134
- role: { type: 'system', name: common_1.OrganizationMemberRole.ADMIN },
135
- });
136
- const desiredAdmin = user('new@example.com', {
137
- role: { type: 'system', name: common_1.OrganizationMemberRole.ADMIN },
138
- });
139
- const desiredDemotion = user('current@example.com');
140
- await writeUser('a-demote.yml', desiredDemotion);
141
- await writeUser('z-promote.yml', desiredAdmin);
142
- vitest_1.vi.mocked(apiClient_1.lightdashApi)
143
- .mockResolvedValueOnce({ users: [currentAdmin] })
144
- .mockResolvedValue({
145
- action: common_1.PromotionAction.UPDATE,
146
- lifecycle: common_1.UserAsCodeLifecycleStatus.READY,
147
- invitation: common_1.UserAsCodeInvitationStatus.NOT_REQUESTED,
148
- });
149
- await (0, users_1.uploadUsers)('organization-uuid', tmpDir);
150
- const firstBody = JSON.parse(vitest_1.vi.mocked(apiClient_1.lightdashApi).mock.calls[1][0].body);
151
- const secondBody = JSON.parse(vitest_1.vi.mocked(apiClient_1.lightdashApi).mock.calls[2][0].body);
152
- expect(firstBody.email).toBe('new@example.com');
153
- expect(secondBody.email).toBe('current@example.com');
154
- });
155
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=preAggregateAudit.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"preAggregateAudit.test.d.ts","sourceRoot":"","sources":["../../src/handlers/preAggregateAudit.test.ts"],"names":[],"mappings":""}
@@ -1,102 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const common_1 = require("@lightdash/common");
4
- const preAggregateAudit_1 = require("./preAggregateAudit");
5
- vi.mock('./dbt/apiClient', () => ({
6
- lightdashApi: vi.fn(),
7
- checkLightdashVersion: vi.fn(),
8
- }));
9
- const { renderSingle, exitIfFailOnMiss } = preAggregateAudit_1.testHelpers;
10
- const makeAudit = (partial = {}) => ({
11
- dashboardUuid: 'd-1',
12
- dashboardSlug: 'd1',
13
- dashboardName: 'D1',
14
- tabs: [{ tabUuid: null, tabName: null, tiles: [] }],
15
- summary: { hitCount: 0, missCount: 0, ineligibleCount: 0 },
16
- ...partial,
17
- });
18
- describe('renderSingle JSON mode', () => {
19
- it('prints DashboardPreAggregateAudit as JSON', () => {
20
- const audit = makeAudit({
21
- summary: { hitCount: 2, missCount: 1, ineligibleCount: 0 },
22
- });
23
- const spy = vi
24
- .spyOn(process.stdout, 'write')
25
- .mockImplementation(() => true);
26
- renderSingle(audit, { json: true, verbose: false });
27
- expect(spy).toHaveBeenCalledWith(`${JSON.stringify(audit, null, 2)}\n`);
28
- spy.mockRestore();
29
- });
30
- });
31
- describe('renderSingle human output', () => {
32
- const missTileWithoutChartName = {
33
- status: 'miss',
34
- tileUuid: 't-1',
35
- tileName: 'Orders over time',
36
- tileType: common_1.DashboardTileTypes.SAVED_CHART,
37
- savedChartUuid: 'sc-1',
38
- exploreName: 'orders',
39
- miss: { reason: common_1.PreAggregateMissReason.NO_PRE_AGGREGATES_DEFINED },
40
- missFieldLabel: null,
41
- };
42
- it('does not crash when tiles lack chartName/exploreLabel', () => {
43
- const audit = makeAudit({
44
- summary: { hitCount: 0, missCount: 1, ineligibleCount: 0 },
45
- tabs: [
46
- {
47
- tabUuid: null,
48
- tabName: null,
49
- tiles: [missTileWithoutChartName],
50
- },
51
- ],
52
- });
53
- const writes = [];
54
- const spy = vi
55
- .spyOn(process.stdout, 'write')
56
- .mockImplementation((chunk) => {
57
- writes.push(String(chunk));
58
- return true;
59
- });
60
- expect(() => renderSingle(audit, { json: false, verbose: false })).not.toThrow();
61
- expect(writes.join('')).toContain('Orders over time');
62
- spy.mockRestore();
63
- });
64
- });
65
- describe('exitIfFailOnMiss', () => {
66
- it('does nothing if flag unset', () => {
67
- const spy = vi
68
- .spyOn(process, 'exit')
69
- .mockImplementation(() => undefined);
70
- exitIfFailOnMiss([
71
- makeAudit({
72
- summary: { hitCount: 0, missCount: 5, ineligibleCount: 0 },
73
- }),
74
- ], false);
75
- expect(spy).not.toHaveBeenCalled();
76
- spy.mockRestore();
77
- });
78
- it('exits 1 when flag set and any miss present', () => {
79
- const spy = vi
80
- .spyOn(process, 'exit')
81
- .mockImplementation(() => undefined);
82
- exitIfFailOnMiss([
83
- makeAudit({
84
- summary: { hitCount: 1, missCount: 2, ineligibleCount: 0 },
85
- }),
86
- ], true);
87
- expect(spy).toHaveBeenCalledWith(1);
88
- spy.mockRestore();
89
- });
90
- it('does not exit when flag set and no misses', () => {
91
- const spy = vi
92
- .spyOn(process, 'exit')
93
- .mockImplementation(() => undefined);
94
- exitIfFailOnMiss([
95
- makeAudit({
96
- summary: { hitCount: 3, missCount: 0, ineligibleCount: 2 },
97
- }),
98
- ], true);
99
- expect(spy).not.toHaveBeenCalled();
100
- spy.mockRestore();
101
- });
102
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=renameHandler.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"renameHandler.test.d.ts","sourceRoot":"","sources":["../../src/handlers/renameHandler.test.ts"],"names":[],"mappings":""}
@@ -1,189 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const tslib_1 = require("tslib");
4
- const common_1 = require("@lightdash/common");
5
- const analytics_1 = require("../analytics/analytics");
6
- const config_1 = require("../config");
7
- const globalState_1 = tslib_1.__importDefault(require("../globalState"));
8
- const apiClient_1 = require("./dbt/apiClient");
9
- const refresh_1 = require("./dbt/refresh");
10
- const renameHandler_1 = require("./renameHandler");
11
- vi.mock('../analytics/analytics');
12
- vi.mock('../config');
13
- vi.mock('./dbt/apiClient');
14
- vi.mock('./dbt/refresh');
15
- const baseOptions = {
16
- verbose: false,
17
- type: common_1.RenameType.FIELD,
18
- project: '11111111-1111-4111-8111-111111111111',
19
- from: 'old_name',
20
- to: 'new_name',
21
- dryRun: false,
22
- assumeYes: true,
23
- list: false,
24
- validate: true,
25
- };
26
- const emptyResults = {
27
- charts: [],
28
- dashboards: [],
29
- alerts: [],
30
- dashboardSchedulers: [],
31
- };
32
- const RENAME_JOB_ID = 'rename-job-id';
33
- const VALIDATION_JOB_ID = 'validation-job-id';
34
- const PREVIEW_PROJECT = '33333333-3333-4333-8333-333333333333';
35
- describe('renameHandler follow-up validation', () => {
36
- let errorOutput;
37
- const mockApi = (failingJobId) => {
38
- vi.mocked(apiClient_1.lightdashApi).mockImplementation(async ({ method, url }) => {
39
- if (method === 'POST' && url.endsWith('/rename')) {
40
- return { jobId: RENAME_JOB_ID };
41
- }
42
- if (method === 'POST' && url.endsWith('/validate')) {
43
- return { jobId: VALIDATION_JOB_ID };
44
- }
45
- if (url.includes(`/schedulers/job/${failingJobId}/status`)) {
46
- return {
47
- status: common_1.SchedulerJobStatus.ERROR,
48
- details: { error: 'job blew up' },
49
- };
50
- }
51
- if (url.includes('/schedulers/job/')) {
52
- return {
53
- status: common_1.SchedulerJobStatus.COMPLETED,
54
- details: { results: emptyResults },
55
- };
56
- }
57
- if (url.includes('/validate?jobId=')) {
58
- return [];
59
- }
60
- if (method === 'GET' &&
61
- url === `/api/v1/projects/${PREVIEW_PROJECT}`) {
62
- return {
63
- projectUuid: PREVIEW_PROJECT,
64
- type: common_1.ProjectType.PREVIEW,
65
- };
66
- }
67
- throw new Error(`Unexpected API call: ${method} ${url}`);
68
- });
69
- };
70
- beforeEach(() => {
71
- vi.clearAllMocks();
72
- vi.stubEnv('LIGHTDASH_PROJECT', undefined);
73
- vi.mocked(apiClient_1.checkLightdashVersion).mockResolvedValue(undefined);
74
- vi.mocked(config_1.getConfig).mockResolvedValue({
75
- context: {
76
- apiKey: 'test-key',
77
- serverUrl: 'http://localhost',
78
- project: '11111111-1111-4111-8111-111111111111',
79
- },
80
- });
81
- vi.mocked(refresh_1.getProject).mockResolvedValue({
82
- name: 'test project',
83
- });
84
- errorOutput = [];
85
- vi.spyOn(console, 'error').mockImplementation((...args) => {
86
- errorOutput.push(args.map(String).join(' '));
87
- });
88
- vi.spyOn(console, 'info').mockImplementation(() => { });
89
- });
90
- afterEach(() => {
91
- vi.restoreAllMocks();
92
- vi.unstubAllEnvs();
93
- });
94
- const trackedEvents = () => vi.mocked(analytics_1.LightdashAnalytics.track).mock.calls.map(([payload]) => ({
95
- event: payload.event,
96
- properties: payload.properties,
97
- }));
98
- test.each([undefined, baseOptions.project])('targets the environment project unless --project overrides it (%s)', async (explicitProject) => {
99
- const envProject = '22222222-2222-4222-8222-222222222222';
100
- vi.stubEnv('LIGHTDASH_PROJECT', envProject);
101
- vi.spyOn(globalState_1.default, 'isNonInteractive').mockReturnValue(true);
102
- vi.mocked(config_1.getConfig).mockResolvedValue({
103
- context: {
104
- apiKey: 'test-key',
105
- serverUrl: 'http://localhost',
106
- project: envProject,
107
- previewProject: PREVIEW_PROJECT,
108
- previewName: 'Stale preview',
109
- },
110
- });
111
- mockApi(null);
112
- await (0, renameHandler_1.renameHandler)({ ...baseOptions, project: explicitProject });
113
- const expectedProject = explicitProject || envProject;
114
- expect(apiClient_1.lightdashApi).toHaveBeenCalledWith(expect.objectContaining({
115
- method: 'POST',
116
- url: `/api/v1/projects/${expectedProject}/rename`,
117
- }));
118
- const output = errorOutput.join('\n');
119
- expect(output).toContain(`Renaming in project: ${expectedProject}`);
120
- if (explicitProject) {
121
- expect(output).not.toContain('Stale preview');
122
- }
123
- else {
124
- expect(output).toContain('active preview "Stale preview" ignored');
125
- }
126
- });
127
- test('reports a failed validation job as a validation failure, not a rename failure', async () => {
128
- mockApi(VALIDATION_JOB_ID);
129
- await (0, renameHandler_1.renameHandler)({ ...baseOptions });
130
- const output = errorOutput.join('\n');
131
- expect(output).toContain('Rename completed');
132
- expect(output).toContain('Validation failed: job blew up');
133
- expect(output).not.toContain('Rename failed');
134
- expect(output).not.toContain('unexpected error');
135
- });
136
- test('counts a rename whose follow-up validation failed as completed', async () => {
137
- mockApi(VALIDATION_JOB_ID);
138
- await (0, renameHandler_1.renameHandler)({ ...baseOptions });
139
- expect(trackedEvents()).toEqual([
140
- {
141
- event: 'rename.completed',
142
- properties: expect.objectContaining({
143
- validationStatus: 'failed',
144
- }),
145
- },
146
- ]);
147
- });
148
- test('still reports a failed rename job as a rename failure', async () => {
149
- mockApi(RENAME_JOB_ID);
150
- await (0, renameHandler_1.renameHandler)({ ...baseOptions });
151
- const output = errorOutput.join('\n');
152
- expect(output).toContain('Rename failed: job blew up');
153
- expect(output).not.toContain('Validation failed');
154
- expect(trackedEvents()).toEqual([
155
- { event: 'rename.error', properties: expect.anything() },
156
- ]);
157
- });
158
- test('records a passing validation on the completed event', async () => {
159
- mockApi(null);
160
- await (0, renameHandler_1.renameHandler)({ ...baseOptions });
161
- expect(trackedEvents()).toEqual([
162
- {
163
- event: 'rename.completed',
164
- properties: expect.objectContaining({
165
- validationStatus: 'passed',
166
- }),
167
- },
168
- ]);
169
- });
170
- test('does not run the validation job when --validate is not set', async () => {
171
- mockApi(null);
172
- await (0, renameHandler_1.renameHandler)({ ...baseOptions, validate: false });
173
- const validationCalls = vi
174
- .mocked(apiClient_1.lightdashApi)
175
- .mock.calls.filter(([{ url }]) => url.endsWith('/validate'));
176
- expect(validationCalls).toEqual([]);
177
- const output = errorOutput.join('\n');
178
- expect(output).not.toContain('failed');
179
- expect(output).not.toContain('unexpected error');
180
- expect(trackedEvents()).toEqual([
181
- {
182
- event: 'rename.completed',
183
- properties: expect.objectContaining({
184
- validationStatus: 'skipped',
185
- }),
186
- },
187
- ]);
188
- });
189
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=resolveProjectFlag.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"resolveProjectFlag.test.d.ts","sourceRoot":"","sources":["../../src/handlers/resolveProjectFlag.test.ts"],"names":[],"mappings":""}
@@ -1,48 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const common_1 = require("@lightdash/common");
4
- const apiClient_1 = require("./dbt/apiClient");
5
- const resolveProjectFlag_1 = require("./resolveProjectFlag");
6
- vi.mock('./dbt/apiClient', () => ({
7
- lightdashApi: vi.fn(),
8
- }));
9
- const mockLightdashApi = apiClient_1.lightdashApi;
10
- const PROJECT_UUID = '00000000-0000-0000-0000-000000000001';
11
- const OTHER_UUID = '00000000-0000-0000-0000-000000000002';
12
- const mockOrgProjects = (projects) => {
13
- mockLightdashApi.mockResolvedValueOnce(projects.map((project) => ({
14
- ...project,
15
- type: common_1.ProjectType.DEFAULT,
16
- })));
17
- };
18
- describe('resolveProjectFlag', () => {
19
- afterEach(() => {
20
- vi.clearAllMocks();
21
- });
22
- it('returns a UUID as-is without calling the API', async () => {
23
- await expect((0, resolveProjectFlag_1.resolveProjectFlag)(PROJECT_UUID)).resolves.toBe(PROJECT_UUID);
24
- expect(mockLightdashApi).not.toHaveBeenCalled();
25
- });
26
- it('resolves a slug to the matching project UUID', async () => {
27
- mockOrgProjects([
28
- { projectUuid: OTHER_UUID, slug: 'other', name: 'Other' },
29
- { projectUuid: PROJECT_UUID, slug: 'jaffle-shop', name: 'Jaffle' },
30
- ]);
31
- await expect((0, resolveProjectFlag_1.resolveProjectFlag)('jaffle-shop')).resolves.toBe(PROJECT_UUID);
32
- expect(mockLightdashApi).toHaveBeenCalledWith(expect.objectContaining({ url: '/api/v1/org/projects' }));
33
- });
34
- it('fails with an actionable error for an unknown slug', async () => {
35
- mockOrgProjects([
36
- { projectUuid: PROJECT_UUID, slug: 'jaffle-shop', name: 'Jaffle' },
37
- { projectUuid: OTHER_UUID, name: 'No slug' },
38
- ]);
39
- await expect((0, resolveProjectFlag_1.resolveProjectFlag)('missing')).rejects.toThrow(common_1.ParameterError);
40
- });
41
- it('fails when a slug matches more than one project', async () => {
42
- mockOrgProjects([
43
- { projectUuid: PROJECT_UUID, slug: 'dup', name: 'A' },
44
- { projectUuid: OTHER_UUID, slug: 'dup', name: 'B' },
45
- ]);
46
- await expect((0, resolveProjectFlag_1.resolveProjectFlag)('dup')).rejects.toThrow(/more than one project/);
47
- });
48
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=selectProject.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"selectProject.test.d.ts","sourceRoot":"","sources":["../../src/handlers/selectProject.test.ts"],"names":[],"mappings":""}