Skip to content

Commit efaaf46

Browse files
authored
Merge pull request #266 from contentstack/fix/DX-9444
fix(export,import): validate --module flag value before execution
2 parents a7b2e78 + 0ec25d9 commit efaaf46

6 files changed

Lines changed: 552 additions & 516 deletions

File tree

.talismanrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
fileignoreconfig:
22
- filename: pnpm-lock.yaml
3-
checksum: 0feb3713a8f2e4a8a1f5f528218c2c578265dc5b31ff283a283fefc949bbafd2
3+
checksum: 6753b1344b2f6ae505a1815ac6e4fc42f4da13e69851c66e6786400364281754
44
version: ""

packages/contentstack-export/src/commands/cm/stacks/export.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,25 @@ export default class ExportCommand extends Command {
5656
}),
5757
module: flags.string({
5858
description:
59-
'[optional] Specific module name. If not specified, the export command will export all the modules to the stack. The available modules are assets, content-types, entries, environments, extensions, marketplace-apps, global-fields, labels, locales, webhooks, workflows, custom-roles, taxonomies, and studio.',
59+
'[optional] Specific module name. If not specified, the export command will export all the modules from the stack. The available modules are stack, assets, locales, environments, extensions, webhooks, global-fields, entries, content-types, custom-roles, workflows, labels, marketplace-apps, taxonomies, personalize, and composable-studio.',
60+
options: [
61+
'stack',
62+
'assets',
63+
'locales',
64+
'environments',
65+
'extensions',
66+
'webhooks',
67+
'global-fields',
68+
'entries',
69+
'content-types',
70+
'custom-roles',
71+
'workflows',
72+
'labels',
73+
'marketplace-apps',
74+
'taxonomies',
75+
'personalize',
76+
'composable-studio',
77+
],
6078
}),
6179
'content-types': flags.string({
6280
description:
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import { expect } from 'chai';
2+
import sinon from 'sinon';
3+
import ExportCommand from '../../../../../src/commands/cm/stacks/export';
4+
5+
describe('ExportCommand', () => {
6+
afterEach(() => {
7+
sinon.restore();
8+
});
9+
10+
describe('Flags Configuration', () => {
11+
it('should have all required flags defined', () => {
12+
const flags = ExportCommand.flags;
13+
14+
expect(flags).to.have.property('stack-api-key');
15+
expect(flags).to.have.property('data-dir');
16+
expect(flags).to.have.property('alias');
17+
expect(flags).to.have.property('config');
18+
expect(flags).to.have.property('module');
19+
expect(flags).to.have.property('branch');
20+
expect(flags).to.have.property('branch-alias');
21+
expect(flags).to.have.property('secured-assets');
22+
});
23+
24+
it('should have correct exclusive flags for branch', () => {
25+
const flags = ExportCommand.flags;
26+
27+
expect(flags['branch']).to.have.property('exclusive');
28+
expect(flags['branch-alias']).to.have.property('exclusive');
29+
expect((flags['branch'] as any).exclusive).to.include('branch-alias');
30+
expect((flags['branch-alias'] as any).exclusive).to.include('branch');
31+
});
32+
});
33+
34+
describe('module flag options', () => {
35+
it('should have options defined on the module flag', () => {
36+
const flags = ExportCommand.flags;
37+
38+
expect(flags['module']).to.have.property('options');
39+
expect((flags['module'] as any).options).to.be.an('array').that.is.not.empty;
40+
});
41+
42+
it('should accept all valid module names', () => {
43+
const validModules = [
44+
'stack',
45+
'assets',
46+
'locales',
47+
'environments',
48+
'extensions',
49+
'webhooks',
50+
'global-fields',
51+
'entries',
52+
'content-types',
53+
'custom-roles',
54+
'workflows',
55+
'labels',
56+
'marketplace-apps',
57+
'taxonomies',
58+
'personalize',
59+
'composable-studio',
60+
];
61+
const moduleOptions = (ExportCommand.flags['module'] as any).options as string[];
62+
63+
for (const mod of validModules) {
64+
expect(moduleOptions).to.include(mod, `module flag options should include '${mod}'`);
65+
}
66+
});
67+
68+
it('should not accept invalid module names', () => {
69+
const moduleOptions = (ExportCommand.flags['module'] as any).options as string[];
70+
71+
expect(moduleOptions).to.not.include('invalid-module');
72+
expect(moduleOptions).to.not.include('foo');
73+
expect(moduleOptions).to.not.include('');
74+
});
75+
76+
it('should have the correct number of valid modules', () => {
77+
const moduleOptions = (ExportCommand.flags['module'] as any).options as string[];
78+
79+
expect(moduleOptions).to.have.lengthOf(16);
80+
});
81+
});
82+
});

packages/contentstack-import/src/commands/cm/stacks/import.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,25 @@ export default class ImportCommand extends Command {
5353
module: flags.string({
5454
required: false,
5555
description:
56-
'[optional] Specify the module to import into the target stack. If not specified, the import command will import all the modules into the stack. The available modules are assets, content-types, entries, environments, extensions, marketplace-apps, global-fields, labels, locales, webhooks, workflows, custom-roles, personalize projects, taxonomies, and composable-studio.',
56+
'[optional] Specify the module to import into the target stack. If not specified, the import command will import all the modules into the stack. The available modules are stack, assets, locales, environments, extensions, webhooks, global-fields, entries, content-types, custom-roles, workflows, labels, marketplace-apps, taxonomies, personalize, and composable-studio.',
57+
options: [
58+
'stack',
59+
'assets',
60+
'locales',
61+
'environments',
62+
'extensions',
63+
'webhooks',
64+
'global-fields',
65+
'entries',
66+
'content-types',
67+
'custom-roles',
68+
'workflows',
69+
'labels',
70+
'marketplace-apps',
71+
'taxonomies',
72+
'personalize',
73+
'composable-studio',
74+
],
5775
}),
5876
'backup-dir': flags.string({
5977
description: '[optional] Backup directory name when using specific module.',

packages/contentstack-import/test/unit/commands/cm/stacks/import.test.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,47 @@ describe('ImportCommand', () => {
195195
expect((flags['import-webhook-status'] as any).options).to.include('disable');
196196
expect((flags['import-webhook-status'] as any).options).to.include('current');
197197
});
198+
199+
it('should have options defined on the module flag', () => {
200+
const flags = ImportCommand.flags;
201+
202+
expect(flags['module']).to.have.property('options');
203+
expect((flags['module'] as any).options).to.be.an('array').that.is.not.empty;
204+
});
205+
206+
it('should accept all valid module names', () => {
207+
const validModules = [
208+
'stack',
209+
'assets',
210+
'locales',
211+
'environments',
212+
'extensions',
213+
'webhooks',
214+
'global-fields',
215+
'entries',
216+
'content-types',
217+
'custom-roles',
218+
'workflows',
219+
'labels',
220+
'marketplace-apps',
221+
'taxonomies',
222+
'personalize',
223+
'composable-studio',
224+
];
225+
const moduleOptions = (ImportCommand.flags['module'] as any).options as string[];
226+
227+
for (const mod of validModules) {
228+
expect(moduleOptions).to.include(mod, `module flag options should include '${mod}'`);
229+
}
230+
});
231+
232+
it('should not accept invalid module names', () => {
233+
const moduleOptions = (ImportCommand.flags['module'] as any).options as string[];
234+
235+
expect(moduleOptions).to.not.include('invalid-module');
236+
expect(moduleOptions).to.not.include('foo');
237+
expect(moduleOptions).to.not.include('');
238+
});
198239
});
199240

200241
describe('createImportContext', () => {

0 commit comments

Comments
 (0)