Skip to content

Commit f14bac7

Browse files
author
naman-contentstack
committed
chore: updated test cases
1 parent 3d7b5f0 commit f14bac7

7 files changed

Lines changed: 104 additions & 113 deletions

File tree

packages/contentstack-asset-management/test/unit/export/asset-types.test.ts

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,7 @@ describe('ExportAssetTypes', () => {
4646
const exporter = new ExportAssetTypes(apiConfig, exportContext);
4747
await exporter.start(spaceUid);
4848

49-
expect(getStub.calledOnce).to.be.true;
50-
expect(getStub.calledWith(spaceUid)).to.be.true;
49+
expect(getStub.firstCall.args[0]).to.equal(spaceUid);
5150
});
5251

5352
it('should write asset types with correct chunked JSON args', async () => {
@@ -56,7 +55,6 @@ describe('ExportAssetTypes', () => {
5655
await exporter.start(spaceUid);
5756

5857
const writeStub = (AssetManagementExportAdapter.prototype as any).writeItemsToChunkedJson as sinon.SinonStub;
59-
expect(writeStub.calledOnce).to.be.true;
6058
const args = writeStub.firstCall.args;
6159
expect(args[0]).to.equal(assetTypesDir);
6260
expect(args[1]).to.equal('asset-types.json');
@@ -75,21 +73,16 @@ describe('ExportAssetTypes', () => {
7573
await exporter.start(spaceUid);
7674

7775
const writeStub = (AssetManagementExportAdapter.prototype as any).writeItemsToChunkedJson as sinon.SinonStub;
78-
expect(writeStub.calledOnce).to.be.true;
7976
expect(writeStub.firstCall.args[4]).to.deep.equal([]);
8077
});
8178

82-
it('should call tick on success', async () => {
79+
it('should tick with success=true, the asset types process name, and null error', async () => {
8380
sinon.stub(ExportAssetTypes.prototype, 'getWorkspaceAssetTypes').resolves(assetTypesResponse);
8481
const exporter = new ExportAssetTypes(apiConfig, exportContext);
8582
await exporter.start(spaceUid);
8683

8784
const tickStub = (AssetManagementExportAdapter.prototype as any).tick as sinon.SinonStub;
88-
expect(tickStub.called).to.be.true;
89-
const args = tickStub.firstCall.args;
90-
expect(args[0]).to.be.true;
91-
expect(args[1]).to.equal(PROCESS_NAMES.AM_ASSET_TYPES);
92-
expect(args[2]).to.be.null;
85+
expect(tickStub.firstCall.args).to.deep.equal([true, PROCESS_NAMES.AM_ASSET_TYPES, null]);
9386
});
9487
});
9588
});

packages/contentstack-asset-management/test/unit/export/assets.test.ts

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -60,17 +60,15 @@ describe('ExportAssets', () => {
6060
});
6161

6262
describe('start method', () => {
63-
it('should fetch folders and assets in parallel', async () => {
63+
it('should fetch folders and assets using the workspace space_uid', async () => {
6464
const foldersStub = sinon.stub(ExportAssets.prototype, 'getWorkspaceFolders').resolves(foldersData);
6565
const assetsStub = sinon.stub(ExportAssets.prototype, 'getWorkspaceAssets').resolves(emptyAssetsResponse);
6666

6767
const exporter = new ExportAssets(apiConfig, exportContext);
6868
await exporter.start(workspace, spaceDir);
6969

70-
expect(foldersStub.calledOnce).to.be.true;
71-
expect(foldersStub.calledWith(workspace.space_uid)).to.be.true;
72-
expect(assetsStub.calledOnce).to.be.true;
73-
expect(assetsStub.calledWith(workspace.space_uid)).to.be.true;
70+
expect(foldersStub.firstCall.args[0]).to.equal(workspace.space_uid);
71+
expect(assetsStub.firstCall.args[0]).to.equal(workspace.space_uid);
7472
});
7573

7674
it('should write chunked assets metadata with correct args', async () => {
@@ -82,27 +80,27 @@ describe('ExportAssets', () => {
8280
await exporter.start(workspace, spaceDir);
8381

8482
const writeStub = (AssetManagementExportAdapter.prototype as any).writeItemsToChunkedJson as sinon.SinonStub;
85-
expect(writeStub.calledOnce).to.be.true;
8683
const args = writeStub.firstCall.args;
8784
expect(args[1]).to.equal('assets.json');
8885
expect(args[2]).to.equal('assets');
8986
expect(args[3]).to.deep.equal(['uid', 'url', 'filename', 'file_name', 'parent_uid']);
9087
expect(args[4]).to.have.length(2);
9188
});
9289

93-
it('should skip downloads when no asset items exist', async () => {
90+
it('should not attempt any downloads when the asset list is empty', async () => {
9491
sinon.stub(ExportAssets.prototype, 'getWorkspaceFolders').resolves(foldersData);
9592
sinon.stub(ExportAssets.prototype, 'getWorkspaceAssets').resolves(emptyAssetsResponse);
9693

9794
const exporter = new ExportAssets(apiConfig, exportContext);
9895
await exporter.start(workspace, spaceDir);
9996

97+
expect(fetchStub.callCount).to.equal(0);
10098
const tickStub = (AssetManagementExportAdapter.prototype as any).tick as sinon.SinonStub;
10199
const downloadTick = tickStub.getCalls().find((c) => String(c.args[1]).startsWith('downloads:'));
102100
expect(downloadTick).to.be.undefined;
103101
});
104102

105-
it('should handle download failures gracefully without throwing', async () => {
103+
it('should tick with success=false and the error message on download failure', async () => {
106104
sinon.stub(ExportAssets.prototype, 'getWorkspaceFolders').resolves(foldersData);
107105
sinon.stub(ExportAssets.prototype, 'getWorkspaceAssets').resolves(assetsResponseWithItems);
108106
fetchStub.rejects(new Error('network failure'));
@@ -112,12 +110,11 @@ describe('ExportAssets', () => {
112110

113111
const tickStub = (AssetManagementExportAdapter.prototype as any).tick as sinon.SinonStub;
114112
const downloadTick = tickStub.getCalls().find((c) => String(c.args[1]).startsWith('downloads:'));
115-
expect(downloadTick).to.not.be.undefined;
116113
expect(downloadTick!.args[0]).to.be.false;
117114
expect(downloadTick!.args[2]).to.equal('network failure');
118115
});
119116

120-
it('should tick success for downloads when all succeed', async () => {
117+
it('should tick with success=true and null error on successful downloads', async () => {
121118
sinon.stub(ExportAssets.prototype, 'getWorkspaceFolders').resolves(foldersData);
122119
sinon.stub(ExportAssets.prototype, 'getWorkspaceAssets').resolves(assetsResponseWithItems);
123120
fetchStub.callsFake(async () => makeFetchResponse() as any);
@@ -127,12 +124,11 @@ describe('ExportAssets', () => {
127124

128125
const tickStub = (AssetManagementExportAdapter.prototype as any).tick as sinon.SinonStub;
129126
const downloadTick = tickStub.getCalls().find((c) => String(c.args[1]).startsWith('downloads:'));
130-
expect(downloadTick).to.not.be.undefined;
131127
expect(downloadTick!.args[0]).to.be.true;
132128
expect(downloadTick!.args[2]).to.be.null;
133129
});
134130

135-
it('should skip assets with no url or uid', async () => {
131+
it('should skip assets that have neither a url nor a uid', async () => {
136132
const incompleteAssets = {
137133
items: [
138134
{ uid: 'a1', url: null as any },
@@ -146,10 +142,10 @@ describe('ExportAssets', () => {
146142
const exporter = new ExportAssets(apiConfig, exportContext);
147143
await exporter.start(workspace, spaceDir);
148144

149-
expect(fetchStub.called).to.be.false;
145+
expect(fetchStub.callCount).to.equal(0);
150146
});
151147

152-
it('should use _uid when uid is not present on asset', async () => {
148+
it('should process assets that have _uid instead of uid without skipping them', async () => {
153149
const assetsWithUnderscoreUid = {
154150
items: [{ _uid: 'a-uid', url: 'https://cdn.example.com/a.png', filename: 'a.png' }],
155151
};
@@ -160,17 +156,18 @@ describe('ExportAssets', () => {
160156
const exporter = new ExportAssets(apiConfig, exportContext);
161157
await exporter.start(workspace, spaceDir);
162158

159+
expect(fetchStub.firstCall.args[0]).to.equal('https://cdn.example.com/a.png');
163160
const tickStub = (AssetManagementExportAdapter.prototype as any).tick as sinon.SinonStub;
164161
const downloadTick = tickStub.getCalls().find((c) => String(c.args[1]).startsWith('downloads:'));
165-
expect(downloadTick).to.not.be.undefined;
166162
expect(downloadTick!.args[0]).to.be.true;
163+
expect(downloadTick!.args[2]).to.be.null;
167164
});
168165

169-
it('should use file_name when filename is not present, defaulting to "asset"', async () => {
166+
it('should download assets that use file_name, and fall back to "asset" when both names are absent', async () => {
170167
const assetsNoFilename = {
171168
items: [
172-
{ uid: 'a1', url: 'https://cdn.example.com/a1', file_name: 'named.pdf' },
173-
{ uid: 'a2', url: 'https://cdn.example.com/a2' },
169+
{ uid: 'a1', url: 'https://cdn.example.com/a1.pdf', file_name: 'named.pdf' },
170+
{ uid: 'a2', url: 'https://cdn.example.com/a2.bin' },
174171
],
175172
};
176173
sinon.stub(ExportAssets.prototype, 'getWorkspaceFolders').resolves(foldersData);
@@ -181,6 +178,11 @@ describe('ExportAssets', () => {
181178
await exporter.start(workspace, spaceDir);
182179

183180
expect(fetchStub.callCount).to.equal(2);
181+
expect(fetchStub.firstCall.args[0]).to.equal('https://cdn.example.com/a1.pdf');
182+
expect(fetchStub.secondCall.args[0]).to.equal('https://cdn.example.com/a2.bin');
183+
const tickStub = (AssetManagementExportAdapter.prototype as any).tick as sinon.SinonStub;
184+
const downloadTick = tickStub.getCalls().find((c) => String(c.args[1]).startsWith('downloads:'));
185+
expect(downloadTick!.args[0]).to.be.true;
184186
});
185187

186188
it('should append authtoken to URL when securedAssets is true', async () => {
@@ -215,7 +217,7 @@ describe('ExportAssets', () => {
215217
expect(downloadUrl).to.include('?v=1&authtoken=');
216218
});
217219

218-
it('should handle non-ok HTTP response as download failure', async () => {
220+
it('should tick with success=false and the HTTP status code on non-ok response', async () => {
219221
sinon.stub(ExportAssets.prototype, 'getWorkspaceFolders').resolves(foldersData);
220222
sinon.stub(ExportAssets.prototype, 'getWorkspaceAssets').resolves({
221223
items: [{ uid: 'a1', url: 'https://cdn.example.com/a1.png', filename: 'img.png' }],
@@ -231,7 +233,7 @@ describe('ExportAssets', () => {
231233
expect(downloadTick!.args[2]).to.include('403');
232234
});
233235

234-
it('should handle missing response body as download failure', async () => {
236+
it('should tick with success=false and "No response body" when body is null', async () => {
235237
sinon.stub(ExportAssets.prototype, 'getWorkspaceFolders').resolves(foldersData);
236238
sinon.stub(ExportAssets.prototype, 'getWorkspaceAssets').resolves({
237239
items: [{ uid: 'a1', url: 'https://cdn.example.com/a1.png', filename: 'img.png' }],

packages/contentstack-asset-management/test/unit/export/base.test.ts

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,16 @@ describe('AssetManagementExportAdapter (base)', () => {
6161
expect(adapter.spacesRootPathPublic).to.equal('/tmp/export/spaces');
6262
});
6363

64-
it('should build getAssetTypesDir from spacesRootPath', () => {
64+
it('should build getAssetTypesDir as <spacesRootPath>/asset_types', () => {
6565
const adapter = new TestAdapter(apiConfig, exportContext);
66-
expect(adapter.getAssetTypesDirPublic()).to.include('asset_types');
66+
const expected = require('node:path').join('/tmp/export/spaces', 'asset_types');
67+
expect(adapter.getAssetTypesDirPublic()).to.equal(expected);
6768
});
6869

69-
it('should build getFieldsDir from spacesRootPath', () => {
70+
it('should build getFieldsDir as <spacesRootPath>/fields', () => {
7071
const adapter = new TestAdapter(apiConfig, exportContext);
71-
expect(adapter.getFieldsDirPublic()).to.include('fields');
72+
const expected = require('node:path').join('/tmp/export/spaces', 'fields');
73+
expect(adapter.getFieldsDirPublic()).to.equal(expected);
7274
});
7375
});
7476

@@ -97,15 +99,14 @@ describe('AssetManagementExportAdapter (base)', () => {
9799
});
98100

99101
describe('createNestedProgress', () => {
100-
it('should create a new CLIProgressManager when no parent is set', () => {
101-
const getStub = sinon.stub(configHandler, 'get').returns({ showConsoleLogs: true });
102+
it('should create a new CLIProgressManager with the given name and showConsoleLogs flag', () => {
103+
sinon.stub(configHandler, 'get').returns({ showConsoleLogs: true });
102104
const fakeProgress = { tick: sinon.stub() } as any;
103105
const createNestedStub = sinon.stub(CLIProgressManager, 'createNested').returns(fakeProgress);
104106

105107
const adapter = new TestAdapter(apiConfig, exportContext);
106108
const result = adapter.callCreateNestedProgress('my-module');
107109

108-
expect(createNestedStub.calledOnce).to.be.true;
109110
expect(createNestedStub.firstCall.args[0]).to.equal('my-module');
110111
expect(result).to.equal(fakeProgress);
111112
});
@@ -132,18 +133,16 @@ describe('AssetManagementExportAdapter (base)', () => {
132133
});
133134

134135
describe('tick', () => {
135-
it('should call tick on progressOrParent when available', () => {
136+
it('should forward success, item name, and error to the progress manager tick', () => {
136137
const fakeParent = { tick: sinon.stub(), updateStatus: sinon.stub() } as any;
137138
const adapter = new TestAdapter(apiConfig, exportContext);
138139
adapter.setParentProgressManager(fakeParent);
139140

140141
adapter.callTick(true, 'my-item', null);
141142

142-
expect(fakeParent.tick.calledOnce).to.be.true;
143-
const args = fakeParent.tick.firstCall.args;
144-
expect(args[0]).to.be.true;
145-
expect(args[1]).to.equal('my-item');
146-
expect(args[2]).to.be.null;
143+
expect(fakeParent.tick.firstCall.args[0]).to.equal(true);
144+
expect(fakeParent.tick.firstCall.args[1]).to.equal('my-item');
145+
expect(fakeParent.tick.firstCall.args[2]).to.be.null;
147146
});
148147

149148
it('should not throw when progressOrParent is null', () => {
@@ -153,14 +152,13 @@ describe('AssetManagementExportAdapter (base)', () => {
153152
});
154153

155154
describe('updateStatus', () => {
156-
it('should call updateStatus on progressOrParent when available', () => {
155+
it('should forward the status message to the progress manager', () => {
157156
const fakeParent = { tick: sinon.stub(), updateStatus: sinon.stub() } as any;
158157
const adapter = new TestAdapter(apiConfig, exportContext);
159158
adapter.setParentProgressManager(fakeParent);
160159

161160
adapter.callUpdateStatus('Fetching...');
162161

163-
expect(fakeParent.updateStatus.calledOnce).to.be.true;
164162
expect(fakeParent.updateStatus.firstCall.args[0]).to.equal('Fetching...');
165163
});
166164

@@ -171,7 +169,7 @@ describe('AssetManagementExportAdapter (base)', () => {
171169
});
172170

173171
describe('completeProcess', () => {
174-
it('should call completeProcess on progressManager when no parent is set', () => {
172+
it('should call completeProcess on progressManager with the given name and success flag', () => {
175173
sinon.stub(configHandler, 'get').returns({});
176174
const fakeProgress = { tick: sinon.stub(), completeProcess: sinon.stub() } as any;
177175
sinon.stub(CLIProgressManager, 'createNested').returns(fakeProgress);
@@ -180,7 +178,7 @@ describe('AssetManagementExportAdapter (base)', () => {
180178
adapter.callCreateNestedProgress('test');
181179
adapter.callCompleteProcess('test', true);
182180

183-
expect(fakeProgress.completeProcess.calledWith('test', true)).to.be.true;
181+
expect(fakeProgress.completeProcess.firstCall.args).to.deep.equal(['test', true]);
184182
});
185183

186184
it('should NOT call completeProcess when parentProgressManager is set', () => {
@@ -190,7 +188,7 @@ describe('AssetManagementExportAdapter (base)', () => {
190188

191189
adapter.callCompleteProcess('test', true);
192190

193-
expect(fakeParent.completeProcess.called).to.be.false;
191+
expect(fakeParent.completeProcess.callCount).to.equal(0);
194192
});
195193
});
196194

@@ -208,16 +206,16 @@ describe('AssetManagementExportAdapter (base)', () => {
208206
fsReal.unlinkSync(path.join(tmpDir, 'test-empty.json'));
209207
});
210208

211-
it('should use FsUtility to write items in batches when items exist', async () => {
209+
it('should write all items in a single batch and complete the file when count is below BATCH_SIZE', async () => {
212210
const writeIntoFileStub = sinon.stub(FsUtility.prototype, 'writeIntoFile');
213211
const completeFileStub = sinon.stub(FsUtility.prototype, 'completeFile');
214212

215213
const items = Array.from({ length: 3 }, (_, i) => ({ uid: `item-${i}` }));
216214
const adapter = new TestAdapter(apiConfig, exportContext);
217215
await adapter.callWriteItemsToChunkedJson('/tmp/dir', 'items.json', 'items', ['uid'], items);
218216

219-
expect(writeIntoFileStub.called).to.be.true;
220-
expect(completeFileStub.calledWith(true)).to.be.true;
217+
expect(writeIntoFileStub.firstCall.args[0]).to.have.length(3);
218+
expect(completeFileStub.firstCall.args[0]).to.be.true;
221219
});
222220

223221
it('should write items in batches of BATCH_SIZE (50)', async () => {

packages/contentstack-asset-management/test/unit/export/fields.test.ts

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,7 @@ describe('ExportFields', () => {
4646
const exporter = new ExportFields(apiConfig, exportContext);
4747
await exporter.start(spaceUid);
4848

49-
expect(getFieldsStub.calledOnce).to.be.true;
50-
expect(getFieldsStub.calledWith(spaceUid)).to.be.true;
49+
expect(getFieldsStub.firstCall.args[0]).to.equal(spaceUid);
5150
});
5251

5352
it('should write fields with correct chunked JSON args', async () => {
@@ -56,7 +55,6 @@ describe('ExportFields', () => {
5655
await exporter.start(spaceUid);
5756

5857
const writeStub = (AssetManagementExportAdapter.prototype as any).writeItemsToChunkedJson as sinon.SinonStub;
59-
expect(writeStub.calledOnce).to.be.true;
6058
const args = writeStub.firstCall.args;
6159
expect(args[0]).to.equal(fieldsDir);
6260
expect(args[1]).to.equal('fields.json');
@@ -75,21 +73,16 @@ describe('ExportFields', () => {
7573
await exporter.start(spaceUid);
7674

7775
const writeStub = (AssetManagementExportAdapter.prototype as any).writeItemsToChunkedJson as sinon.SinonStub;
78-
expect(writeStub.calledOnce).to.be.true;
7976
expect(writeStub.firstCall.args[4]).to.deep.equal([]);
8077
});
8178

82-
it('should call tick on success', async () => {
79+
it('should tick with success=true, the fields process name, and null error', async () => {
8380
sinon.stub(ExportFields.prototype, 'getWorkspaceFields').resolves(fieldsResponse);
8481
const exporter = new ExportFields(apiConfig, exportContext);
8582
await exporter.start(spaceUid);
8683

8784
const tickStub = (AssetManagementExportAdapter.prototype as any).tick as sinon.SinonStub;
88-
expect(tickStub.called).to.be.true;
89-
const args = tickStub.firstCall.args;
90-
expect(args[0]).to.be.true;
91-
expect(args[1]).to.equal(PROCESS_NAMES.AM_FIELDS);
92-
expect(args[2]).to.be.null;
85+
expect(tickStub.firstCall.args).to.deep.equal([true, PROCESS_NAMES.AM_FIELDS, null]);
9386
});
9487
});
9588
});

0 commit comments

Comments
 (0)