@lightdash/cli 2.228.1 → 2.229.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.
- package/dist/.tsbuildinfo.build +1 -0
- package/package.json +4 -4
- package/dist/.tsbuildinfo +0 -1
- package/dist/config.test.d.ts +0 -2
- package/dist/config.test.d.ts.map +0 -1
- package/dist/config.test.js +0 -72
- package/dist/dbt/context.test.d.ts +0 -2
- package/dist/dbt/context.test.d.ts.map +0 -1
- package/dist/dbt/context.test.js +0 -152
- package/dist/dbt/manifest.test.d.ts +0 -2
- package/dist/dbt/manifest.test.d.ts.map +0 -1
- package/dist/dbt/manifest.test.js +0 -170
- package/dist/dbt/models.test.d.ts +0 -2
- package/dist/dbt/models.test.d.ts.map +0 -1
- package/dist/dbt/models.test.js +0 -139
- package/dist/dbt/profiles.test.d.ts +0 -2
- package/dist/dbt/profiles.test.d.ts.map +0 -1
- package/dist/dbt/profiles.test.js +0 -50
- package/dist/dbt/targets/athena.test.d.ts +0 -2
- package/dist/dbt/targets/athena.test.d.ts.map +0 -1
- package/dist/dbt/targets/athena.test.js +0 -78
- package/dist/dbt/targets/duckdb.test.d.ts +0 -2
- package/dist/dbt/targets/duckdb.test.d.ts.map +0 -1
- package/dist/dbt/targets/duckdb.test.js +0 -149
- package/dist/dbt/targets/redshift.test.d.ts +0 -2
- package/dist/dbt/targets/redshift.test.d.ts.map +0 -1
- package/dist/dbt/targets/redshift.test.js +0 -198
- package/dist/dbt/templating.test.d.ts +0 -2
- package/dist/dbt/templating.test.d.ts.map +0 -1
- package/dist/dbt/templating.test.js +0 -51
- package/dist/dbt/validation.test.d.ts +0 -2
- package/dist/dbt/validation.test.d.ts.map +0 -1
- package/dist/dbt/validation.test.js +0 -67
- package/dist/handlers/apps/appCodeFiles.test.d.ts +0 -2
- package/dist/handlers/apps/appCodeFiles.test.d.ts.map +0 -1
- package/dist/handlers/apps/appCodeFiles.test.js +0 -391
- package/dist/handlers/apps/appsDownload.test.d.ts +0 -2
- package/dist/handlers/apps/appsDownload.test.d.ts.map +0 -1
- package/dist/handlers/apps/appsDownload.test.js +0 -639
- package/dist/handlers/apps/build.test.d.ts +0 -2
- package/dist/handlers/apps/build.test.d.ts.map +0 -1
- package/dist/handlers/apps/build.test.js +0 -252
- package/dist/handlers/apps/createApp.test.d.ts +0 -2
- package/dist/handlers/apps/createApp.test.d.ts.map +0 -1
- package/dist/handlers/apps/createApp.test.js +0 -340
- package/dist/handlers/apps/pathContainment.test.d.ts +0 -2
- package/dist/handlers/apps/pathContainment.test.d.ts.map +0 -1
- package/dist/handlers/apps/pathContainment.test.js +0 -66
- package/dist/handlers/apps/preview.test.d.ts +0 -2
- package/dist/handlers/apps/preview.test.d.ts.map +0 -1
- package/dist/handlers/apps/preview.test.js +0 -353
- package/dist/handlers/apps/previewProxy.test.d.ts +0 -2
- package/dist/handlers/apps/previewProxy.test.d.ts.map +0 -1
- package/dist/handlers/apps/previewProxy.test.js +0 -178
- package/dist/handlers/apps/scaffolding.test.d.ts +0 -2
- package/dist/handlers/apps/scaffolding.test.d.ts.map +0 -1
- package/dist/handlers/apps/scaffolding.test.js +0 -151
- package/dist/handlers/apps/uploadRetry.test.d.ts +0 -2
- package/dist/handlers/apps/uploadRetry.test.d.ts.map +0 -1
- package/dist/handlers/apps/uploadRetry.test.js +0 -103
- package/dist/handlers/apps/validate.test.d.ts +0 -2
- package/dist/handlers/apps/validate.test.d.ts.map +0 -1
- package/dist/handlers/apps/validate.test.js +0 -526
- package/dist/handlers/compile.test.d.ts +0 -2
- package/dist/handlers/compile.test.d.ts.map +0 -1
- package/dist/handlers/compile.test.js +0 -151
- package/dist/handlers/compileProject.test.d.ts +0 -2
- package/dist/handlers/compileProject.test.d.ts.map +0 -1
- package/dist/handlers/compileProject.test.js +0 -637
- package/dist/handlers/compileWarehouseColumnValidation.test.d.ts +0 -2
- package/dist/handlers/compileWarehouseColumnValidation.test.d.ts.map +0 -1
- package/dist/handlers/compileWarehouseColumnValidation.test.js +0 -493
- package/dist/handlers/connectSnowflake.test.d.ts +0 -2
- package/dist/handlers/connectSnowflake.test.d.ts.map +0 -1
- package/dist/handlers/connectSnowflake.test.js +0 -320
- package/dist/handlers/contentAsCode/fileNames.test.d.ts +0 -2
- package/dist/handlers/contentAsCode/fileNames.test.d.ts.map +0 -1
- package/dist/handlers/contentAsCode/fileNames.test.js +0 -79
- package/dist/handlers/contentAsCode/registry.test.d.ts +0 -2
- package/dist/handlers/contentAsCode/registry.test.d.ts.map +0 -1
- package/dist/handlers/contentAsCode/registry.test.js +0 -18
- package/dist/handlers/contentAsCode/resource.test.d.ts +0 -2
- package/dist/handlers/contentAsCode/resource.test.d.ts.map +0 -1
- package/dist/handlers/contentAsCode/resource.test.js +0 -121
- package/dist/handlers/dbt/getDbtVersion.test.d.ts +0 -2
- package/dist/handlers/dbt/getDbtVersion.test.d.ts.map +0 -1
- package/dist/handlers/dbt/getDbtVersion.test.js +0 -106
- package/dist/handlers/deploy.test.d.ts +0 -2
- package/dist/handlers/deploy.test.d.ts.map +0 -1
- package/dist/handlers/deploy.test.js +0 -244
- package/dist/handlers/download.test.d.ts +0 -2
- package/dist/handlers/download.test.d.ts.map +0 -1
- package/dist/handlers/download.test.js +0 -1739
- package/dist/handlers/exportChartImage.test.d.ts +0 -2
- package/dist/handlers/exportChartImage.test.d.ts.map +0 -1
- package/dist/handlers/exportChartImage.test.js +0 -55
- package/dist/handlers/homepagesAsCode.test.d.ts +0 -2
- package/dist/handlers/homepagesAsCode.test.d.ts.map +0 -1
- package/dist/handlers/homepagesAsCode.test.js +0 -72
- package/dist/handlers/lint.test.d.ts +0 -2
- package/dist/handlers/lint.test.d.ts.map +0 -1
- package/dist/handlers/lint.test.js +0 -221
- package/dist/handlers/login.test.d.ts +0 -2
- package/dist/handlers/login.test.d.ts.map +0 -1
- package/dist/handlers/login.test.js +0 -24
- package/dist/handlers/metadataFile.test.d.ts +0 -2
- package/dist/handlers/metadataFile.test.d.ts.map +0 -1
- package/dist/handlers/metadataFile.test.js +0 -46
- package/dist/handlers/organizationContent/customRoles.test.d.ts +0 -2
- package/dist/handlers/organizationContent/customRoles.test.d.ts.map +0 -1
- package/dist/handlers/organizationContent/customRoles.test.js +0 -179
- package/dist/handlers/organizationContent/groups.test.d.ts +0 -2
- package/dist/handlers/organizationContent/groups.test.d.ts.map +0 -1
- package/dist/handlers/organizationContent/groups.test.js +0 -135
- package/dist/handlers/organizationContent/index.test.d.ts +0 -2
- package/dist/handlers/organizationContent/index.test.d.ts.map +0 -1
- package/dist/handlers/organizationContent/index.test.js +0 -212
- package/dist/handlers/organizationContent/themes.test.d.ts +0 -2
- package/dist/handlers/organizationContent/themes.test.d.ts.map +0 -1
- package/dist/handlers/organizationContent/themes.test.js +0 -180
- package/dist/handlers/organizationContent/users.test.d.ts +0 -2
- package/dist/handlers/organizationContent/users.test.d.ts.map +0 -1
- package/dist/handlers/organizationContent/users.test.js +0 -155
- package/dist/handlers/preAggregateAudit.test.d.ts +0 -2
- package/dist/handlers/preAggregateAudit.test.d.ts.map +0 -1
- package/dist/handlers/preAggregateAudit.test.js +0 -102
- package/dist/handlers/renameHandler.test.d.ts +0 -2
- package/dist/handlers/renameHandler.test.d.ts.map +0 -1
- package/dist/handlers/renameHandler.test.js +0 -189
- package/dist/handlers/resolveProjectFlag.test.d.ts +0 -2
- package/dist/handlers/resolveProjectFlag.test.d.ts.map +0 -1
- package/dist/handlers/resolveProjectFlag.test.js +0 -48
- package/dist/handlers/selectProject.test.d.ts +0 -2
- package/dist/handlers/selectProject.test.d.ts.map +0 -1
- package/dist/handlers/selectProject.test.js +0 -224
- package/dist/handlers/setProject.test.d.ts +0 -2
- package/dist/handlers/setProject.test.d.ts.map +0 -1
- package/dist/handlers/setProject.test.js +0 -63
- package/dist/handlers/slugUpdate.test.d.ts +0 -2
- package/dist/handlers/slugUpdate.test.d.ts.map +0 -1
- package/dist/handlers/slugUpdate.test.js +0 -265
- package/dist/handlers/timestampConversion.test.d.ts +0 -2
- package/dist/handlers/timestampConversion.test.d.ts.map +0 -1
- package/dist/handlers/timestampConversion.test.js +0 -87
- package/dist/handlers/upgradeCheck.test.d.ts +0 -2
- package/dist/handlers/upgradeCheck.test.d.ts.map +0 -1
- package/dist/handlers/upgradeCheck.test.js +0 -227
- package/dist/handlers/validate.test.d.ts +0 -2
- package/dist/handlers/validate.test.d.ts.map +0 -1
- package/dist/handlers/validate.test.js +0 -318
- package/dist/handlers/validateSpaceFilter.test.d.ts +0 -2
- package/dist/handlers/validateSpaceFilter.test.d.ts.map +0 -1
- package/dist/handlers/validateSpaceFilter.test.js +0 -79
- package/dist/handlers/warehouseConnection.test.d.ts +0 -2
- package/dist/handlers/warehouseConnection.test.d.ts.map +0 -1
- package/dist/handlers/warehouseConnection.test.js +0 -75
- package/dist/lightdash-config/lightdash-config.test.d.ts +0 -2
- package/dist/lightdash-config/lightdash-config.test.d.ts.map +0 -1
- package/dist/lightdash-config/lightdash-config.test.js +0 -69
- package/dist/prompts/fuzzySearchPrompt.test.d.ts +0 -2
- package/dist/prompts/fuzzySearchPrompt.test.d.ts.map +0 -1
- package/dist/prompts/fuzzySearchPrompt.test.js +0 -53
- package/dist/refsArgument.test.d.ts +0 -2
- package/dist/refsArgument.test.d.ts.map +0 -1
- package/dist/refsArgument.test.js +0 -42
- package/dist/releaseSafety/index.test.d.ts +0 -2
- package/dist/releaseSafety/index.test.d.ts.map +0 -1
- package/dist/releaseSafety/index.test.js +0 -154
- package/dist/releaseSafety/version.test.d.ts +0 -2
- package/dist/releaseSafety/version.test.d.ts.map +0 -1
- package/dist/releaseSafety/version.test.js +0 -22
- package/dist/skills.test.d.ts +0 -2
- package/dist/skills.test.d.ts.map +0 -1
- package/dist/skills.test.js +0 -112
- package/dist/terminal/contentAsCodeOutput.test.d.ts +0 -2
- package/dist/terminal/contentAsCodeOutput.test.d.ts.map +0 -1
- package/dist/terminal/contentAsCodeOutput.test.js +0 -231
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"upgradeCheck.test.d.ts","sourceRoot":"","sources":["../../src/handlers/upgradeCheck.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const commander_1 = require("commander");
|
|
4
|
-
const node_fetch_1 = require("node-fetch");
|
|
5
|
-
const releaseSafety_1 = require("../releaseSafety");
|
|
6
|
-
const upgradeCheck_1 = require("./upgradeCheck");
|
|
7
|
-
const safeIndex = {
|
|
8
|
-
schemaVersion: releaseSafety_1.INDEX_SCHEMA_VERSION,
|
|
9
|
-
generatedAt: '2026-08-11T00:00:00.000Z',
|
|
10
|
-
backfillFloorVersion: null,
|
|
11
|
-
entries: [
|
|
12
|
-
{
|
|
13
|
-
version: '1.114.0',
|
|
14
|
-
previousVersion: '1.113.0',
|
|
15
|
-
releaseDate: '2026-07-31T00:00:00.000Z',
|
|
16
|
-
rollingUpdateSafe: true,
|
|
17
|
-
requiredStops: [],
|
|
18
|
-
minPreviousVersion: null,
|
|
19
|
-
backfilled: true,
|
|
20
|
-
syntheticRequiredStop: false,
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
version: '1.115.0',
|
|
24
|
-
previousVersion: '1.114.0',
|
|
25
|
-
releaseDate: '2026-08-01T00:00:00.000Z',
|
|
26
|
-
rollingUpdateSafe: true,
|
|
27
|
-
requiredStops: [],
|
|
28
|
-
minPreviousVersion: null,
|
|
29
|
-
backfilled: true,
|
|
30
|
-
syntheticRequiredStop: false,
|
|
31
|
-
},
|
|
32
|
-
],
|
|
33
|
-
};
|
|
34
|
-
class ExitError extends Error {
|
|
35
|
-
code;
|
|
36
|
-
constructor(code) {
|
|
37
|
-
super(`exit ${code}`);
|
|
38
|
-
this.code = code;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
function responseFor(index) {
|
|
42
|
-
return new node_fetch_1.Response(JSON.stringify(index), {
|
|
43
|
-
status: 200,
|
|
44
|
-
headers: { 'content-type': 'application/json' },
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
function dependenciesFor(index) {
|
|
48
|
-
const fetchIndex = vi
|
|
49
|
-
.fn()
|
|
50
|
-
.mockResolvedValue(responseFor(index));
|
|
51
|
-
const output = [];
|
|
52
|
-
return {
|
|
53
|
-
dependencies: {
|
|
54
|
-
fetch: fetchIndex,
|
|
55
|
-
writeOutput: (message) => output.push(message),
|
|
56
|
-
exit: (code) => {
|
|
57
|
-
throw new ExitError(code);
|
|
58
|
-
},
|
|
59
|
-
},
|
|
60
|
-
fetchIndex,
|
|
61
|
-
output,
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
describe('upgradeCheckHandler', () => {
|
|
65
|
-
it('fetches the public index without authentication context', async () => {
|
|
66
|
-
const { dependencies, fetchIndex } = dependenciesFor(safeIndex);
|
|
67
|
-
await (0, upgradeCheck_1.upgradeCheckHandler)({ from: '1.114.0', to: '1.115.0' }, dependencies);
|
|
68
|
-
expect(fetchIndex).toHaveBeenCalledTimes(1);
|
|
69
|
-
expect(fetchIndex).toHaveBeenCalledWith(upgradeCheck_1.RELEASE_SAFETY_INDEX_URL);
|
|
70
|
-
expect(fetchIndex.mock.calls[0]).toHaveLength(1);
|
|
71
|
-
});
|
|
72
|
-
it('renders a boundary-precise gap and exits non-zero', async () => {
|
|
73
|
-
const gapIndex = {
|
|
74
|
-
...safeIndex,
|
|
75
|
-
entries: [
|
|
76
|
-
...safeIndex.entries,
|
|
77
|
-
{
|
|
78
|
-
...safeIndex.entries[0],
|
|
79
|
-
version: '1.121.0',
|
|
80
|
-
previousVersion: '1.120.1',
|
|
81
|
-
releaseDate: '2026-08-07T00:00:00.000Z',
|
|
82
|
-
},
|
|
83
|
-
],
|
|
84
|
-
};
|
|
85
|
-
const { dependencies, output } = dependenciesFor(gapIndex);
|
|
86
|
-
await expect((0, upgradeCheck_1.upgradeCheckHandler)({ from: '1.114.0', to: '1.121.0' }, dependencies)).rejects.toMatchObject({ code: 1 });
|
|
87
|
-
expect(output.join('\n')).toContain('after 1.115.0 and before 1.121.0');
|
|
88
|
-
expect(output.join('\n')).toContain('Verdict: UNSAFE');
|
|
89
|
-
});
|
|
90
|
-
it('fails closed when the source version is not indexed', async () => {
|
|
91
|
-
const indexWithMissingSource = {
|
|
92
|
-
...safeIndex,
|
|
93
|
-
entries: safeIndex.entries.filter((entry) => entry.version !== '1.114.0'),
|
|
94
|
-
};
|
|
95
|
-
const { dependencies, output } = dependenciesFor(indexWithMissingSource);
|
|
96
|
-
await expect((0, upgradeCheck_1.upgradeCheckHandler)({ from: '1.114.0', to: '1.115.0' }, dependencies)).rejects.toMatchObject({ code: 1 });
|
|
97
|
-
expect(output[0]).toContain('version 1.114.0 is not present in the release-safety index');
|
|
98
|
-
});
|
|
99
|
-
it('emits the stable JSON shape without human output', async () => {
|
|
100
|
-
const { dependencies, output } = dependenciesFor(safeIndex);
|
|
101
|
-
await (0, upgradeCheck_1.upgradeCheckHandler)({ from: '1.114.0', to: '1.115.0', json: true }, dependencies);
|
|
102
|
-
expect(JSON.parse(output[0])).toEqual({
|
|
103
|
-
fromVersion: '1.114.0',
|
|
104
|
-
toVersion: '1.115.0',
|
|
105
|
-
direction: 'upgrade',
|
|
106
|
-
safe: true,
|
|
107
|
-
verdict: true,
|
|
108
|
-
requiredStops: [],
|
|
109
|
-
minPreviousVersion: null,
|
|
110
|
-
coveredVersions: ['1.115.0'],
|
|
111
|
-
missingRanges: [],
|
|
112
|
-
});
|
|
113
|
-
expect(output).toHaveLength(1);
|
|
114
|
-
});
|
|
115
|
-
it('preserves same-version evaluation', async () => {
|
|
116
|
-
const { dependencies, output } = dependenciesFor(safeIndex);
|
|
117
|
-
await (0, upgradeCheck_1.upgradeCheckHandler)({ from: '1.115.0', to: '1.115.0', json: true }, dependencies);
|
|
118
|
-
expect(JSON.parse(output[0])).toMatchObject({
|
|
119
|
-
direction: 'same-version',
|
|
120
|
-
safe: true,
|
|
121
|
-
verdict: true,
|
|
122
|
-
coveredVersions: [],
|
|
123
|
-
missingRanges: [],
|
|
124
|
-
});
|
|
125
|
-
});
|
|
126
|
-
it('names false and unknown release reasons in human output', async () => {
|
|
127
|
-
const unsafeIndex = {
|
|
128
|
-
...safeIndex,
|
|
129
|
-
entries: [
|
|
130
|
-
safeIndex.entries[0],
|
|
131
|
-
{
|
|
132
|
-
...safeIndex.entries[1],
|
|
133
|
-
rollingUpdateSafe: false,
|
|
134
|
-
},
|
|
135
|
-
{
|
|
136
|
-
...safeIndex.entries[1],
|
|
137
|
-
version: '1.116.0',
|
|
138
|
-
previousVersion: '1.115.0',
|
|
139
|
-
rollingUpdateSafe: 'unknown',
|
|
140
|
-
},
|
|
141
|
-
],
|
|
142
|
-
};
|
|
143
|
-
const { dependencies, output } = dependenciesFor(unsafeIndex);
|
|
144
|
-
await expect((0, upgradeCheck_1.upgradeCheckHandler)({ from: '1.114.0', to: '1.116.0' }, dependencies)).rejects.toMatchObject({ code: 1 });
|
|
145
|
-
expect(output[0]).toContain('Unsafe rolling-update safety: 1.115.0');
|
|
146
|
-
expect(output[0]).toContain('Unknown rolling-update safety: 1.116.0');
|
|
147
|
-
});
|
|
148
|
-
it('rejects non-X.Y.Z endpoints before fetching', async () => {
|
|
149
|
-
const { dependencies, fetchIndex } = dependenciesFor(safeIndex);
|
|
150
|
-
await expect((0, upgradeCheck_1.upgradeCheckHandler)({ from: 'v1.114.0', to: '1.115.0' }, dependencies)).rejects.toThrow('--from must be a release version in X.Y.Z format');
|
|
151
|
-
expect(fetchIndex).not.toHaveBeenCalled();
|
|
152
|
-
});
|
|
153
|
-
});
|
|
154
|
-
describe('upgrade-check argv and exit codes', () => {
|
|
155
|
-
async function run(argv, index = safeIndex) {
|
|
156
|
-
const { dependencies } = dependenciesFor(index);
|
|
157
|
-
const command = new commander_1.Command()
|
|
158
|
-
.name('lightdash')
|
|
159
|
-
.exitOverride()
|
|
160
|
-
.configureOutput({ writeOut: () => { }, writeErr: () => { } });
|
|
161
|
-
(0, upgradeCheck_1.registerUpgradeCheckCommand)(command, dependencies);
|
|
162
|
-
try {
|
|
163
|
-
await command.parseAsync(['node', 'lightdash', ...argv]);
|
|
164
|
-
return 0;
|
|
165
|
-
}
|
|
166
|
-
catch (error) {
|
|
167
|
-
if (error instanceof ExitError) {
|
|
168
|
-
return error.code;
|
|
169
|
-
}
|
|
170
|
-
if (error instanceof commander_1.CommanderError) {
|
|
171
|
-
return error.exitCode;
|
|
172
|
-
}
|
|
173
|
-
throw error;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
it.each([
|
|
177
|
-
{
|
|
178
|
-
name: 'green forward span',
|
|
179
|
-
argv: ['upgrade-check', '--from', '1.114.0', '--to', '1.115.0'],
|
|
180
|
-
expected: 0,
|
|
181
|
-
},
|
|
182
|
-
{
|
|
183
|
-
name: 'unsafe missing target',
|
|
184
|
-
argv: ['upgrade-check', '--from', '1.114.0', '--to', '1.116.0'],
|
|
185
|
-
expected: 1,
|
|
186
|
-
},
|
|
187
|
-
{
|
|
188
|
-
name: 'missing from option',
|
|
189
|
-
argv: ['upgrade-check', '--to', '1.115.0'],
|
|
190
|
-
expected: 1,
|
|
191
|
-
},
|
|
192
|
-
{
|
|
193
|
-
name: 'missing to option',
|
|
194
|
-
argv: ['upgrade-check', '--from', '1.114.0'],
|
|
195
|
-
expected: 1,
|
|
196
|
-
},
|
|
197
|
-
])('returns $expected for $name', async ({ argv, expected }) => {
|
|
198
|
-
await expect(run(argv)).resolves.toBe(expected);
|
|
199
|
-
});
|
|
200
|
-
it('rejects a reverse argv span with a non-zero exit and rollback guidance', async () => {
|
|
201
|
-
const { dependencies, fetchIndex, output } = dependenciesFor(safeIndex);
|
|
202
|
-
const command = new commander_1.Command().name('lightdash').exitOverride();
|
|
203
|
-
(0, upgradeCheck_1.registerUpgradeCheckCommand)(command, dependencies);
|
|
204
|
-
let exitCode = 0;
|
|
205
|
-
let errorMessage = '';
|
|
206
|
-
try {
|
|
207
|
-
await command.parseAsync([
|
|
208
|
-
'node',
|
|
209
|
-
'lightdash',
|
|
210
|
-
'upgrade-check',
|
|
211
|
-
'--from',
|
|
212
|
-
'1.115.0',
|
|
213
|
-
'--to',
|
|
214
|
-
'1.114.0',
|
|
215
|
-
'--json',
|
|
216
|
-
]);
|
|
217
|
-
}
|
|
218
|
-
catch (error) {
|
|
219
|
-
exitCode = error instanceof ExitError ? error.code : 1;
|
|
220
|
-
errorMessage = error instanceof Error ? error.message : '';
|
|
221
|
-
}
|
|
222
|
-
expect(exitCode).toBe(1);
|
|
223
|
-
expect(errorMessage).toBe('Rollback spans are not supported by this command; rollback guidance ships in the upgrade runbook.');
|
|
224
|
-
expect(fetchIndex).not.toHaveBeenCalled();
|
|
225
|
-
expect(output).toHaveLength(0);
|
|
226
|
-
});
|
|
227
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"validate.test.d.ts","sourceRoot":"","sources":["../../src/handlers/validate.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,318 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const common_1 = require("@lightdash/common");
|
|
4
|
-
const compile_1 = require("./compile");
|
|
5
|
-
const apiClient_1 = require("./dbt/apiClient");
|
|
6
|
-
const validate_1 = require("./validate");
|
|
7
|
-
vi.mock('../analytics/analytics');
|
|
8
|
-
vi.mock('../config', () => ({
|
|
9
|
-
getConfig: vi.fn().mockResolvedValue({ user: null, context: null }),
|
|
10
|
-
}));
|
|
11
|
-
vi.mock('./compile');
|
|
12
|
-
vi.mock('./dbt/apiClient');
|
|
13
|
-
vi.mock('./timestampConversion');
|
|
14
|
-
const baseOptions = {
|
|
15
|
-
project: '11111111-1111-4111-8111-111111111111',
|
|
16
|
-
preview: false,
|
|
17
|
-
only: Object.values(common_1.ValidationTarget),
|
|
18
|
-
validateWarehouseColumns: false,
|
|
19
|
-
severity: 'error',
|
|
20
|
-
projectDir: '.',
|
|
21
|
-
profilesDir: '.',
|
|
22
|
-
target: undefined,
|
|
23
|
-
profile: undefined,
|
|
24
|
-
vars: undefined,
|
|
25
|
-
verbose: false,
|
|
26
|
-
startOfWeek: 0,
|
|
27
|
-
skipWarehouseCatalog: undefined,
|
|
28
|
-
skipDbtCompile: true,
|
|
29
|
-
useDbtList: false,
|
|
30
|
-
select: undefined,
|
|
31
|
-
models: undefined,
|
|
32
|
-
threads: undefined,
|
|
33
|
-
noVersionCheck: false,
|
|
34
|
-
exclude: undefined,
|
|
35
|
-
selector: undefined,
|
|
36
|
-
state: undefined,
|
|
37
|
-
fullRefresh: false,
|
|
38
|
-
defer: false,
|
|
39
|
-
targetPath: undefined,
|
|
40
|
-
favorState: false,
|
|
41
|
-
combineManifest: undefined,
|
|
42
|
-
warehouseCredentials: false,
|
|
43
|
-
disableTimestampConversion: false,
|
|
44
|
-
};
|
|
45
|
-
const TARGET_SKIP_WARNING = 'Skipping warehouse column validation because --only does not include the tables validation target';
|
|
46
|
-
const chartConfigurationWarning = {
|
|
47
|
-
validationUuid: 'warning-uuid',
|
|
48
|
-
validationId: null,
|
|
49
|
-
createdAt: new Date('2026-08-26T12:00:00Z'),
|
|
50
|
-
projectUuid: '11111111-1111-4111-8111-111111111111',
|
|
51
|
-
name: 'Orders over time',
|
|
52
|
-
error: 'dimension is not used in the chart configuration',
|
|
53
|
-
errorType: common_1.ValidationErrorType.ChartConfiguration,
|
|
54
|
-
source: common_1.ValidationSourceType.Chart,
|
|
55
|
-
chartUuid: 'chart-uuid',
|
|
56
|
-
fieldName: 'orders.unused_dim',
|
|
57
|
-
chartViews: 3,
|
|
58
|
-
lastUpdatedBy: 'Ada Lovelace',
|
|
59
|
-
lastUpdatedAt: new Date('2026-08-06T15:30:00Z'),
|
|
60
|
-
};
|
|
61
|
-
const brokenChartError = {
|
|
62
|
-
validationUuid: 'error-uuid',
|
|
63
|
-
validationId: null,
|
|
64
|
-
createdAt: new Date('2026-08-26T12:00:00Z'),
|
|
65
|
-
projectUuid: '11111111-1111-4111-8111-111111111111',
|
|
66
|
-
name: 'Broken chart',
|
|
67
|
-
error: 'Dimension does not exist',
|
|
68
|
-
errorType: common_1.ValidationErrorType.Dimension,
|
|
69
|
-
source: common_1.ValidationSourceType.Chart,
|
|
70
|
-
chartUuid: 'broken-chart-uuid',
|
|
71
|
-
fieldName: 'orders.missing',
|
|
72
|
-
chartViews: 1,
|
|
73
|
-
lastUpdatedBy: 'Ada Lovelace',
|
|
74
|
-
lastUpdatedAt: new Date('2026-08-06T15:30:00Z'),
|
|
75
|
-
};
|
|
76
|
-
describe('validateHandler', () => {
|
|
77
|
-
let errorOutput;
|
|
78
|
-
let validationResults = [];
|
|
79
|
-
const skipWarnings = () => errorOutput.filter((line) => line.includes('Skipping warehouse column validation'));
|
|
80
|
-
beforeEach(() => {
|
|
81
|
-
vi.clearAllMocks();
|
|
82
|
-
vi.mocked(apiClient_1.checkLightdashVersion).mockResolvedValue(undefined);
|
|
83
|
-
vi.mocked(compile_1.compile).mockResolvedValue([]);
|
|
84
|
-
vi.mocked(apiClient_1.lightdashApi).mockImplementation(async ({ method, url }) => {
|
|
85
|
-
if (method === 'POST' && url.endsWith('/validate')) {
|
|
86
|
-
return { jobId: 'test-job-id' };
|
|
87
|
-
}
|
|
88
|
-
if (url.includes('/schedulers/job/')) {
|
|
89
|
-
return { status: common_1.SchedulerJobStatus.COMPLETED, details: null };
|
|
90
|
-
}
|
|
91
|
-
if (url.includes('/validate?jobId=')) {
|
|
92
|
-
return validationResults;
|
|
93
|
-
}
|
|
94
|
-
throw new Error(`Unexpected API call: ${method} ${url}`);
|
|
95
|
-
});
|
|
96
|
-
errorOutput = [];
|
|
97
|
-
validationResults = [];
|
|
98
|
-
vi.spyOn(console, 'error').mockImplementation((...args) => {
|
|
99
|
-
errorOutput.push(args.map(String).join(' '));
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
afterEach(() => {
|
|
103
|
-
vi.restoreAllMocks();
|
|
104
|
-
});
|
|
105
|
-
test('does not request warehouse column validation by default', async () => {
|
|
106
|
-
await (0, validate_1.validateHandler)({ ...baseOptions });
|
|
107
|
-
expect(compile_1.compile).toHaveBeenCalledTimes(1);
|
|
108
|
-
expect(compile_1.compile).toHaveBeenCalledWith(expect.objectContaining({ validateWarehouseColumns: false }));
|
|
109
|
-
expect(skipWarnings()).toEqual([]);
|
|
110
|
-
});
|
|
111
|
-
test('requests warehouse column validation when the flag is set and every target is validated', async () => {
|
|
112
|
-
await (0, validate_1.validateHandler)({
|
|
113
|
-
...baseOptions,
|
|
114
|
-
validateWarehouseColumns: true,
|
|
115
|
-
});
|
|
116
|
-
expect(compile_1.compile).toHaveBeenCalledWith(expect.objectContaining({ validateWarehouseColumns: true }));
|
|
117
|
-
expect(skipWarnings()).toEqual([]);
|
|
118
|
-
});
|
|
119
|
-
test('requests warehouse column validation when the flag is set and only tables are validated', async () => {
|
|
120
|
-
await (0, validate_1.validateHandler)({
|
|
121
|
-
...baseOptions,
|
|
122
|
-
only: [common_1.ValidationTarget.TABLES],
|
|
123
|
-
validateWarehouseColumns: true,
|
|
124
|
-
});
|
|
125
|
-
expect(compile_1.compile).toHaveBeenCalledWith(expect.objectContaining({ validateWarehouseColumns: true }));
|
|
126
|
-
expect(skipWarnings()).toEqual([]);
|
|
127
|
-
});
|
|
128
|
-
test('requests warehouse column validation when the flag is set and a mixed target list includes tables', async () => {
|
|
129
|
-
await (0, validate_1.validateHandler)({
|
|
130
|
-
...baseOptions,
|
|
131
|
-
only: [common_1.ValidationTarget.TABLES, common_1.ValidationTarget.CHARTS],
|
|
132
|
-
validateWarehouseColumns: true,
|
|
133
|
-
});
|
|
134
|
-
expect(compile_1.compile).toHaveBeenCalledWith(expect.objectContaining({ validateWarehouseColumns: true }));
|
|
135
|
-
expect(skipWarnings()).toEqual([]);
|
|
136
|
-
});
|
|
137
|
-
test('does not request warehouse column validation when tables are not validated', async () => {
|
|
138
|
-
await (0, validate_1.validateHandler)({
|
|
139
|
-
...baseOptions,
|
|
140
|
-
only: [common_1.ValidationTarget.CHARTS, common_1.ValidationTarget.DASHBOARDS],
|
|
141
|
-
validateWarehouseColumns: true,
|
|
142
|
-
});
|
|
143
|
-
expect(compile_1.compile).toHaveBeenCalledWith(expect.objectContaining({ validateWarehouseColumns: false }));
|
|
144
|
-
const warnings = skipWarnings();
|
|
145
|
-
expect(warnings).toHaveLength(1);
|
|
146
|
-
expect(warnings[0]).toContain(TARGET_SKIP_WARNING);
|
|
147
|
-
});
|
|
148
|
-
test('warns exactly once when the flag is set and only charts are validated', async () => {
|
|
149
|
-
await (0, validate_1.validateHandler)({
|
|
150
|
-
...baseOptions,
|
|
151
|
-
only: [common_1.ValidationTarget.CHARTS],
|
|
152
|
-
validateWarehouseColumns: true,
|
|
153
|
-
});
|
|
154
|
-
expect(compile_1.compile).toHaveBeenCalledWith(expect.objectContaining({ validateWarehouseColumns: false }));
|
|
155
|
-
const warnings = skipWarnings();
|
|
156
|
-
expect(warnings).toHaveLength(1);
|
|
157
|
-
expect(warnings[0]).toContain(TARGET_SKIP_WARNING);
|
|
158
|
-
});
|
|
159
|
-
test('does not warn when only charts are validated without the flag', async () => {
|
|
160
|
-
await (0, validate_1.validateHandler)({
|
|
161
|
-
...baseOptions,
|
|
162
|
-
only: [common_1.ValidationTarget.CHARTS],
|
|
163
|
-
validateWarehouseColumns: false,
|
|
164
|
-
});
|
|
165
|
-
expect(compile_1.compile).toHaveBeenCalledWith(expect.objectContaining({ validateWarehouseColumns: false }));
|
|
166
|
-
expect(skipWarnings()).toEqual([]);
|
|
167
|
-
});
|
|
168
|
-
test.each([
|
|
169
|
-
{ select: ['orders'] },
|
|
170
|
-
{ models: ['orders'] },
|
|
171
|
-
{ exclude: ['customers'] },
|
|
172
|
-
{ selector: 'marts' },
|
|
173
|
-
])('validates data apps with model selection %j', async (selection) => {
|
|
174
|
-
const only = [common_1.ValidationTarget.CHARTS, common_1.ValidationTarget.APPS];
|
|
175
|
-
await (0, validate_1.validateHandler)({
|
|
176
|
-
...baseOptions,
|
|
177
|
-
...selection,
|
|
178
|
-
only,
|
|
179
|
-
});
|
|
180
|
-
expect(compile_1.compile).toHaveBeenCalledTimes(1);
|
|
181
|
-
expect(compile_1.compile).toHaveBeenCalledWith(expect.objectContaining(selection));
|
|
182
|
-
expect(apiClient_1.lightdashApi).toHaveBeenCalledWith(expect.objectContaining({
|
|
183
|
-
method: 'POST',
|
|
184
|
-
url: `/api/v1/projects/${baseOptions.project}/validate`,
|
|
185
|
-
body: JSON.stringify({ explores: [], validationTargets: only }),
|
|
186
|
-
}));
|
|
187
|
-
});
|
|
188
|
-
test.each([
|
|
189
|
-
{ only: [] },
|
|
190
|
-
{ only: Object.values(common_1.ValidationTarget) },
|
|
191
|
-
{ only: [common_1.ValidationTarget.APPS] },
|
|
192
|
-
])('preserves validation targets %j with model selection', async ({ only }) => {
|
|
193
|
-
await (0, validate_1.validateHandler)({
|
|
194
|
-
...baseOptions,
|
|
195
|
-
only,
|
|
196
|
-
select: ['orders'],
|
|
197
|
-
});
|
|
198
|
-
expect(apiClient_1.lightdashApi).toHaveBeenCalledWith(expect.objectContaining({
|
|
199
|
-
method: 'POST',
|
|
200
|
-
url: `/api/v1/projects/${baseOptions.project}/validate`,
|
|
201
|
-
body: JSON.stringify({
|
|
202
|
-
explores: [],
|
|
203
|
-
validationTargets: only,
|
|
204
|
-
}),
|
|
205
|
-
}));
|
|
206
|
-
});
|
|
207
|
-
test('fails selected apps-only validation and prints the latest version author and date', async () => {
|
|
208
|
-
vi.spyOn(process, 'exit').mockImplementation(() => undefined);
|
|
209
|
-
vi.mocked(apiClient_1.lightdashApi).mockImplementation(async ({ method, url }) => {
|
|
210
|
-
if (method === 'POST' && url.endsWith('/validate')) {
|
|
211
|
-
return { jobId: 'test-job-id' };
|
|
212
|
-
}
|
|
213
|
-
if (url.includes('/schedulers/job/')) {
|
|
214
|
-
return {
|
|
215
|
-
status: common_1.SchedulerJobStatus.COMPLETED,
|
|
216
|
-
details: null,
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
if (url.includes('/validate?jobId=')) {
|
|
220
|
-
return [
|
|
221
|
-
{
|
|
222
|
-
validationUuid: 'validation-uuid',
|
|
223
|
-
validationId: null,
|
|
224
|
-
createdAt: new Date('2026-08-07T09:00:00Z'),
|
|
225
|
-
projectUuid: '11111111-1111-4111-8111-111111111111',
|
|
226
|
-
name: 'Broken data app',
|
|
227
|
-
error: 'Dimension does not exist',
|
|
228
|
-
errorType: common_1.ValidationErrorType.Dimension,
|
|
229
|
-
source: common_1.ValidationSourceType.DataApp,
|
|
230
|
-
appUuid: 'app-uuid',
|
|
231
|
-
lastUpdatedBy: 'Ada Lovelace',
|
|
232
|
-
lastUpdatedAt: new Date('2026-08-06T15:30:00Z'),
|
|
233
|
-
},
|
|
234
|
-
];
|
|
235
|
-
}
|
|
236
|
-
throw new Error(`Unexpected API call: ${method} ${url}`);
|
|
237
|
-
});
|
|
238
|
-
await (0, validate_1.validateHandler)({
|
|
239
|
-
...baseOptions,
|
|
240
|
-
only: [common_1.ValidationTarget.APPS],
|
|
241
|
-
select: ['orders'],
|
|
242
|
-
});
|
|
243
|
-
expect(process.exit).toHaveBeenCalledWith(1);
|
|
244
|
-
const output = errorOutput.join('\n');
|
|
245
|
-
expect(output).toContain('Dimension does not exist');
|
|
246
|
-
expect(output).toContain('Ada Lovelace');
|
|
247
|
-
expect(output).toContain('2026-08-06');
|
|
248
|
-
});
|
|
249
|
-
test('succeeds when only chart configuration warnings exist at default severity', async () => {
|
|
250
|
-
validationResults = [chartConfigurationWarning];
|
|
251
|
-
const exitSpy = vi
|
|
252
|
-
.spyOn(process, 'exit')
|
|
253
|
-
.mockImplementation(() => undefined);
|
|
254
|
-
await (0, validate_1.validateHandler)({ ...baseOptions });
|
|
255
|
-
expect(exitSpy).not.toHaveBeenCalled();
|
|
256
|
-
expect(errorOutput.join('\n')).not.toContain('orders.unused_dim');
|
|
257
|
-
});
|
|
258
|
-
test('fails when --severity warning is set and warnings exist', async () => {
|
|
259
|
-
validationResults = [chartConfigurationWarning];
|
|
260
|
-
vi.spyOn(process, 'exit').mockImplementation(() => undefined);
|
|
261
|
-
await (0, validate_1.validateHandler)({
|
|
262
|
-
...baseOptions,
|
|
263
|
-
severity: 'warning',
|
|
264
|
-
});
|
|
265
|
-
expect(process.exit).toHaveBeenCalledWith(1);
|
|
266
|
-
const output = errorOutput.join('\n');
|
|
267
|
-
expect(output).toContain('Chart configuration warning');
|
|
268
|
-
expect(output).toContain('orders.unused_dim');
|
|
269
|
-
expect(output).toContain('1 warning');
|
|
270
|
-
});
|
|
271
|
-
test('fails when deprecated --show-chart-configuration-warnings is set and warnings exist', async () => {
|
|
272
|
-
validationResults = [chartConfigurationWarning];
|
|
273
|
-
vi.spyOn(process, 'exit').mockImplementation(() => undefined);
|
|
274
|
-
await (0, validate_1.validateHandler)({
|
|
275
|
-
...baseOptions,
|
|
276
|
-
showChartConfigurationWarnings: true,
|
|
277
|
-
});
|
|
278
|
-
expect(process.exit).toHaveBeenCalledWith(1);
|
|
279
|
-
const output = errorOutput.join('\n');
|
|
280
|
-
expect(output).toContain(validate_1.SHOW_CHART_CONFIGURATION_WARNINGS_DEPRECATION);
|
|
281
|
-
expect(output).toContain('Chart configuration warning');
|
|
282
|
-
expect(output).toContain('orders.unused_dim');
|
|
283
|
-
expect(output).toContain('1 warning');
|
|
284
|
-
});
|
|
285
|
-
test('treats the deprecated flag as --severity warning even when severity defaults to error', async () => {
|
|
286
|
-
expect((0, validate_1.resolveValidateSeverity)({
|
|
287
|
-
severity: 'error',
|
|
288
|
-
showChartConfigurationWarnings: true,
|
|
289
|
-
})).toBe('warning');
|
|
290
|
-
expect((0, validate_1.resolveValidateSeverity)({
|
|
291
|
-
severity: 'error',
|
|
292
|
-
})).toBe('error');
|
|
293
|
-
});
|
|
294
|
-
test('fails on blocking errors even when warnings stay hidden', async () => {
|
|
295
|
-
validationResults = [brokenChartError, chartConfigurationWarning];
|
|
296
|
-
vi.spyOn(process, 'exit').mockImplementation(() => undefined);
|
|
297
|
-
await (0, validate_1.validateHandler)({ ...baseOptions });
|
|
298
|
-
expect(process.exit).toHaveBeenCalledWith(1);
|
|
299
|
-
const output = errorOutput.join('\n');
|
|
300
|
-
expect(output).toContain('Broken chart');
|
|
301
|
-
expect(output).not.toContain('orders.unused_dim');
|
|
302
|
-
expect(output).toContain('chart configuration warning hidden');
|
|
303
|
-
});
|
|
304
|
-
test('reports errors and warnings together when severity is warning', async () => {
|
|
305
|
-
validationResults = [brokenChartError, chartConfigurationWarning];
|
|
306
|
-
vi.spyOn(process, 'exit').mockImplementation(() => undefined);
|
|
307
|
-
await (0, validate_1.validateHandler)({
|
|
308
|
-
...baseOptions,
|
|
309
|
-
severity: 'warning',
|
|
310
|
-
});
|
|
311
|
-
expect(process.exit).toHaveBeenCalledWith(1);
|
|
312
|
-
const output = errorOutput.join('\n');
|
|
313
|
-
expect(output).toContain('Broken chart');
|
|
314
|
-
expect(output).toContain('orders.unused_dim');
|
|
315
|
-
expect(output).toContain('1 error');
|
|
316
|
-
expect(output).toContain('1 warning');
|
|
317
|
-
});
|
|
318
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"validateSpaceFilter.test.d.ts","sourceRoot":"","sources":["../../src/handlers/validateSpaceFilter.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const common_1 = require("@lightdash/common");
|
|
4
|
-
const validateSpaceFilter_1 = require("./validateSpaceFilter");
|
|
5
|
-
const space = (uuid, slug, parentSpaceUuid = null) => ({ uuid, slug, parentSpaceUuid });
|
|
6
|
-
// marketing; archive > archive-2024 > deep-child; second root space also slugged "archive"
|
|
7
|
-
const spaces = [
|
|
8
|
-
space('s1', 'marketing'),
|
|
9
|
-
space('s2', 'archive'),
|
|
10
|
-
space('s3', 'archive-2024', 's2'),
|
|
11
|
-
space('s4', 'deep-child', 's3'),
|
|
12
|
-
space('s5', 'archive'),
|
|
13
|
-
];
|
|
14
|
-
const base = {
|
|
15
|
-
validationUuid: 'v1',
|
|
16
|
-
validationId: null,
|
|
17
|
-
createdAt: new Date(),
|
|
18
|
-
error: 'error message',
|
|
19
|
-
projectUuid: 'p1',
|
|
20
|
-
};
|
|
21
|
-
const chartError = (spaceUuid) => ({
|
|
22
|
-
...base,
|
|
23
|
-
name: 'chart',
|
|
24
|
-
errorType: common_1.ValidationErrorType.Chart,
|
|
25
|
-
source: common_1.ValidationSourceType.Chart,
|
|
26
|
-
chartUuid: 'c1',
|
|
27
|
-
chartViews: 0,
|
|
28
|
-
spaceUuid,
|
|
29
|
-
});
|
|
30
|
-
const dashboardError = (spaceUuid) => ({
|
|
31
|
-
...base,
|
|
32
|
-
name: 'dashboard',
|
|
33
|
-
errorType: common_1.ValidationErrorType.Chart,
|
|
34
|
-
source: common_1.ValidationSourceType.Dashboard,
|
|
35
|
-
dashboardUuid: 'd1',
|
|
36
|
-
dashboardViews: 0,
|
|
37
|
-
spaceUuid,
|
|
38
|
-
});
|
|
39
|
-
const tableError = () => ({
|
|
40
|
-
...base,
|
|
41
|
-
name: 'table',
|
|
42
|
-
errorType: common_1.ValidationErrorType.Model,
|
|
43
|
-
source: common_1.ValidationSourceType.Table,
|
|
44
|
-
});
|
|
45
|
-
describe('resolveSpaceSelection', () => {
|
|
46
|
-
it('selects a space by slug', () => {
|
|
47
|
-
expect((0, validateSpaceFilter_1.resolveSpaceSelection)(spaces, ['marketing'])).toEqual(new Set(['s1']));
|
|
48
|
-
});
|
|
49
|
-
it('cascades into nested sub-spaces recursively', () => {
|
|
50
|
-
// s2 selected -> s3 and s4 follow; s5 shares the slug and is also selected
|
|
51
|
-
expect((0, validateSpaceFilter_1.resolveSpaceSelection)(spaces, ['archive'])).toEqual(new Set(['s2', 's3', 's4', 's5']));
|
|
52
|
-
});
|
|
53
|
-
it('selects a mid-tree space with its descendants only', () => {
|
|
54
|
-
expect((0, validateSpaceFilter_1.resolveSpaceSelection)(spaces, ['archive-2024'])).toEqual(new Set(['s3', 's4']));
|
|
55
|
-
});
|
|
56
|
-
it('throws ParameterError listing available slugs on unknown slug', () => {
|
|
57
|
-
expect(() => (0, validateSpaceFilter_1.resolveSpaceSelection)(spaces, ['typo'])).toThrow(common_1.ParameterError);
|
|
58
|
-
expect(() => (0, validateSpaceFilter_1.resolveSpaceSelection)(spaces, ['typo'])).toThrow(/typo.*archive.*marketing/s);
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
describe('filterValidationsBySpace', () => {
|
|
62
|
-
const selection = new Set(['s2']);
|
|
63
|
-
it('include mode keeps only errors in selected spaces', () => {
|
|
64
|
-
const kept = (0, validateSpaceFilter_1.filterValidationsBySpace)([chartError('s1'), chartError('s2'), dashboardError('s2')], selection, 'include');
|
|
65
|
-
expect(kept).toHaveLength(2);
|
|
66
|
-
});
|
|
67
|
-
it('exclude mode drops errors in selected spaces', () => {
|
|
68
|
-
const kept = (0, validateSpaceFilter_1.filterValidationsBySpace)([chartError('s1'), chartError('s2'), dashboardError('s2')], selection, 'exclude');
|
|
69
|
-
expect(kept).toHaveLength(1);
|
|
70
|
-
});
|
|
71
|
-
it('never filters table errors', () => {
|
|
72
|
-
expect((0, validateSpaceFilter_1.filterValidationsBySpace)([tableError()], selection, 'include')).toHaveLength(1);
|
|
73
|
-
expect((0, validateSpaceFilter_1.filterValidationsBySpace)([tableError()], selection, 'exclude')).toHaveLength(1);
|
|
74
|
-
});
|
|
75
|
-
it('keeps errors without spaceUuid under exclude, drops them under include', () => {
|
|
76
|
-
expect((0, validateSpaceFilter_1.filterValidationsBySpace)([chartError(undefined)], selection, 'exclude')).toHaveLength(1);
|
|
77
|
-
expect((0, validateSpaceFilter_1.filterValidationsBySpace)([chartError(undefined)], selection, 'include')).toHaveLength(0);
|
|
78
|
-
});
|
|
79
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"warehouseConnection.test.d.ts","sourceRoot":"","sources":["../../src/handlers/warehouseConnection.test.ts"],"names":[],"mappings":""}
|