Skip to content

Commit 5e1b31c

Browse files
committed
added test cases
1 parent 286e549 commit 5e1b31c

4 files changed

Lines changed: 97 additions & 13 deletions

File tree

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,13 +1202,19 @@ export default class EntriesImport extends BaseClass {
12021202
log.debug(`Found ${cTsWithFieldRules.length} content types with field rules to update`, this.importConfig.context);
12031203

12041204
try {
1205+
// Read content types from individual files
1206+
const cTs = readContentTypeSchemas(this.cTsPath) || [];
12051207
for (let cTUid of cTsWithFieldRules) {
12061208
log.debug(`Processing field rules for content type: ${cTUid}`, this.importConfig.context);
12071209

1208-
// Read content types from individual files
1209-
const cTs = readContentTypeSchemas(this.cTsPath);
1210+
12101211
const contentType: any = find(cTs, { uid: cTUid });
12111212

1213+
if (!contentType) {
1214+
log.debug(`Content type ${cTUid} not found in schemas`, this.importConfig.context);
1215+
continue;
1216+
}
1217+
12121218
if (contentType.field_rules) {
12131219
log.debug(
12141220
`Found ${contentType.field_rules.length} field rules for content type: ${cTUid}`,

packages/contentstack-import/test/unit/import/modules/content-types.test.ts

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { fsUtil } from '../../../../src/utils';
66
import * as contentTypeHelper from '../../../../src/utils/content-type-helper';
77
import * as extensionHelper from '../../../../src/utils/extension-helper';
88
import * as taxonomiesHelper from '../../../../src/utils/taxonomies-helper';
9+
import { FsUtility } from '@contentstack/cli-utilities';
910

1011
describe('ImportContentTypes', () => {
1112
let importContentTypes: ImportContentTypes;
@@ -16,6 +17,8 @@ describe('ImportContentTypes', () => {
1617
let lookupExtensionStub: sinon.SinonStub;
1718
let lookUpTaxonomyStub: sinon.SinonStub;
1819
let makeConcurrentCallStub: sinon.SinonStub;
20+
let fsUtilityReaddirStub: sinon.SinonStub;
21+
let fsUtilityReadFileStub: sinon.SinonStub;
1922

2023
beforeEach(() => {
2124
fsUtilStub = {
@@ -27,6 +30,46 @@ describe('ImportContentTypes', () => {
2730
sinon.stub(fsUtil, 'writeFile').callsFake(fsUtilStub.writeFile);
2831
sinon.stub(fsUtil, 'makeDirectory').callsFake(fsUtilStub.makeDirectory);
2932

33+
// Stub FsUtility prototype to make readContentTypeSchemas work
34+
// readContentTypeSchemas reads individual JSON files (ignoring schema.json)
35+
// We'll check what fsUtilStub.readFile returns for schema.json and use that to populate individual files
36+
fsUtilityReaddirStub = sinon.stub(FsUtility.prototype, 'readdir').callsFake((dirPath: string) => {
37+
// Try to get mock CTs from the test's fsUtilStub setup for schema.json
38+
// This allows tests to continue using schema.json pattern
39+
try {
40+
const mockCTs = fsUtilStub.readFile(dirPath + '/schema.json');
41+
if (Array.isArray(mockCTs) && mockCTs.length > 0) {
42+
return mockCTs.map((ct: any) => `${ct.uid}.json`);
43+
}
44+
} catch (e) {
45+
// If schema.json isn't stubbed, return empty
46+
}
47+
return [];
48+
});
49+
50+
fsUtilityReadFileStub = sinon.stub(FsUtility.prototype, 'readFile').callsFake((filePath: string) => {
51+
// Extract the UID from the file path and return matching content type
52+
const match = filePath.match(/([^\/]+)\.json$/);
53+
if (match) {
54+
const uid = match[1];
55+
const dirPath = filePath.substring(0, filePath.lastIndexOf('/'));
56+
try {
57+
// Check if test has stubbed schema.json with mock content types
58+
const mockCTs = fsUtilStub.readFile(dirPath + '/schema.json');
59+
if (Array.isArray(mockCTs)) {
60+
const ct = mockCTs.find((ct: any) => ct.uid === uid);
61+
if (ct) {
62+
// FsUtility.readFile returns parsed JSON (object), not string
63+
return ct;
64+
}
65+
}
66+
} catch (e) {
67+
// If schema.json isn't stubbed, return undefined (file doesn't exist)
68+
}
69+
}
70+
return undefined;
71+
});
72+
3073
updateFieldRulesStub = sinon.stub(contentTypeHelper, 'updateFieldRules');
3174
lookupExtensionStub = sinon.stub(extensionHelper, 'lookupExtension');
3275
lookUpTaxonomyStub = sinon.stub(taxonomiesHelper, 'lookUpTaxonomy');
@@ -1168,13 +1211,17 @@ describe('ImportContentTypes', () => {
11681211
describe('analyzeImportData() with individual content type files', () => {
11691212
it('should read content types from individual files', async () => {
11701213
const mockContentTypes = [
1171-
{ uid: 'ct-1', title: 'CT 1', schema: [] },
1172-
{ uid: 'ct-2', title: 'CT 2', schema: [] },
1214+
{ uid: 'ct-1', title: 'CT 1', schema: [] as any },
1215+
{ uid: 'ct-2', title: 'CT 2', schema: [] as any },
11731216
];
11741217

1175-
// Stub readContentTypeSchemas to return mock content types
1176-
const readContentTypeSchemasStub = sinon.stub().returns(mockContentTypes);
1177-
sinon.stub(require('@contentstack/cli-utilities'), 'readContentTypeSchemas').value(readContentTypeSchemasStub);
1218+
// Configure FsUtility stubs to make readContentTypeSchemas return mock content types
1219+
(FsUtility.prototype.readdir as sinon.SinonStub).returns(['ct-1.json', 'ct-2.json']);
1220+
(FsUtility.prototype.readFile as sinon.SinonStub).callsFake((filePath: string) => {
1221+
if (filePath.includes('ct-1.json')) return JSON.stringify(mockContentTypes[0]);
1222+
if (filePath.includes('ct-2.json')) return JSON.stringify(mockContentTypes[1]);
1223+
return '{}';
1224+
});
11781225

11791226
fsUtilStub.readFile.returns([]);
11801227

@@ -1184,10 +1231,7 @@ describe('ImportContentTypes', () => {
11841231
});
11851232

11861233
it('should return empty array when no individual files are found', async () => {
1187-
// Stub readContentTypeSchemas to return empty array (no individual files)
1188-
const readContentTypeSchemasStub = sinon.stub().returns([]);
1189-
sinon.stub(require('@contentstack/cli-utilities'), 'readContentTypeSchemas').value(readContentTypeSchemasStub);
1190-
1234+
// readdir returns [] by default, so readContentTypeSchemas will return []
11911235
fsUtilStub.readFile.returns([]);
11921236

11931237
await (importContentTypes as any).analyzeImportData();

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ describe('EntriesImport', () => {
2727
sinon.stub(FsUtility.prototype, 'createFolderIfNotExist').callsFake(() => {
2828
return Promise.resolve();
2929
});
30+
31+
// Stub FsUtility prototype to support readContentTypeSchemas
32+
// readContentTypeSchemas reads individual JSON files and returns parsed objects
33+
sinon.stub(FsUtility.prototype, 'readdir').returns([]);
34+
sinon.stub(FsUtility.prototype, 'readFile').returns(undefined);
35+
3036
fsUtilityReadFileStub = sinon.stub(fsUtil, 'readFile');
3137
fsUtilityWriteFileStub = sinon.stub(fsUtil, 'writeFile').callsFake(() => {
3238
return Promise.resolve();
@@ -505,6 +511,10 @@ describe('EntriesImport', () => {
505511
}
506512
return {};
507513
});
514+
515+
// Override FsUtility stubs to return field_rules_ct
516+
(FsUtility.prototype.readdir as sinon.SinonStub).returns(['field_rules_ct.json']);
517+
(FsUtility.prototype.readFile as sinon.SinonStub).returns(mockData.contentTypeWithFieldRules);
508518
});
509519

510520
it('should update field rules with new UIDs', async () => {
@@ -539,6 +549,9 @@ describe('EntriesImport', () => {
539549
});
540550

541551
it('should handle content type not found', async () => {
552+
// This test expects the content type to be in schemas but API fetch returns null
553+
// The beforeEach already sets up field_rules_ct, so this should work
554+
542555
mockStackClient.contentType.returns({
543556
fetch: sinon.stub().resolves(null),
544557
});
@@ -563,6 +576,9 @@ describe('EntriesImport', () => {
563576
}
564577
return {};
565578
});
579+
580+
// Override FsUtility.readFile for this test
581+
(FsUtility.prototype.readFile as sinon.SinonStub).returns(contentTypeWithoutFieldRules);
566582

567583
await entriesImport['updateFieldRules']();
568584

@@ -3096,9 +3112,21 @@ describe('EntriesImport', () => {
30963112
});
30973113

30983114
describe('updateFieldRules() Method Error Handling', () => {
3115+
beforeEach(() => {
3116+
// Override FsUtility stubs to return mock content types
3117+
(FsUtility.prototype.readdir as sinon.SinonStub).returns(['simple_ct.json', 'ref_ct.json']);
3118+
});
3119+
30993120
it('should handle content type fetch error', async () => {
31003121
const mockContentTypes = [mockData.simpleContentType, mockData.contentTypeWithReferences];
31013122

3123+
// Configure FsUtility.readFile to return the right content type based on file name
3124+
(FsUtility.prototype.readFile as sinon.SinonStub).callsFake((filePath: string) => {
3125+
if (filePath.includes('simple_ct.json')) return JSON.stringify(mockData.simpleContentType);
3126+
if (filePath.includes('ref_ct.json')) return JSON.stringify(mockData.contentTypeWithReferences);
3127+
return '{}';
3128+
});
3129+
31023130
fsUtilityReadFileStub.callsFake((filePath) => {
31033131
console.log('fsUtil.readFile called with path:', filePath);
31043132
if (filePath.includes('field_rules_uid.json')) {
@@ -3134,6 +3162,8 @@ describe('EntriesImport', () => {
31343162
it('should handle content type update error', async () => {
31353163
const mockContentTypes = [mockData.simpleContentType, mockData.contentTypeWithReferences];
31363164

3165+
(FsUtility.prototype.readFile as sinon.SinonStub).returns(JSON.stringify(mockData.simpleContentType));
3166+
31373167
fsUtilityReadFileStub.callsFake((path) => {
31383168
if (path.includes('field_rules_uid.json')) {
31393169
return ['simple_ct']; // array of strings
@@ -3171,6 +3201,8 @@ describe('EntriesImport', () => {
31713201
it('should skip when content type not found', async () => {
31723202
const mockContentTypes = [mockData.simpleContentType, mockData.contentTypeWithReferences];
31733203

3204+
(FsUtility.prototype.readFile as sinon.SinonStub).returns(JSON.stringify(mockData.simpleContentType));
3205+
31743206
fsUtilityReadFileStub.callsFake((path) => {
31753207
if (path.includes('field_rules_uid.json')) {
31763208
return ['simple_ct']; // array of strings
@@ -3213,6 +3245,8 @@ describe('EntriesImport', () => {
32133245
delete contentTypeWithoutRules.field_rules;
32143246
const mockContentTypes = [contentTypeWithoutRules];
32153247

3248+
(FsUtility.prototype.readFile as sinon.SinonStub).returns(JSON.stringify(contentTypeWithoutRules));
3249+
32163250
fsUtilityReadFileStub.callsFake((path) => {
32173251
if (path.includes('field_rules_uid.json')) {
32183252
return ['simple_ct']; // array of strings

packages/contentstack-utilities/src/content-type-utils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ import { FsUtility } from './fs-utility';
1010
export function readContentTypeSchemas(
1111
dirPath: string,
1212
ignoredFiles: string[] = ['schema.json', '.DS_Store', '__master.json', '__priority.json'],
13-
): Record<string, unknown>[] {
13+
): Record<string, unknown>[] | null {
1414
const fsUtil = new FsUtility();
1515
const files = fsUtil.readdir(dirPath);
1616

1717
if (!files || files.length === 0) {
18-
return [];
18+
return null;
1919
}
2020

2121
const contentTypes: Record<string, unknown>[] = [];

0 commit comments

Comments
 (0)