Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/unit-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ jobs:
working-directory: ./packages/contentstack-auth
run: pnpm test
# Commented out in v2-beta production
# - name: Test contentstack-utilities
# working-directory: ./packages/contentstack-utilities
# run: pnpm test
- name: Test contentstack-utilities
working-directory: ./packages/contentstack-utilities
run: pnpm test
78 changes: 47 additions & 31 deletions packages/contentstack-utilities/test/unit/auth-handler.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//@ts-nocheck
import { expect } from 'chai';
import { assert, stub, createSandbox } from 'sinon';
import { cliux } from '@contentstack/cli-utilities';
import cliux from '../../src/cli-ux';
import authHandler from '../../src/auth-handler';
import configHandler from '../../src/config-handler';
import { HttpClient } from '../../src/http-client';
Expand Down Expand Up @@ -32,15 +32,18 @@ describe('Auth Handler', () => {
describe('oauth', () => {
let createHTTPServerStub;
let openOAuthURLStub;
let initSDKStub;

beforeEach(() => {
initSDKStub = stub(authHandler, 'initSDK').resolves();
createHTTPServerStub = stub(authHandler, 'createHTTPServer');
openOAuthURLStub = stub(authHandler, 'openOAuthURL');
});

afterEach(() => {
createHTTPServerStub.restore();
openOAuthURLStub.restore();
initSDKStub.restore();
});

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

const exchangeStub = sandbox.stub().resolves(userData);
sandbox.stub(authHandler, 'oauthHandler').value({
const prevOAuthHandler = authHandler.oauthHandler;
authHandler.oauthHandler = {
exchangeCodeForToken: exchangeStub,
});
};
const getUserDetailsStub = sandbox.stub(authHandler, 'getUserDetails').resolves(userData);
const setConfigDataStub = sandbox.stub(authHandler, 'setConfigData').resolves();
await authHandler.getAccessToken(code);
// Verify the actual calls made:
assert.calledWith(exchangeStub, code); // exchangeCodeForToken called with code
assert.calledWith(getUserDetailsStub, userData); // getUserDetails called with result from exchange
assert.calledWith(setConfigDataStub, 'oauth', userData); // setConfigData called with 'oauth' and userData
try {
await authHandler.getAccessToken(code);
// Verify the actual calls made:
assert.calledWith(exchangeStub, code); // exchangeCodeForToken called with code
assert.calledWith(getUserDetailsStub, userData); // getUserDetails called with result from exchange
assert.calledWith(setConfigDataStub, 'oauth', userData); // setConfigData called with 'oauth' and userData
} finally {
authHandler.oauthHandler = prevOAuthHandler;
}
});
});

Expand Down Expand Up @@ -296,51 +304,59 @@ describe('Auth Handler', () => {
};
// Stub oauthHandler with refreshAccessToken method
const refreshAccessTokenStub = sandbox.stub().resolves(expectedData);
sandbox.stub(authHandler, 'oauthHandler').value({
const prevOAuthHandler = authHandler.oauthHandler;
authHandler.oauthHandler = {
refreshAccessToken: refreshAccessTokenStub,
});
// Stub configHandler.get to return proper values
sandbox
.stub(configHandler, 'get')
.withArgs(authHandler.oauthRefreshTokenKeyName)
.returns(configOauthRefreshToken)
.withArgs(authHandler.authorisationTypeKeyName)
.returns(configAuthorisationType);
// Stub setConfigData
sandbox.stub(authHandler, 'setConfigData').resolves(expectedData);
const result = await authHandler.refreshToken();
// Verify calls
assert.calledWith(refreshAccessTokenStub, configOauthRefreshToken);
assert.calledWith(authHandler.setConfigData, 'refreshToken', expectedData);
expect(result).to.deep.equal(expectedData);
};
try {
// Stub configHandler.get to return proper values
sandbox
.stub(configHandler, 'get')
.withArgs(authHandler.oauthRefreshTokenKeyName)
.returns(configOauthRefreshToken)
.withArgs(authHandler.authorisationTypeKeyName)
.returns(configAuthorisationType);
// Stub setConfigData
sandbox.stub(authHandler, 'setConfigData').resolves(expectedData);
const result = await authHandler.refreshToken();
// Verify calls
assert.calledWith(refreshAccessTokenStub, configOauthRefreshToken);
assert.calledWith(authHandler.setConfigData, 'refreshToken', expectedData);
expect(result).to.deep.equal(expectedData);
} finally {
authHandler.oauthHandler = prevOAuthHandler;
}
});
});

