Skip to content

Commit 471180b

Browse files
cs-rajclaude
andcommitted
test(DX-9464): fix broken export tests, remove 13 stale globalfields.json stubs, add per-uid file assertions across export/import/audit
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 1d24e01 commit 471180b

4 files changed

Lines changed: 159 additions & 56 deletions

File tree

packages/contentstack-audit/test/unit/audit-base-command.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,30 @@ describe('AuditBaseCommand class', () => {
369369
gfSchema: [],
370370
});
371371
});
372+
373+
fancy
374+
.stdout({ print: process.env.PRINT === 'true' || false })
375+
.stub(winston.transports, 'File', () => fsTransport)
376+
.stub(winston, 'createLogger', createMockWinstonLogger)
377+
.stub(fs, 'createWriteStream', () => new PassThrough())
378+
.it('should return per-uid global field schemas and skip globalfields.json', async () => {
379+
class CMD extends AuditBaseCommand {
380+
async run() {
381+
// Point basePath at mock/contents which has global_fields/gf_1.json (per-uid)
382+
// and global_fields/globalfields.json (bulk legacy — must be ignored)
383+
this.sharedConfig.basePath = resolve(__dirname, 'mock', 'contents');
384+
return this.getCtAndGfSchema();
385+
}
386+
}
387+
388+
const result = await CMD.run([]);
389+
// gf_1.json is read; globalfields.json is excluded by readGlobalFieldSchemas
390+
expect(result.gfSchema).to.be.an('array');
391+
expect(result.gfSchema.length).to.equal(1);
392+
expect((result.gfSchema[0] as any).uid).to.equal('gf_1');
393+
// content_types dir absent → ctSchema empty
394+
expect(result.ctSchema).to.deep.equal([]);
395+
});
372396
});
373397

374398
describe('Progress Manager Integration', () => {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"uid": "gf_1",
3+
"title": "GF - 1",
4+
"schema": [
5+
{
6+
"data_type": "text",
7+
"display_name": "Single Line Textbox",
8+
"uid": "single_line",
9+
"mandatory": false,
10+
"multiple": false,
11+
"non_localizable": false,
12+
"unique": false
13+
}
14+
]
15+
}

packages/contentstack-export/test/unit/export/modules/global-fields.test.ts

Lines changed: 50 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,9 @@ describe('ExportGlobalFields', () => {
112112
});
113113
});
114114

