|
14 | 14 |
|
15 | 15 | import {strict as assert} from 'assert';
|
16 | 16 |
|
17 |
| -import {Gaxios, GaxiosOptionsPrepared} from 'gaxios'; |
| 17 | +import {Gaxios, GaxiosError, GaxiosOptionsPrepared, GaxiosResponse} from 'gaxios'; |
18 | 18 |
|
19 | 19 | import {AuthClient, PassThroughClient} from '../src';
|
20 | 20 | import {snakeToCamel} from '../src/util';
|
21 | 21 | import {PRODUCT_NAME, USER_AGENT} from '../src/shared.cjs';
|
| 22 | +import * as logging from 'google-logging-utils'; |
| 23 | + |
| 24 | +// Fakes for the logger, to capture logs that would've happened. |
| 25 | +interface TestLog { |
| 26 | + namespace: string; |
| 27 | + fields: logging.LogFields; |
| 28 | + args: unknown[]; |
| 29 | +} |
| 30 | + |
| 31 | +class TestLogSink extends logging.DebugLogBackendBase { |
| 32 | + logs: TestLog[] = []; |
| 33 | + |
| 34 | + makeLogger(namespace: string): logging.AdhocDebugLogCallable { |
| 35 | + return (fields: logging.LogFields, ...args: unknown[]) => { |
| 36 | + this.logs.push({namespace, fields, args}); |
| 37 | + }; |
| 38 | + } |
| 39 | + |
| 40 | + setFilters(): void {} |
| 41 | + |
| 42 | + reset() { |
| 43 | + this.filters = []; |
| 44 | + this.logs = []; |
| 45 | + } |
| 46 | +} |
22 | 47 |
|
23 | 48 | describe('AuthClient', () => {
|
24 | 49 | it('should accept and normalize snake case options to camel case', () => {
|
@@ -162,5 +187,99 @@ describe('AuthClient', () => {
|
162 | 187 | assert.equal(options.headers.get('x-goog-api-client'), expected);
|
163 | 188 | });
|
164 | 189 | });
|
| 190 | + |
| 191 | + describe('logging', () => { |
| 192 | + // Enable and capture any log lines that happen during these tests. |
| 193 | + let testLogSink: TestLogSink; |
| 194 | + let replacementLogger: logging.AdhocDebugLogFunction; |
| 195 | + beforeEach(() => { |
| 196 | + process.env[logging.env.nodeEnables] = 'auth'; |
| 197 | + testLogSink = new TestLogSink(); |
| 198 | + logging.setBackend(testLogSink); |
| 199 | + replacementLogger = logging.log('auth'); |
| 200 | + }); |
| 201 | + after(() => { |
| 202 | + delete process.env[logging.env.nodeEnables]; |
| 203 | + logging.setBackend(null); |
| 204 | + }) |
| 205 | + |
| 206 | + it('logs requests', async () => { |
| 207 | + const options: GaxiosOptionsPrepared = { |
| 208 | + headers: new Headers({ |
| 209 | + 'x-goog-api-client': 'something', |
| 210 | + }), |
| 211 | + url: new URL('https://google.com'), |
| 212 | + }; |
| 213 | + AuthClient.setMethodName(options, 'testMethod'); |
| 214 | + |
| 215 | + // This will become nicer with the 1.1.0 release of google-logging-utils. |
| 216 | + AuthClient.log = replacementLogger; |
| 217 | + const returned = await AuthClient.DEFAULT_REQUEST_INTERCEPTOR?.resolved?.(options); |
| 218 | + assert.strictEqual(returned, options); |
| 219 | + |
| 220 | + // Unfortunately, there is a fair amount of entropy and changeable formatting in the |
| 221 | + // actual logs, so this mostly validates that a few key pieces of info are in there. |
| 222 | + assert.deepStrictEqual(testLogSink.logs.length, 1); |
| 223 | + assert.deepStrictEqual(testLogSink.logs[0].namespace, 'auth'); |
| 224 | + assert.deepStrictEqual(testLogSink.logs[0].args.length, 4); |
| 225 | + assert.strictEqual((testLogSink.logs[0].args[0] as string).includes('request'), true); |
| 226 | + assert.deepStrictEqual(testLogSink.logs[0].args[1], 'testMethod'); |
| 227 | + assert.deepStrictEqual((testLogSink.logs[0].args[3] as GaxiosOptionsPrepared).headers.get('x-goog-api-client'), 'something'); |
| 228 | + assert.deepStrictEqual((testLogSink.logs[0].args[3] as GaxiosOptionsPrepared).url.href, 'https://google.com/'); |
| 229 | + }); |
| 230 | + |
| 231 | + it('logs responses', async () => { |
| 232 | + const response = { |
| 233 | + config: { |
| 234 | + headers: new Headers({ |
| 235 | + 'x-goog-api-client': 'something', |
| 236 | + }), |
| 237 | + url: new URL('https://google.com'), |
| 238 | + } as GaxiosOptionsPrepared, |
| 239 | + headers: new Headers({ |
| 240 | + 'x-goog-api-client': 'something', |
| 241 | + }), |
| 242 | + url: new URL('https://google.com'), |
| 243 | + data: { |
| 244 | + test:'test!' |
| 245 | + }, |
| 246 | + } as unknown as GaxiosResponse<{test: string}>; |
| 247 | + AuthClient.setMethodName(response.config, 'testMethod'); |
| 248 | + |
| 249 | + // This will become nicer with the 1.1.0 release of google-logging-utils. |
| 250 | + AuthClient.log = replacementLogger; |
| 251 | + const resolvedReturned = await AuthClient.DEFAULT_RESPONSE_INTERCEPTOR?.resolved?.(response); |
| 252 | + assert.strictEqual(resolvedReturned, response); |
| 253 | + |
| 254 | + // Unfortunately, there is a fair amount of entropy and changeable formatting in the |
| 255 | + // actual logs, so this mostly validates that a few key pieces of info are in there. |
| 256 | + assert.deepStrictEqual(testLogSink.logs.length, 1); |
| 257 | + assert.deepStrictEqual(testLogSink.logs[0].namespace, 'auth'); |
| 258 | + assert.deepStrictEqual(testLogSink.logs[0].args.length, 4); |
| 259 | + assert.strictEqual((testLogSink.logs[0].args[0] as string).includes('response'), true); |
| 260 | + assert.deepStrictEqual(testLogSink.logs[0].args[1], 'testMethod'); |
| 261 | + assert.deepStrictEqual((testLogSink.logs[0].args[3] as {test: string}), {test: 'test!'}); |
| 262 | + |
| 263 | + const error = { |
| 264 | + config: response.config, |
| 265 | + response: { |
| 266 | + data: { |
| 267 | + message: 'boo!', |
| 268 | + } |
| 269 | + } |
| 270 | + } as unknown as GaxiosError<{test: string}>; |
| 271 | + testLogSink.reset(); |
| 272 | + AuthClient.DEFAULT_RESPONSE_INTERCEPTOR?.rejected?.(error); |
| 273 | + |
| 274 | + // Unfortunately, there is a fair amount of entropy and changeable formatting in the |
| 275 | + // actual logs, so this mostly validates that a few key pieces of info are in there. |
| 276 | + assert.deepStrictEqual(testLogSink.logs.length, 1); |
| 277 | + assert.deepStrictEqual(testLogSink.logs[0].namespace, 'auth'); |
| 278 | + assert.deepStrictEqual(testLogSink.logs[0].args.length, 4); |
| 279 | + assert.strictEqual((testLogSink.logs[0].args[0] as string).includes('error'), true); |
| 280 | + assert.deepStrictEqual(testLogSink.logs[0].args[1], 'testMethod'); |
| 281 | + assert.deepStrictEqual((testLogSink.logs[0].args[3] as {test: string}), {message: 'boo!'}); |
| 282 | + }); |
| 283 | + }); |
165 | 284 | });
|
166 | 285 | });
|
0 commit comments