test('authenticate does not try to open browser in SSH session', async function (t) { const openStub = url => t.fail('should not try to open browser') const origEnv = process.env process.env = { ...origEnv, SSH_CLIENT: '127.0.0.1 1234 22' } // IP PID port t.on('end', () => { process.env = origEnv }) const authenticate = proxyquire('../lib/authenticate', { open: openStub }) const jwtToken = await authenticate(`http://127.0.0.1:${server.address().port}`, { ask: true }) t.ok(jwtToken) })
test('authenticate no auth token', async function (t) { const openStub = url => openSuccess() const authenticate = proxyquire('../lib/authenticate', { open: openStub }) // mocking the browser opening simulateNoToken = true t.on('end', () => { simulateNoToken = false }) try { await authenticate(`http://127.0.0.1:${server.address().port}`) t.fail('it should reject') } catch (err) { t.plan(2) t.ok(err) t.ok(err.message.includes('Authentication failed. No token obtained')) } })
test('Non-200 status codes return an error', (t) => { t.on('end', async () => { nock.cleanAll() }) const logger = new Logger(apiKey, createOptions()) nock(logger._url) .post('/', () => { return true }) .query(() => { return true }) .reply(204, 'STRANGE') const expectedErr = 'Unsuccessful request. Status text: null' logger.log('Hey! This will produce non-200 error', (err) => { t.equal(err, expectedErr, 'Error message is as expected') t.end() }) })
test('log.addMetaProperty adds it to each message', (t) => { const log = new Logger(apiKey, createOptions()) log.addMetaProperty('metaProp', 'metaVal') t.on('end', async () => { nock.cleanAll() }) nock(log._url) .post('/', (body) => { const payload = body.ls[0] t.deepEqual(payload.meta, { metaProp: 'metaVal' }, 'meta property injected into message payload') return true }) .query(() => { return true }) .reply(200, 'Ingester response') log.warn('Howdy, folks!', (err, body) => { t.error(err, 'No error returned') t.end() }) })
test('Can call .log with HTTP (not https)', (t) => { const log = new Logger(apiKey, createOptions({ protocol: 'http' })) t.equal(log._req.useHttps, false, 'HTTPS is off') t.on('end', async () => { nock.cleanAll() }) nock(log._url) .post('/', () => { return true }) .query(() => { return true }) .reply(200, 'Ingester response') log.warn('This is not secure', (err, res) => { t.equal(res.body.config.httpAgent.protocol, 'http:', 'http protocol is used') t.error(err, 'No error returned') t.end() }) })
test('.log() can be called by itself without a callback', (t) => { t.plan(4) const logger = new Logger(apiKey, createOptions()) t.on('end', async () => { nock.cleanAll() }) nock(logger._url) .post('/', (body) => { const payload = body.ls[0] t.equal(payload.line, 'Hi there', 'Log text was passed in body') t.equal(payload.level, 'INFO', 'Default level was used') return true }) .query((qs) => { t.pass('Intercepted query string') return true }) .reply(200, 'Ingester response') t.doesNotThrow(() => { logger.log('Hi there') }, 'Should not throw if .log() is called without a callback') })
test('.log() can be passed an object to log', (t) => { const log = new Logger(apiKey, createOptions()) t.on('end', async () => { nock.cleanAll() }) nock(log._url) .post('/', (body) => { const line = body.ls[0].line t.equal(line, '{\n "some": "test"\n}', 'Object was serialized pretty') return true }) .query(() => { return true }) .reply(200, 'Ingester response') log.info({some: 'test'}, (err, body) => { t.error(err, 'No error returned') t.deepEqual(body.lines, ['{\n "some": "test"\n}'], 'Line returned correctly') t.end() }) })
test('.log() truncates long opts strings', (t) => { const logger = new Logger(apiKey, createOptions()) t.on('end', async () => { nock.cleanAll() }) nock(logger._url) .post('/', () => { return true }) .query(() => { return true }) .reply(200, 'Ingester response') logger.log('log line', 'x'.repeat(configs.MAX_INPUT_LENGTH + 1), (err, res) => { // This test should actually throw due to an invalid level string. Fix later. t.error(err, 'No error') t.end() }) })
test('.log() can be called by itself with callback in place of opts', (t) => { const logger = new Logger(apiKey, createOptions()) t.on('end', async () => { nock.cleanAll() }) nock(logger._url) .post('/', (body) => { const payload = body.ls[0] t.equal(payload.line, 'Hi there', 'Log text was passed in body') t.equal(payload.level, 'INFO', 'Default level was used') return true }) .query(() => { return true }) .reply(200, 'Ingester response') logger.log('Hi there', (err, res) => { t.error(err, 'No error returned') t.end() }) })
test('Using opts.index_meta will not stringify the meta data', (t) => { const log = new Logger(apiKey, createOptions()) const opts = { index_meta: true , meta: { luke: 'skywalker' } } t.on('end', async () => { nock.cleanAll() }) nock(log._url) .post('/', (body) => { const payload = body.ls[0] t.deepEqual(payload.meta, opts.meta, 'Meta is an object') return true }) .query(() => { return true }) .reply(200, 'Ingester response') log.log('Howdy, folks!', opts, (err, body) => { t.error(err, 'No error returned') t.end() }) })
test('.log() rejects invalid `opts` data type', (t) => { const logger = new Logger(apiKey, createOptions()) t.on('end', async () => { nock.cleanAll() }) nock(logger._url) .post('/', () => { return true }) .query(() => { return true }) .reply(200, 'Ingester response') logger.log('log line', 12345, (err, res) => { t.type(err, Error, 'Error was returned') t.equal( err.message , 'options parameter must be a level (string), or object' , 'Error message is correct' ) t.deepEqual(err.meta, {opts: 12345}, 'Meta is set on the error') t.end() }) })
test('.log() can be called with level as an opts string', (t) => { const logger = new Logger(apiKey, createOptions()) const myLevel = 'DEBUG' t.on('end', async () => { nock.cleanAll() }) nock(logger._url) .post('/', (body) => { const payload = body.ls[0] t.equal(payload.level, myLevel, 'Level is correct') return true }) .query(() => { return true }) .reply(200, 'Ingester response') logger.log('Hi there', 'DEBUG', (err, res) => { t.error(err, 'No error returned') t.end() }) })
test('Using opts.context will replace opts.meta', (t) => { const log = new Logger(apiKey, createOptions()) const opts = { context: { hello: 'there' } } t.on('end', async () => { nock.cleanAll() }) nock(log._url) .post('/', (body) => { const payload = body.ls[0] t.equal(payload.meta, JSON.stringify(opts.context), 'Context replaced meta') return true }) .query(() => { return true }) .reply(200, 'Ingester response') log.trace('Hi', opts, (err, body) => { t.error(err, 'No error returned') t.end() }) })
test('Using _index_meta will not stringify the meta data', (t) => { const log = new Logger(apiKey, createOptions({ index_meta: true })) const opts = { meta: { luke: 'skywalker' } } t.on('end', async () => { nock.cleanAll() }) nock(log._url) .post('/', (body) => { const payload = body.ls[0] t.deepEqual(payload.meta, opts.meta, 'Meta is an object') return true }) .query(() => { return true }) .reply(200, 'Ingester response') log.trace('Howdy, folks!', opts, (err, body) => { t.error(err, 'No error returned') t.end() }) })
test('authenticate timeout', async function (t) { const openStub = url => openSuccess() const authenticate = proxyquire('../lib/authenticate', { open: openStub }) // mocking the browser opening simulateTimeout = true t.on('end', () => { simulateTimeout = false }) try { await authenticate(`http://127.0.0.1:${server.address().port}`) t.fail('it should reject') } catch (err) { t.plan(2) t.ok(err) t.ok(err.message.includes('Authentication timed out')) } })