describe('getUserDetails', () => {
let sandbox;
let managementAPIClientStub;

beforeEach(() => {
sandbox = createSandbox();
managementAPIClientStub = sandbox.stub();
});

afterEach(() => {
sandbox.restore();
authHandler.managementAPIClient = undefined;
});

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

const getUserStub = sandbox.stub().rejects(expectedError);
managementAPIClientStub.returns({ getUser: getUserStub });
authHandler.managementAPIClient = { getUser: getUserStub };

authHandler.contentstackManagementSDKClient = managementAPIClientStub;

authHandler.getUserDetails(data);
try {
await authHandler.getUserDetails(data);
expect.fail('Expected getUserDetails to reject');
} catch (error) {
expect(error).to.equal(expectedError);
}
assert.calledOnce(getUserStub);
});

it('should reject with error when access token is invalid/empty', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,12 +223,28 @@ describe('CLIProgressManager', () => {

fancy.it('should create simple progress manager', () => {
const simple = CLIProgressManager.createSimple('testModule', 50, true);
expect(simple).to.be.instanceOf(CLIProgressManager);
try {
expect(simple).to.be.instanceOf(CLIProgressManager);
} finally {
try {
simple.stop();
} catch (e) {
// ignore
}
}
});

fancy.it('should create nested progress manager', () => {
const nested = CLIProgressManager.createNested('testModule', false);
expect(nested).to.be.instanceOf(CLIProgressManager);
try {
expect(nested).to.be.instanceOf(CLIProgressManager);
} finally {
try {
nested.stop();
} catch (e) {
// ignore
}
}
});

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

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

try {
CLIProgressManager.initializeGlobalSummary('SKIP_SUMMARY_TEST', '');
CLIProgressManager.printGlobalSummary();
expect(summaryStub.called).to.be.false;
expect(summaryStub.calledOnce).to.be.true;
} finally {
configGetStub.restore();
summaryStub.restore();
Expand Down Expand Up @@ -305,8 +322,16 @@ describe('CLIProgressManager', () => {

fancy.it('should handle non-nested mode gracefully', () => {
const simpleManager = new CLIProgressManager({ enableNestedProgress: false });
const result = simpleManager.addProcess('process1', 50);
expect(result).to.equal(simpleManager);
try {
const result = simpleManager.addProcess('process1', 50);
expect(result).to.equal(simpleManager);
} finally {
try {
simpleManager.stop();
} catch (e) {
// ignore
}
}
});
});

Expand Down Expand Up @@ -334,10 +359,18 @@ describe('CLIProgressManager', () => {
enableNestedProgress: true,
moduleName: 'TEST',
});
nestedManager.addProcess('process1', 10);
nestedManager.startProcess('process1');
const result = nestedManager.tick(true, 'item1', null, 'process1');
expect(result).to.equal(nestedManager);
try {
nestedManager.addProcess('process1', 10);
nestedManager.startProcess('process1');
const result = nestedManager.tick(true, 'item1', null, 'process1');
expect(result).to.equal(nestedManager);
} finally {
try {
nestedManager.stop();
} catch (e) {
// ignore
}
}
});

fancy.it('should update status message', () => {
Expand Down Expand Up @@ -432,8 +465,18 @@ describe('CLIProgressManager', () => {
showConsoleLogs: false,
moduleName: 'TEST',
});
silentManager.log('Test message');
expect(consoleLogStub.called).to.be.false;
try {
// Ignore prior tests in this describe; only assert console.log for this log() call.
consoleLogStub.resetHistory();
silentManager.log('Test message');
expect(consoleLogStub.callCount).to.equal(0);
} finally {
try {
silentManager.stop();
} catch (e) {
// ignore
}
}
});

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