Skip to content

Commit fd72578

Browse files
Fixed failed unit tests
1 parent a772c50 commit fd72578

File tree

11 files changed

+119
-44
lines changed

11 files changed

+119
-44
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ export default class ImportCommand extends Command {
247247
command: this.context?.info?.command || 'cm:stacks:import',
248248
module: '',
249249
userId: configHandler.get('userUid') || '',
250-
email: configHandler.get('email') || undefined,
250+
email: configHandler.get('email') || '',
251251
sessionId: this.context?.sessionId,
252252
apiKey: apiKey || '',
253253
orgId: configHandler.get('oauthOrgUid') || '',

packages/contentstack-import/src/import/module-importer.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,17 @@ class ModuleImporter {
8686

8787
async importByModuleByName(moduleName: Modules) {
8888
log.info(`Starting import of ${moduleName} module`, this.importConfig.context);
89-
// import the modules by name
90-
// calls the module runner which inturn calls the module itself
89+
90+
// Check if module should be skipped for legacy contentVersion
91+
if (this.importConfig.contentVersion !== 2) {
92+
const onlyTSModules = this.importConfig.onlyTSModules || [];
93+
if (onlyTSModules.includes(moduleName)) {
94+
// Module is in onlyTSModules list, skip import for legacy contentVersion
95+
return undefined;
96+
}
97+
}
98+
99+
// Use module import (same for both contentVersion 1 and 2)
91100
return startModuleImport({
92101
stackAPIClient: this.stackAPIClient,
93102
importConfig: this.importConfig,

packages/contentstack-import/src/import/modules/workflows.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ export default class ImportWorkflows extends BaseClass {
199199
error?.message || 'Failed to import workflow',
200200
PROCESS_NAMES.WORKFLOWS_CREATE,
201201
);
202-
if (error.errors['workflow_stages.0.users']) {
202+
if (error?.errors && error.errors['workflow_stages.0.users']) {
203203
log.error(
204204
"Failed to import Workflows as you've specified certain roles in the Stage transition and access rules section. We currently don't import roles to the stack.",
205205
this.importConfig.context,

packages/contentstack-import/src/types/import-config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ export default interface ImportConfig extends DefaultConfig, ExternalConfig {
5959
personalizeProjectName?: string;
6060
'exclude-global-modules': false;
6161
context: Context;
62+
onlyTSModules?: Modules[];
6263
}
6364

6465
type branch = {

packages/contentstack-import/src/utils/import-path-resolver.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,29 @@ export const updateImportConfigWithResolvedPath = async (
141141

142142
importConfig.data = resolvedPath;
143143

144+
// Check if export-info.json exists to determine contentVersion
145+
const exportInfoPath = path.join(resolvedPath, 'export-info.json');
146+
if (fileExistsSync(exportInfoPath)) {
147+
try {
148+
const exportInfo = await readFile(exportInfoPath);
149+
// If export-info.json exists, set contentVersion to 2 (or use value from file if present)
150+
if (exportInfo && exportInfo.contentVersion) {
151+
importConfig.contentVersion = exportInfo.contentVersion;
152+
} else {
153+
// If export-info.json exists but contentVersion is missing, default to 2
154+
importConfig.contentVersion = 2;
155+
}
156+
} catch (error) {
157+
// If export-info.json exists but is null or can't be read, default to 2
158+
importConfig.contentVersion = 2;
159+
}
160+
} else {
161+
// If export-info.json doesn't exist, default to 1 (legacy format)
162+
importConfig.contentVersion = 1;
163+
}
164+
144165
log.debug(
145-
`Import config updated - contentDir: ${importConfig.contentDir}, branchDir: ${importConfig.branchDir}, data: ${importConfig.data},`,
166+
`Import config updated - contentDir: ${importConfig.contentDir}, branchDir: ${importConfig.branchDir}, data: ${importConfig.data}, contentVersion: ${importConfig.contentVersion}`,
146167
);
147168
};
148169

packages/contentstack-import/test/unit/import/module-importer.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ describe('ModuleImporter', () => {
102102
const modulesIndex = require('../../../src/import/modules');
103103
startModuleImportStub = sandbox.stub(modulesIndex, 'default').resolves();
104104

105-
const modulesJSIndex = require('../../../src/import/modules-js');
106-
startJSModuleImportStub = sandbox.stub(modulesJSIndex, 'default').resolves();
105+
// startJSModuleImport is now the same as startModuleImport, so we stub the same module
106+
startJSModuleImportStub = startModuleImportStub;
107107

108108
// Mock @contentstack/cli-utilities
109109
// TODO: Fix addLocale mocking - currently skipping tests that need it
@@ -633,15 +633,15 @@ describe('ModuleImporter', () => {
633633
});
634634

635635
describe('Content Version 1', () => {
636-
it('should call startJSModuleImport when contentVersion !== 2 and module is NOT in onlyTSModules', async () => {
636+
it('should call startModuleImport when contentVersion !== 2 and module is NOT in onlyTSModules', async () => {
637637
mockImportConfig.contentVersion = 1;
638638
mockImportConfig.onlyTSModules = ['personalize'];
639639
const importer = new ModuleImporter(mockManagementClient as any, mockImportConfig);
640640

641641
await importer.importByModuleByName('entries');
642642

643-
expect(startJSModuleImportStub.calledOnce).to.be.true;
644-
expect(startJSModuleImportStub.firstCall.args[0]).to.deep.equal({
643+
expect(startModuleImportStub.calledOnce).to.be.true;
644+
expect(startModuleImportStub.firstCall.args[0]).to.deep.equal({
645645
stackAPIClient: mockStackClient,
646646
importConfig: mockImportConfig,
647647
moduleName: 'entries'
@@ -655,7 +655,7 @@ describe('ModuleImporter', () => {
655655

656656
const result = await importer.importByModuleByName('entries');
657657

658-
expect(startJSModuleImportStub.called).to.be.false;
658+
expect(startModuleImportStub.called).to.be.false;
659659
expect(result).to.be.undefined;
660660
});
661661

@@ -673,7 +673,7 @@ describe('ModuleImporter', () => {
673673
expect(result2).to.be.undefined;
674674
expect(result3).to.be.undefined;
675675
expect(result4).to.be.undefined; // webhooks would call startJSModuleImport
676-
expect(startJSModuleImportStub.calledOnce).to.be.true;
676+
expect(startModuleImportStub.calledOnce).to.be.true;
677677
expect(startJSModuleImportStub.firstCall.args[0].moduleName).to.equal('webhooks');
678678
});
679679

@@ -684,7 +684,7 @@ describe('ModuleImporter', () => {
684684

685685
await importer.importByModuleByName('entries');
686686

687-
expect(startJSModuleImportStub.calledOnce).to.be.true;
687+
expect(startModuleImportStub.calledOnce).to.be.true;
688688
});
689689
});
690690
});

packages/contentstack-import/test/unit/import/modules/assets.test.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,32 @@ describe('ImportAssets', () => {
130130
let importAssetsStub: sinon.SinonStub;
131131
let publishStub: sinon.SinonStub;
132132
let existsSyncStub: sinon.SinonStub;
133+
let analyzeImportDataStub: sinon.SinonStub;
134+
let withLoadingSpinnerStub: sinon.SinonStub;
135+
let createNestedProgressStub: sinon.SinonStub;
136+
let executeStepStub: sinon.SinonStub;
133137

134138
beforeEach(() => {
135139
importFoldersStub = sinon.stub(importAssets as any, 'importFolders').resolves();
136140
importAssetsStub = sinon.stub(importAssets as any, 'importAssets').resolves();
137141
publishStub = sinon.stub(importAssets as any, 'publish').resolves();
138142
existsSyncStub = sinon.stub().returns(true);
139143
sinon.replace(require('node:fs'), 'existsSync', existsSyncStub);
144+
145+
// Stub the new methods used in start()
146+
analyzeImportDataStub = sinon.stub(importAssets as any, 'analyzeImportData').resolves([1, 2, 0, 1]);
147+
withLoadingSpinnerStub = sinon.stub(importAssets as any, 'withLoadingSpinner').callsFake(async (msg: string, fn: () => Promise<any>) => {
148+
return await fn();
149+
});
150+
createNestedProgressStub = sinon.stub(importAssets as any, 'createNestedProgress').returns({
151+
addProcess: sinon.stub(),
152+
startProcess: sinon.stub().returns({ updateStatus: sinon.stub() }),
153+
completeProcess: sinon.stub(),
154+
tick: sinon.stub()
155+
});
156+
executeStepStub = sinon.stub(importAssets as any, 'executeStep').callsFake(async (progress: any, processName: string, status: string, fn: () => Promise<any>) => {
157+
return await fn();
158+
});
140159
});
141160

142161
it('should call importFolders first', async () => {
@@ -148,6 +167,7 @@ describe('ImportAssets', () => {
148167
const originalValue = importAssets.assetConfig.includeVersionedAssets;
149168
importAssets.assetConfig.includeVersionedAssets = true;
150169
existsSyncStub.returns(true);
170+
analyzeImportDataStub.resolves([1, 2, 1, 1]); // foldersCount, assetsCount, versionedAssetsCount, publishableAssetsCount
151171

152172
await importAssets.start();
153173

@@ -164,6 +184,7 @@ describe('ImportAssets', () => {
164184
it('should skip versioned assets when directory does not exist', async () => {
165185
mockImportConfig.modules.assets.includeVersionedAssets = true;
166186
existsSyncStub.returns(false);
187+
analyzeImportDataStub.resolves([1, 2, 0, 1]); // versionedAssetsCount = 0
167188

168189
await importAssets.start();
169190

@@ -173,6 +194,7 @@ describe('ImportAssets', () => {
173194

174195
it('should not import versioned assets when includeVersionedAssets is false', async () => {
175196
mockImportConfig.modules.assets.includeVersionedAssets = false;
197+
analyzeImportDataStub.resolves([1, 2, 1, 1]); // versionedAssetsCount = 1, but includeVersionedAssets is false
176198

177199
await importAssets.start();
178200

@@ -189,6 +211,7 @@ describe('ImportAssets', () => {
189211

190212
it('should skip publish when skipAssetsPublish is true', async () => {
191213
mockImportConfig.skipAssetsPublish = true;
214+
analyzeImportDataStub.resolves([1, 2, 0, 1]); // publishableAssetsCount = 1, but skipAssetsPublish is true
192215

193216
await importAssets.start();
194217

@@ -204,7 +227,7 @@ describe('ImportAssets', () => {
204227

205228
it('should handle errors gracefully', async () => {
206229
const error = new Error('Import failed');
207-
importFoldersStub.rejects(error);
230+
analyzeImportDataStub.rejects(error);
208231

209232
await importAssets.start();
210233

@@ -868,6 +891,19 @@ describe('ImportAssets', () => {
868891
const importFoldersStub = sinon.stub(importAssets as any, 'importFolders').resolves();
869892
const importAssetsStub = sinon.stub(importAssets as any, 'importAssets').resolves();
870893
const publishStub = sinon.stub(importAssets as any, 'publish').resolves();
894+
const analyzeImportDataStub = sinon.stub(importAssets as any, 'analyzeImportData').resolves([1, 2, 0, 1]);
895+
sinon.stub(importAssets as any, 'withLoadingSpinner').callsFake(async (msg: string, fn: () => Promise<any>) => {
896+
return await fn();
897+
});
898+
sinon.stub(importAssets as any, 'createNestedProgress').returns({
899+
addProcess: sinon.stub(),
900+
startProcess: sinon.stub().returns({ updateStatus: sinon.stub() }),
901+
completeProcess: sinon.stub(),
902+
tick: sinon.stub()
903+
});
904+
sinon.stub(importAssets as any, 'executeStep').callsFake(async (progress: any, processName: string, status: string, fn: () => Promise<any>) => {
905+
return await fn();
906+
});
871907

872908
await importAssets.start();
873909

packages/contentstack-import/test/unit/import/modules/custom-roles.test.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -335,15 +335,15 @@ describe('ImportCustomRoles', () => {
335335
});
336336
});
337337

338-
describe('serializeWebhooks()', () => {
338+
describe('serializeCustomRoles()', () => {
339339
it('should skip role if already exists in mapper', () => {
340340
importCustomRoles['customRolesUidMapper'] = { role1: 'mapped-role1' };
341341
const apiOptions = {
342342
apiData: { uid: 'role1', name: 'Role 1', rules: [] as any },
343343
entity: 'create-custom-role',
344344
};
345345

346-
const result = importCustomRoles.serializeWebhooks(apiOptions as any);
346+
const result = importCustomRoles.serializeCustomRoles(apiOptions as any);
347347

348348
expect(result.entity).to.be.undefined;
349349
});
@@ -353,7 +353,7 @@ describe('ImportCustomRoles', () => {
353353
apiData: { uid: 'role1', name: 'Role 1', rules: [] as any },
354354
};
355355

356-
const result = importCustomRoles.serializeWebhooks(apiOptions as any);
356+
const result = importCustomRoles.serializeCustomRoles(apiOptions as any);
357357

358358
expect(result.apiData.rules).to.have.lengthOf(1);
359359
expect(result.apiData.rules[0].module).to.equal('branch');
@@ -368,7 +368,7 @@ describe('ImportCustomRoles', () => {
368368
},
369369
};
370370

371-
const result = importCustomRoles.serializeWebhooks(apiOptions as any);
371+
const result = importCustomRoles.serializeCustomRoles(apiOptions as any);
372372

373373
expect(result.apiData.rules).to.have.lengthOf(1);
374374
});
@@ -383,7 +383,7 @@ describe('ImportCustomRoles', () => {
383383
},
384384
};
385385

386-
const result = importCustomRoles.serializeWebhooks(apiOptions as any);
386+
const result = importCustomRoles.serializeCustomRoles(apiOptions as any);
387387

388388
expect(result.apiData.rules[0].environments).to.deep.equal(['new-env1', 'new-env2']);
389389
});
@@ -398,7 +398,7 @@ describe('ImportCustomRoles', () => {
398398
},
399399
};
400400

401-
const result = importCustomRoles.serializeWebhooks(apiOptions as any);
401+
const result = importCustomRoles.serializeCustomRoles(apiOptions as any);
402402

403403
expect(result.apiData.rules[0].locales).to.deep.equal(['new-locale1', 'new-locale2']);
404404
});
@@ -413,7 +413,7 @@ describe('ImportCustomRoles', () => {
413413
},
414414
};
415415

416-
const result = importCustomRoles.serializeWebhooks(apiOptions as any);
416+
const result = importCustomRoles.serializeCustomRoles(apiOptions as any);
417417

418418
expect(result.apiData.rules[0].entries).to.deep.equal(['new-entry1', 'new-entry2']);
419419
});
@@ -672,7 +672,7 @@ describe('ImportCustomRoles', () => {
672672
reject: sinon.stub(),
673673
};
674674

675-
const result = importCustomRoles.serializeWebhooks(apiOptions);
675+
const result = importCustomRoles.serializeCustomRoles(apiOptions);
676676

677677
expect(result.entity).to.be.undefined;
678678
});
@@ -693,7 +693,7 @@ describe('ImportCustomRoles', () => {
693693
reject: sinon.stub(),
694694
};
695695

696-
const result = importCustomRoles.serializeWebhooks(apiOptions);
696+
const result = importCustomRoles.serializeCustomRoles(apiOptions);
697697

698698
expect(result.apiData.rules).to.have.length(2);
699699
expect(result.apiData.rules[1]).to.deep.include({
@@ -722,7 +722,7 @@ describe('ImportCustomRoles', () => {
722722
reject: sinon.stub(),
723723
};
724724

725-
const result = importCustomRoles.serializeWebhooks(apiOptions);
725+
const result = importCustomRoles.serializeCustomRoles(apiOptions);
726726

727727
expect(result.apiData.rules).to.have.length(2);
728728
expect(result.apiData.rules[1].module).to.equal('branch');
@@ -744,7 +744,7 @@ describe('ImportCustomRoles', () => {
744744
reject: sinon.stub(),
745745
};
746746

747-
const result = importCustomRoles.serializeWebhooks(apiOptions);
747+
const result = importCustomRoles.serializeCustomRoles(apiOptions);
748748

749749
expect(result.apiData.rules).to.be.an('array');
750750
expect(result.apiData.rules).to.have.length(1);
@@ -771,7 +771,7 @@ describe('ImportCustomRoles', () => {
771771
reject: sinon.stub(),
772772
};
773773

774-
const result = importCustomRoles.serializeWebhooks(apiOptions);
774+
const result = importCustomRoles.serializeCustomRoles(apiOptions);
775775

776776
expect(result.apiData.rules).to.have.length(1);
777777
expect(result.apiData.rules[0]).to.deep.include({
@@ -797,7 +797,7 @@ describe('ImportCustomRoles', () => {
797797
reject: sinon.stub(),
798798
};
799799

800-
const result = importCustomRoles.serializeWebhooks(apiOptions);
800+
const result = importCustomRoles.serializeCustomRoles(apiOptions);
801801

802802
expect(result.apiData.rules).to.be.an('array');
803803
expect(result.apiData.rules).to.have.length(1);
@@ -828,7 +828,7 @@ describe('ImportCustomRoles', () => {
828828
reject: sinon.stub(),
829829
};
830830

831-
const result = importCustomRoles.serializeWebhooks(apiOptions);
831+
const result = importCustomRoles.serializeCustomRoles(apiOptions);
832832

833833
expect(result.apiData.rules).to.have.length(3);
834834
expect(result.apiData.rules[2].module).to.equal('branch');

0 commit comments

Comments
 (0)