115-
it('should initialize empty globalFields array', () => {
116-
expect(exportGlobalFields.globalFields).to.be.an('array');
117-
expect(exportGlobalFields.globalFields.length).to.equal(0);
115+
it('should initialize global fields dir path', () => {
116+
expect(exportGlobalFields.globalFieldsDirPath).to.be.a('string');
117+
expect(exportGlobalFields.globalFieldsDirPath).to.include('global_fields');
118118
});
119119

120120
it('should set correct directory path', () => {
@@ -140,12 +140,12 @@ describe('ExportGlobalFields', () => {
140140

141141
await exportGlobalFields.getGlobalFields();
142142

143-
// Verify global fields were processed
144-
expect(exportGlobalFields.globalFields.length).to.equal(2);
145-
// Verify invalid keys were removed
146-
expect(exportGlobalFields.globalFields[0].invalidKey).to.be.undefined;
147-
expect(exportGlobalFields.globalFields[0].uid).to.equal('gf-1');
148-
expect(exportGlobalFields.globalFields[0].title).to.equal('Field 1');
143+
// Verify each global field written to its own per-uid file (not globalfields.json)
144+
const writeFileStub = FsUtility.prototype.writeFile as sinon.SinonStub;
145+
expect(writeFileStub.callCount).to.equal(2);
146+
expect(writeFileStub.calledWith(sinon.match(/gf-1\.json/))).to.be.true;
147+
expect(writeFileStub.calledWith(sinon.match(/gf-2\.json/))).to.be.true;
148+
expect(writeFileStub.neverCalledWith(sinon.match(/globalfields\.json/))).to.be.true;
149149
});
150150

151151
it('should call getGlobalFields recursively when more fields exist', async () => {
@@ -171,9 +171,10 @@ describe('ExportGlobalFields', () => {
171171

172172
await exportGlobalFields.getGlobalFields();
173173

174-
// Verify multiple calls were made
174+
// Verify multiple calls were made and each item written as per-uid file
175175
expect(callCount).to.be.greaterThan(1);
176-
expect(exportGlobalFields.globalFields.length).to.equal(150);
176+
const writeFileStub = FsUtility.prototype.writeFile as sinon.SinonStub;
177+
expect(writeFileStub.callCount).to.equal(150);
177178
});
178179

179180
it('should handle API errors gracefully', async () => {
@@ -201,11 +202,11 @@ describe('ExportGlobalFields', () => {
201202
}),
202203
});
203204

204-
const initialCount = exportGlobalFields.globalFields.length;
205+
const writeFileStub = FsUtility.prototype.writeFile as sinon.SinonStub;
205206
await exportGlobalFields.getGlobalFields();
206207

207-
// Verify no new global fields were added
208-
expect(exportGlobalFields.globalFields.length).to.equal(initialCount);
208+
// No items → writeFile never called
209+
expect(writeFileStub.called).to.be.false;
209210
});
210211

211212
it('should handle empty items array', async () => {
@@ -218,11 +219,11 @@ describe('ExportGlobalFields', () => {
218219
}),
219220
});
220221

221-
const initialCount = exportGlobalFields.globalFields.length;
222+
const writeFileStub = FsUtility.prototype.writeFile as sinon.SinonStub;
222223
await exportGlobalFields.getGlobalFields();
223224

224-
// Verify no processing occurred with null items
225-
expect(exportGlobalFields.globalFields.length).to.equal(initialCount);
225+
// Null items → writeFile never called
226+
expect(writeFileStub.called).to.be.false;
226227
});
227228

228229
it('should update query params with skip value', async () => {
@@ -251,28 +252,33 @@ describe('ExportGlobalFields', () => {
251252

252253
exportGlobalFields.sanitizeAttribs(globalFields);
253254

254-
// Verify invalid keys were removed
255-
expect(exportGlobalFields.globalFields[0].invalidKey).to.be.undefined;
256-
expect(exportGlobalFields.globalFields[0].uid).to.equal('gf-1');
257-
expect(exportGlobalFields.globalFields[0].title).to.equal('Field 1');
258-
expect(exportGlobalFields.globalFields[0].validKey).to.equal('value1');
255+
// sanitizeAttribs modifies the array elements in-place
256+
expect(globalFields[0].invalidKey).to.be.undefined;
257+
expect(globalFields[0].uid).to.equal('gf-1');
258+
expect(globalFields[0].title).to.equal('Field 1');
259+
expect(globalFields[0].validKey).to.equal('value1');
260+
// Each field written to its own per-uid file (never to globalfields.json)
261+
const writeFileStub = FsUtility.prototype.writeFile as sinon.SinonStub;
262+
expect(writeFileStub.calledWith(sinon.match(/gf-1\.json/))).to.be.true;
263+
expect(writeFileStub.calledWith(sinon.match(/gf-2\.json/))).to.be.true;
264+
expect(writeFileStub.neverCalledWith(sinon.match(/globalfields\.json/))).to.be.true;
259265
});
260266

261267
it('should handle global fields without required keys', () => {
262268
const globalFields = [{ uid: 'gf-1', invalidKey: 'remove' }];
263269

264270
exportGlobalFields.sanitizeAttribs(globalFields);
265271

266-
expect(exportGlobalFields.globalFields[0]).to.exist;
267-
expect(exportGlobalFields.globalFields[0].invalidKey).to.be.undefined;
272+
expect(globalFields[0]).to.exist;
273+
expect(globalFields[0].invalidKey).to.be.undefined;
268274
});
269275

270276
it('should handle empty global fields array', () => {
271277
const globalFields: any[] = [];
272278

273279
exportGlobalFields.sanitizeAttribs(globalFields);
274280

275-
expect(exportGlobalFields.globalFields.length).to.equal(0);
281+
expect(globalFields.length).to.equal(0);
276282
});
277283

278284
it('should keep only valid keys from validKeys config', () => {
@@ -289,7 +295,7 @@ describe('ExportGlobalFields', () => {
289295

290296
exportGlobalFields.sanitizeAttribs(globalFields);
291297

292-
const processedField = exportGlobalFields.globalFields[0];
298+
const processedField = globalFields[0];
293299

294300
// Should only keep uid, title, validKey
295301
expect(processedField.keyToRemove1).to.be.undefined;
@@ -298,6 +304,10 @@ describe('ExportGlobalFields', () => {
298304
expect(processedField.uid).to.equal('gf-1');
299305
expect(processedField.title).to.equal('Field 1');
300306
expect(processedField.validKey).to.equal('value1');
307+
// Written to per-uid file path
308+
const writeFileStub = FsUtility.prototype.writeFile as sinon.SinonStub;
309+
expect(writeFileStub.calledWith(sinon.match(/gf-1\.json/))).to.be.true;
310+
expect(writeFileStub.neverCalledWith(sinon.match(/globalfields\.json/))).to.be.true;
301311
});
302312
});
303313

@@ -322,16 +332,14 @@ describe('ExportGlobalFields', () => {
322332

323333
await exportGlobalFields.start();
324334

325-
// Verify global fields were processed
326-
expect(exportGlobalFields.globalFields.length).to.equal(2);
327-
expect(exportGlobalFields.globalFields[0].uid).to.equal('gf-1');
328-
expect(exportGlobalFields.globalFields[1].uid).to.equal('gf-2');
329-
// Verify file was written
330-
expect(writeFileStub.called).to.be.true;
335+
// Verify each field written to its own per-uid file (not globalfields.json)
336+
expect(writeFileStub.calledWith(sinon.match(/gf-1\.json/))).to.be.true;
337+
expect(writeFileStub.calledWith(sinon.match(/gf-2\.json/))).to.be.true;
338+
expect(writeFileStub.neverCalledWith(sinon.match(/globalfields\.json/))).to.be.true;
331339
expect(makeDirectoryStub.called).to.be.true;
332340
});
333341

334-
it('should handle empty global fields and still write file', async () => {
342+
it('should return early when no global fields found', async () => {
335343
const writeFileStub = FsUtility.prototype.writeFile as sinon.SinonStub;
336344

337345
mockStackClient.globalField.returns({
@@ -343,12 +351,10 @@ describe('ExportGlobalFields', () => {
343351
}),
344352
});
345353

346-
exportGlobalFields.globalFields = [];
347354
await exportGlobalFields.start();
348355

349-
// Verify writeFile was called even with empty array
350-
expect(writeFileStub.called).to.be.true;
351-
expect(exportGlobalFields.globalFields.length).to.equal(0);
356+
// start() exits early on count=0 — no per-uid files written
357+
expect(writeFileStub.called).to.be.false;
352358
});
353359

354360
it('should handle errors during export without throwing', async () => {
@@ -398,9 +404,11 @@ describe('ExportGlobalFields', () => {
398404

399405
await exportGlobalFields.start();
400406

401-
// Verify all fields were processed
402-
expect(exportGlobalFields.globalFields.length).to.equal(150);
407+
// Verify all fields processed — one writeFile call per item, no globalfields.json
408+
const writeFileStub = FsUtility.prototype.writeFile as sinon.SinonStub;
409+
expect(writeFileStub.callCount).to.equal(150);
403410
expect(callCount).to.be.greaterThan(1);
411+
expect(writeFileStub.neverCalledWith(sinon.match(/globalfields\.json/))).to.be.true;
404412
});
405413

406414
it('should call makeDirectory and writeFile with correct paths', async () => {
@@ -418,9 +426,10 @@ describe('ExportGlobalFields', () => {
418426

419427
await exportGlobalFields.start();
420428

421-
// Verify directories and files were created
429+
// Verify directory created and per-uid file written (not globalfields.json)
422430
expect(makeDirectoryStub.called).to.be.true;
423-
expect(writeFileStub.called).to.be.true;
431+
expect(writeFileStub.calledWith(sinon.match(/gf-1\.json/))).to.be.true;
432+
expect(writeFileStub.neverCalledWith(sinon.match(/globalfields\.json/))).to.be.true;
424433
});
425434
});
426435
});

0 commit comments

Comments
 (0)