Skip to content

Commit 1bc0dcf

Browse files
Merge branch 'v2-dev' into fix/dx-7341-fix-chalk-load-error
2 parents aa23403 + aec4848 commit 1bc0dcf

7 files changed

Lines changed: 119 additions & 60 deletions

File tree

.github/workflows/unit-test.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,6 @@ jobs:
3131
working-directory: ./packages/contentstack-auth
3232
run: pnpm test
3333
# Commented out in v2-beta production
34-
# - name: Test contentstack-utilities
35-
# working-directory: ./packages/contentstack-utilities
36-
# run: pnpm test
34+
- name: Test contentstack-utilities
35+
working-directory: ./packages/contentstack-utilities
36+
run: pnpm test

packages/contentstack-config/src/commands/config/set/region.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ export default class RegionSetCommand extends BaseCommand<typeof RegionSetComman
4646
studio: _flags.string({
4747
description: 'Custom host to set for Studio API',
4848
}),
49-
'asset-management': _flags.string({
50-
description: 'Custom host to set for Asset Management API',
49+
'cs-assets': _flags.string({
50+
description: 'Custom host to set for Contentstack Assets API',
5151
}),
5252
};
5353
static examples = [
@@ -64,7 +64,7 @@ export default class RegionSetCommand extends BaseCommand<typeof RegionSetComman
6464
'$ csdx config:set:region --cma <custom_cma_host_url> --cda <custom_cda_host_url> --ui-host <custom_ui_host_url> --name "India" --personalize <custom_personalize_url>',
6565
'$ csdx config:set:region --cma <custom_cma_host_url> --cda <custom_cda_host_url> --ui-host <custom_ui_host_url> --name "India" --launch <custom_launch_url>',
6666
'$ csdx config:set:region --cma <custom_cma_host_url> --cda <custom_cda_host_url> --ui-host <custom_ui_host_url> --name "India" --studio <custom_studio_url>',
67-
'$ csdx config:set:region --cma <custom_cma_host_url> --cda <custom_cda_host_url> --ui-host <custom_ui_host_url> --name "India" --asset-management <asset_management_url>',
67+
'$ csdx config:set:region --cma <custom_cma_host_url> --cda <custom_cda_host_url> --ui-host <custom_ui_host_url> --name "India" --cs-assets <cs_assets_url>',
6868
'$ csdx config:set:region --cda <custom_cda_host_url> --cma <custom_cma_host_url> --ui-host <custom_ui_host_url> --name "India" --developer-hub <custom_developer_hub_url> --launch <custom_launch_url> --personalize <custom_personalize_url> --studio <custom_studio_url>',
6969
];
7070

@@ -82,7 +82,7 @@ export default class RegionSetCommand extends BaseCommand<typeof RegionSetComman
8282
let personalizeUrl = regionSetFlags['personalize'];
8383
let launchHubUrl = regionSetFlags['launch'];
8484
let composableStudioUrl = regionSetFlags['studio'];
85-
let assetManagementUrl = regionSetFlags['asset-management'];
85+
let csAssetsUrl = regionSetFlags['cs-assets'];
8686
let selectedRegion = args.region;
8787
if (!(cda && cma && uiHost && name) && !selectedRegion) {
8888
selectedRegion = await interactive.askRegions();
@@ -113,8 +113,8 @@ export default class RegionSetCommand extends BaseCommand<typeof RegionSetComman
113113
if (!composableStudioUrl) {
114114
composableStudioUrl = this.transformUrl(cma, 'composable-studio-api');
115115
}
116-
if (!assetManagementUrl) {
117-
assetManagementUrl = this.transformUrl(cma, 'am-api');
116+
if (!csAssetsUrl) {
117+
csAssetsUrl = this.transformUrl(cma, 'am-api');
118118
}
119119
let customRegion: Region = {
120120
cda,
@@ -125,7 +125,7 @@ export default class RegionSetCommand extends BaseCommand<typeof RegionSetComman
125125
personalizeUrl,
126126
launchHubUrl,
127127
composableStudioUrl,
128-
assetManagementUrl,
128+
csAssetsUrl,
129129
};
130130
customRegion = regionHandler.setCustomRegion(customRegion);
131131
await authHandler.setConfigData('logout'); //Todo: Handle this logout flow well through logout command call
@@ -137,7 +137,7 @@ export default class RegionSetCommand extends BaseCommand<typeof RegionSetComman
137137
cliux.success(`Personalize URL: ${customRegion.personalizeUrl}`);
138138
cliux.success(`Launch URL: ${customRegion.launchHubUrl}`);
139139
cliux.success(`Studio URL: ${customRegion.composableStudioUrl}`);
140-
cliux.success(`Asset Management URL: ${customRegion.assetManagementUrl}`);
140+
cliux.success(`Contentstack Assets URL: ${customRegion.csAssetsUrl}`);
141141
} catch (error) {
142142
handleAndLogError(error, { ...this.contextDetails, module: 'config-set-region' });
143143
}
@@ -156,7 +156,7 @@ export default class RegionSetCommand extends BaseCommand<typeof RegionSetComman
156156
cliux.success(`Personalize URL: ${regionDetails.personalizeUrl}`);
157157
cliux.success(`Launch URL: ${regionDetails.launchHubUrl}`);
158158
cliux.success(`Studio URL: ${regionDetails.composableStudioUrl}`);
159-
cliux.success(`Asset Management URL: ${regionDetails.assetManagementUrl}`);
159+
cliux.success(`Contentstack Assets URL: ${regionDetails.csAssetsUrl}`);
160160
} else {
161161
cliux.error(`Invalid region specified.`);
162162
}

packages/contentstack-config/src/interfaces/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export interface Region {
1919
personalizeUrl: string;
2020
launchHubUrl: string;
2121
composableStudioUrl: string;
22-
assetManagementUrl?: string;
22+
csAssetsUrl?: string;
2323
}
2424

2525
export interface Limit {

packages/contentstack-config/src/utils/region-handler.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ function getRegionObject(regionKey: string): Region {
4040
launchHubUrl: endpoints.launch,
4141
personalizeUrl: endpoints.personalizeManagement,
4242
composableStudioUrl: endpoints.composableStudio,
43-
assetManagementUrl: endpoints.assetManagement,
43+
csAssetsUrl: endpoints.assetManagement,
4444
};
4545
} catch {
4646
return null;
@@ -156,7 +156,7 @@ class UserConfig {
156156
personalizeUrl: regionObject['personalizeUrl'],
157157
launchHubUrl: regionObject['launchHubUrl'],
158158
composableStudioUrl: regionObject['composableStudioUrl'],
159-
assetManagementUrl: regionObject['assetManagementUrl'],
159+
csAssetsUrl: regionObject['csAssetsUrl'],
160160
};
161161

162162
return sanitizedRegion;

packages/contentstack-config/test/unit/commands/region.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ describe('Region command', function () {
1717
launchHubUrl: 'https://launch-api.contentstack.com',
1818
personalizeUrl: 'https://personalization-api.contentstack.com',
1919
composableStudioUrl: 'https://composable-studio-api.contentstack.com',
20-
assetManagementUrl: 'https://am-api.contentstack.com',
20+
csAssetsUrl: 'https://am-api.contentstack.com',
2121
};
2222
let cliuxPrintStub: sinon.SinonStub;
2323
let configGetStub: sinon.SinonStub;
@@ -310,7 +310,7 @@ describe('Region command', function () {
310310
personalizeUrl: 'https://custom-personalize.com',
311311
launchHubUrl: 'https://custom-launch.com',
312312
composableStudioUrl: 'https://custom-composable-studio.com',
313-
assetManagementUrl: 'https://custom-asset-management.com',
313+
csAssetsUrl: 'https://custom-asset-management.com',
314314
};
315315
const result = UserConfig.setCustomRegion(customRegion);
316316
expect(result).to.deep.equal(customRegion);

packages/contentstack-utilities/test/unit/auth-handler.test.ts

Lines changed: 47 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//@ts-nocheck
22
import { expect } from 'chai';
33
import { assert, stub, createSandbox } from 'sinon';
4-
import { cliux } from '@contentstack/cli-utilities';
4+
import cliux from '../../src/cli-ux';
55
import authHandler from '../../src/auth-handler';
66
import configHandler from '../../src/config-handler';
77
import { HttpClient } from '../../src/http-client';
@@ -32,15 +32,18 @@ describe('Auth Handler', () => {
3232
describe('oauth', () => {
3333
let createHTTPServerStub;
3434
let openOAuthURLStub;
35+
let initSDKStub;
3536

3637
beforeEach(() => {
38+
initSDKStub = stub(authHandler, 'initSDK').resolves();
3739
createHTTPServerStub = stub(authHandler, 'createHTTPServer');
3840
openOAuthURLStub = stub(authHandler, 'openOAuthURL');
3941
});
4042

4143
afterEach(() => {
4244
createHTTPServerStub.restore();
4345
openOAuthURLStub.restore();
46+
initSDKStub.restore();
4447
});
4548

4649
it('should reject with an error when createHTTPServer fails', async () => {
@@ -167,16 +170,21 @@ describe('Auth Handler', () => {
167170
};
168171

169172
const exchangeStub = sandbox.stub().resolves(userData);
170-
sandbox.stub(authHandler, 'oauthHandler').value({
173+
const prevOAuthHandler = authHandler.oauthHandler;
174+
authHandler.oauthHandler = {
171175
exchangeCodeForToken: exchangeStub,
172-
});
176+
};
173177
const getUserDetailsStub = sandbox.stub(authHandler, 'getUserDetails').resolves(userData);
174178
const setConfigDataStub = sandbox.stub(authHandler, 'setConfigData').resolves();
175-
await authHandler.getAccessToken(code);
176-
// Verify the actual calls made:
177-
assert.calledWith(exchangeStub, code); // exchangeCodeForToken called with code
178-
assert.calledWith(getUserDetailsStub, userData); // getUserDetails called with result from exchange
179-
assert.calledWith(setConfigDataStub, 'oauth', userData); // setConfigData called with 'oauth' and userData
179+
try {
180+
await authHandler.getAccessToken(code);
181+
// Verify the actual calls made:
182+
assert.calledWith(exchangeStub, code); // exchangeCodeForToken called with code
183+
assert.calledWith(getUserDetailsStub, userData); // getUserDetails called with result from exchange
184+
assert.calledWith(setConfigDataStub, 'oauth', userData); // setConfigData called with 'oauth' and userData
185+
} finally {
186+
authHandler.oauthHandler = prevOAuthHandler;
187+
}
180188
});
181189
});
182190

@@ -296,51 +304,59 @@ describe('Auth Handler', () => {
296304
};
297305
// Stub oauthHandler with refreshAccessToken method
298306
const refreshAccessTokenStub = sandbox.stub().resolves(expectedData);
299-
sandbox.stub(authHandler, 'oauthHandler').value({
307+
const prevOAuthHandler = authHandler.oauthHandler;
308+
authHandler.oauthHandler = {
300309
refreshAccessToken: refreshAccessTokenStub,
301-
});
302-
// Stub configHandler.get to return proper values
303-
sandbox
304-
.stub(configHandler, 'get')
305-
.withArgs(authHandler.oauthRefreshTokenKeyName)
306-
.returns(configOauthRefreshToken)
307-
.withArgs(authHandler.authorisationTypeKeyName)
308-
.returns(configAuthorisationType);
309-
// Stub setConfigData
310-
sandbox.stub(authHandler, 'setConfigData').resolves(expectedData);
311-
const result = await authHandler.refreshToken();
312-
// Verify calls
313-
assert.calledWith(refreshAccessTokenStub, configOauthRefreshToken);
314-
assert.calledWith(authHandler.setConfigData, 'refreshToken', expectedData);
315-
expect(result).to.deep.equal(expectedData);
310+
};
311+
try {
312+
// Stub configHandler.get to return proper values
313+
sandbox
314+
.stub(configHandler, 'get')
315+
.withArgs(authHandler.oauthRefreshTokenKeyName)
316+
.returns(configOauthRefreshToken)
317+
.withArgs(authHandler.authorisationTypeKeyName)
318+
.returns(configAuthorisationType);
319+
// Stub setConfigData
320+
sandbox.stub(authHandler, 'setConfigData').resolves(expectedData);
321+
const result = await authHandler.refreshToken();
322+
// Verify calls
323+
assert.calledWith(refreshAccessTokenStub, configOauthRefreshToken);
324+
assert.calledWith(authHandler.setConfigData, 'refreshToken', expectedData);
325+
expect(result).to.deep.equal(expectedData);
326+
} finally {
327+
authHandler.oauthHandler = prevOAuthHandler;
328+
}
316329
});
317330
});
318331

319332
describe('getUserDetails', () => {
320333
let sandbox;
321-
let managementAPIClientStub;
322334

323335
beforeEach(() => {
324336
sandbox = createSandbox();
325-
managementAPIClientStub = sandbox.stub();
326337
});
327338

328339
afterEach(() => {
329340
sandbox.restore();
341+
authHandler.managementAPIClient = undefined;
330342
});
331343

332-
it('should reject with error when access token is invalid/empty', async () => {
344+
it('should reject when Management SDK getUser fails', async () => {
333345
const data = {
334346
access_token: config.invalid_access_token,
335347
};
336348
const expectedError = new Error('The provided access token is invalid or expired or revoked');
337349

338350
const getUserStub = sandbox.stub().rejects(expectedError);
339-
managementAPIClientStub.returns({ getUser: getUserStub });
351+
authHandler.managementAPIClient = { getUser: getUserStub };
340352

341-
authHandler.contentstackManagementSDKClient = managementAPIClientStub;
342-
343-
authHandler.getUserDetails(data);
353+
try {
354+
await authHandler.getUserDetails(data);
355+
expect.fail('Expected getUserDetails to reject');
356+
} catch (error) {
357+
expect(error).to.equal(expectedError);
358+
}
359+
assert.calledOnce(getUserStub);
344360
});
345361

346362
it('should reject with error when access token is invalid/empty', async () => {

packages/contentstack-utilities/test/unit/cliProgressManager.test.ts

Lines changed: 55 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -223,12 +223,28 @@ describe('CLIProgressManager', () => {
223223

224224
fancy.it('should create simple progress manager', () => {
225225
const simple = CLIProgressManager.createSimple('testModule', 50, true);
226-
expect(simple).to.be.instanceOf(CLIProgressManager);
226+
try {
227+
expect(simple).to.be.instanceOf(CLIProgressManager);
228+
} finally {
229+
try {
230+
simple.stop();
231+
} catch (e) {
232+
// ignore
233+
}
234+
}
227235
});
228236

229237
fancy.it('should create nested progress manager', () => {
230238
const nested = CLIProgressManager.createNested('testModule', false);
231-
expect(nested).to.be.instanceOf(CLIProgressManager);
239+
try {
240+
expect(nested).to.be.instanceOf(CLIProgressManager);
241+
} finally {
242+
try {
243+
nested.stop();
244+
} catch (e) {
245+
// ignore
246+
}
247+
}
232248
});
233249

234250
fancy.it('should validate static factory methods exist', () => {
@@ -253,15 +269,16 @@ describe('CLIProgressManager', () => {
253269
}
254270
});
255271

256-
fancy.it('should skip global summary when showConsoleLogs is true (pure console log mode)', () => {
272+
// printGlobalSummary always calls printFinalSummary; log.showConsoleLogs only gates the header in initializeGlobalSummary.
273+
fancy.it('should print global summary when showConsoleLogs is true (same as printGlobalSummary behavior)', () => {
257274
const summaryStub = sinon.stub(SummaryManager.prototype, 'printFinalSummary');
258275
const configGetStub = sinon.stub(configHandler, 'get').callThrough();
259276
configGetStub.withArgs('log').returns({ showConsoleLogs: true });
260277

261278
try {
262279
CLIProgressManager.initializeGlobalSummary('SKIP_SUMMARY_TEST', '');
263280
CLIProgressManager.printGlobalSummary();
264-
expect(summaryStub.called).to.be.false;
281+
expect(summaryStub.calledOnce).to.be.true;
265282
} finally {
266283
configGetStub.restore();
267284
summaryStub.restore();
@@ -305,8 +322,16 @@ describe('CLIProgressManager', () => {
305322

306323
fancy.it('should handle non-nested mode gracefully', () => {
307324
const simpleManager = new CLIProgressManager({ enableNestedProgress: false });
308-
const result = simpleManager.addProcess('process1', 50);
309-
expect(result).to.equal(simpleManager);
325+
try {
326+
const result = simpleManager.addProcess('process1', 50);
327+
expect(result).to.equal(simpleManager);
328+
} finally {
329+
try {
330+
simpleManager.stop();
331+
} catch (e) {
332+
// ignore
333+
}
334+
}
310335
});
311336
});
312337

@@ -334,10 +359,18 @@ describe('CLIProgressManager', () => {
334359
enableNestedProgress: true,
335360
moduleName: 'TEST',
336361
});
337-
nestedManager.addProcess('process1', 10);
338-
nestedManager.startProcess('process1');
339-
const result = nestedManager.tick(true, 'item1', null, 'process1');
340-
expect(result).to.equal(nestedManager);
362+
try {
363+
nestedManager.addProcess('process1', 10);
364+
nestedManager.startProcess('process1');
365+
const result = nestedManager.tick(true, 'item1', null, 'process1');
366+
expect(result).to.equal(nestedManager);
367+
} finally {
368+
try {
369+
nestedManager.stop();
370+
} catch (e) {
371+
// ignore
372+
}
373+
}
341374
});
342375

343376
fancy.it('should update status message', () => {
@@ -432,8 +465,18 @@ describe('CLIProgressManager', () => {
432465
showConsoleLogs: false,
433466
moduleName: 'TEST',
434467
});
435-
silentManager.log('Test message');
436-
expect(consoleLogStub.called).to.be.false;
468+
try {
469+
// Ignore prior tests in this describe; only assert console.log for this log() call.
470+
consoleLogStub.resetHistory();
471+
silentManager.log('Test message');
472+
expect(consoleLogStub.callCount).to.equal(0);
473+
} finally {
474+
try {
475+
silentManager.stop();
476+
} catch (e) {
477+
// ignore
478+
}
479+
}
437480
});
438481

439482
fancy.it('should not print Progress Manager summary when showConsoleLogs is true (pure console log mode)', () => {

0 commit comments

Comments
 (0)