Skip to content

Commit b09ec68

Browse files
committed
fix & updated test cases
1 parent 96a5282 commit b09ec68

4 files changed

Lines changed: 112 additions & 28 deletions

File tree

packages/contentstack-utilities/src/logger/cliErrorHandler.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ import { ERROR_TYPES } from '../constants/errorTypes';
1818
*
1919
* @remarks
2020
* This class is designed to handle a wide range of error types, including generic
21-
* JavaScript errors, API errors, and custom error objects.
21+
* JavaScript errors, API errors, and custom error objects. It also supports
22+
* optional debugging and context metadata for enhanced error reporting.
2223
*
2324
* @example
2425
* ```typescript

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

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ describe('Auth Handler', () => {
7979

8080
expect(createHTTPServerStub.calledOnce).to.be.true;
8181
expect(openOAuthURLStub.calledOnce).to.be.true;
82-
expect(result).to.deep.equal({});
82+
expect(result).to.be.undefined;
8383
});
8484
});
8585

@@ -127,7 +127,6 @@ describe('Auth Handler', () => {
127127

128128
sandbox.stub(authHandler, 'setOAuthBaseURL').resolves();
129129
sandbox.stub(crypto, 'createHash').returns({ update: () => {}, digest: () => {} });
130-
sandbox.stub(authHandler, 'codeVerifier').value('CODE_VERIFIER');
131130
sandbox.stub(authHandler, 'OAuthBaseURL').value('https://example.com');
132131
sandbox.stub(authHandler, 'OAuthAppId').value('APP_ID');
133132
sandbox.stub(authHandler, 'OAuthResponseType').value('response_type');
@@ -355,13 +354,15 @@ describe('Auth Handler', () => {
355354
const data = {
356355
access_token: '',
357356
};
358-
359-
const userDetailsPromise = authHandler.getUserDetails(data);
360-
361-
return userDetailsPromise.catch((error) => {
362-
expect(error).to.equal('Invalid/Empty access token');
363-
});
364-
});
357+
358+
try {
359+
await authHandler.getUserDetails(data);
360+
throw new Error('Expected getUserDetails to throw'); // ensure failure if no error is thrown
361+
} catch (error) {
362+
expect(error).to.be.instanceOf(Error);
363+
expect(error.message).to.equal('Invalid/Empty access token');
364+
}
365+
});
365366
});
366367

367368
describe('isAuthenticated', () => {

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

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -71,18 +71,6 @@ describe('CLIErrorHandler', () => {
7171
expect(classified.hidden).to.be.false;
7272
});
7373

74-
fancy.it('normalizeToError should handle object that throws', () => {
75-
const badInput = {
76-
get message() {
77-
throw new Error('fail to access message');
78-
},
79-
};
80-
81-
const result = errorHandler['normalizeToError'](badInput);
82-
expect(result).to.be.instanceOf(Error);
83-
expect(result.message).to.include('fail');
84-
});
85-
8674
fancy.it('containsSensitiveInfo should return false for clean error', () => {
8775
const error = new Error('All good');
8876
const result = errorHandler['containsSensitiveInfo'](error);

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

Lines changed: 100 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ describe('Logger', () => {
1919
expect(winLogger.level).to.equal('error');
2020
});
2121

22+
fancy.it('should create hidden logger as error level', () => {
23+
const hiddenLogger = logger.getLoggerInstance('hidden');
24+
expect(hiddenLogger.level).to.equal('error');
25+
});
26+
2227
fancy.it('should redact sensitive keys', () => {
2328
const testMeta = {
2429
password: 'secret123',
@@ -34,6 +39,14 @@ describe('Logger', () => {
3439
expect(redacted.other).to.equal('safe');
3540
});
3641

42+
fancy.it('should detect valid LogEntry object', () => {
43+
const validEntry = { level: 'info', message: 'Test message' };
44+
expect(logger['isLogEntry'](validEntry)).to.equal(true);
45+
46+
const invalidEntry = { msg: 'nope' };
47+
expect(logger['isLogEntry'](invalidEntry)).to.equal(false);
48+
});
49+
3750
fancy.it('should log error messages using error method', () => {
3851
const errorLogger = logger['loggers'].error;
3952
const spy = sinon.spy();
@@ -76,13 +89,17 @@ describe('Logger', () => {
7689
expect(spy.args[0][1].type).to.equal('success');
7790
});
7891

79-
fancy
80-
.it('logError with hidden true logs to debug logger', () => {
81-
const debugLogger = logger['loggers'].debug;
92+
fancy.it('logError with hidden true logs to debug logger', () => {
93+
const debugLogger = new Logger({
94+
basePath: './logs',
95+
consoleLogLevel: 'debug',
96+
logLevel: 'debug',
97+
});
98+
8299
const spy = sinon.spy();
83-
debugLogger.error = spy;
100+
debugLogger['loggers'].debug.error = spy;
84101

85-
logger.logError({
102+
debugLogger.logError({
86103
type: 'hiddenType',
87104
message: 'Something secret',
88105
error: new Error('oops'),
@@ -94,7 +111,6 @@ describe('Logger', () => {
94111
expect(logPayload.meta.type).to.equal('hiddenType');
95112
});
96113

97-
98114
fancy.it('redact handles splat symbol', () => {
99115
const obj = {
100116
token: 'abc',
@@ -104,4 +120,82 @@ describe('Logger', () => {
104120
expect(result.token).to.equal('[REDACTED]');
105121
expect(result[Symbol.for('splat')][0].password).to.equal('[REDACTED]');
106122
});
123+
124+
fancy.it('redact should return original if klona fails', () => {
125+
const faultyLogger = new Logger({
126+
basePath: './logs',
127+
consoleLogLevel: 'info',
128+
logLevel: 'info',
129+
});
130+
131+
const obj = {
132+
toJSON: () => {
133+
throw new Error('klona fails');
134+
}
135+
};
136+
137+
const result = faultyLogger['redact'](obj);
138+
expect(result).to.deep.equal(obj);
139+
});
140+
141+
fancy.it('should call logWarn with correct meta', () => {
142+
const warnSpy = sinon.spy();
143+
logger['loggers'].warn.warn = warnSpy;
144+
145+
logger.logWarn({
146+
type: 'testType',
147+
message: 'Warn occurred',
148+
context: 'warnContext',
149+
meta: { custom: 'value' }
150+
});
151+
152+
expect(warnSpy.calledOnce).to.be.true;
153+
expect(warnSpy.args[0][0].meta.type).to.equal('testType');
154+
expect(warnSpy.args[0][0].meta.custom).to.equal('value');
155+
});
156+
157+
fancy.it('should call logInfo with correct meta', () => {
158+
const infoSpy = sinon.spy();
159+
logger['loggers'].info.info = infoSpy;
160+
161+
logger.logInfo({
162+
type: 'infoType',
163+
message: 'This is info',
164+
meta: { foo: 'bar' },
165+
});
166+
167+
expect(infoSpy.calledOnce).to.be.true;
168+
expect(infoSpy.args[0][0].meta.foo).to.equal('bar');
169+
});
170+
171+
fancy.it('should call logDebug with correct meta', () => {
172+
const debugLogger = new Logger({
173+
basePath: './logs',
174+
consoleLogLevel: 'debug',
175+
logLevel: 'debug',
176+
});
177+
178+
const debugSpy = sinon.spy();
179+
debugLogger['loggers'].debug.debug = debugSpy;
180+
181+
debugLogger.logDebug({
182+
type: 'debugType',
183+
message: 'Debug data',
184+
meta: { extra: 'info' },
185+
});
186+
187+
expect(debugSpy.calledOnce).to.be.true;
188+
expect(debugSpy.args[0][0].meta.extra).to.equal('info');
189+
});
190+
191+
fancy.it('shouldLog should default to info when config not defined', () => {
192+
const defaultLogger = new Logger({
193+
basePath: './logs',
194+
consoleLogLevel: undefined as any,
195+
logLevel: undefined as any,
196+
});
197+
198+
expect(defaultLogger['shouldLog']('info', 'console')).to.equal(true);
199+
expect(defaultLogger['shouldLog']('debug', 'console')).to.equal(false);
200+
});
107201
});

0 commit comments

Comments
 (0)