GT2/GT2-iOS/node_modules/analytics-node/test/index.js

387 lines
10 KiB
JavaScript

/* global describe, before, beforeEach, it */
var assert = require('assert')
var Analytics = require('..')
var server = require('./server')
var a
var noop = function () {}
var id = 'id'
var context = {
library: {
name: 'analytics-node',
version: require('../package.json').version
}
}
describe('Analytics', function () {
before(function (done) {
server.app
.post('/v1/batch', server.fixture)
.listen(server.port, done)
})
beforeEach(function () {
a = Analytics('key', {
host: 'http://localhost:4063',
flushAt: Infinity,
flushAfter: Infinity
})
})
it('should expose a constructor', function () {
assert.equal('function', typeof Analytics)
})
it('should require a write key', function () {
assert.throws(Analytics, error("You must pass your Segment project's write key."))
})
it('should not require the new keyword', function () {
assert(a instanceof Analytics)
})
it('should create a queue', function () {
assert.deepEqual(a.queue, [])
})
it('should set default options', function () {
var a = Analytics('key')
assert.equal(a.writeKey, 'key')
assert.equal(a.host, 'https://api.segment.io')
assert.equal(a.flushAt, 20)
assert.equal(a.flushAfter, 10000)
})
it('should remove trailing slashes from `.host`', function () {
var a = Analytics('key', { host: 'http://google.com/////' })
assert.equal(a.host, 'http://google.com')
})
it('should take options', function () {
var a = Analytics('key', {
host: 'a',
flushAt: 1,
flushAfter: 2
})
assert.equal(a.host, 'a')
assert.equal(a.flushAt, 1)
assert.equal(a.flushAfter, 2)
})
it('should keep the flushAt option above zero', function () {
var a = Analytics('key', { flushAt: 0 })
assert.equal(a.flushAt, 1)
})
describe('#enqueue', function () {
it('should add a message to the queue', function () {
var date = new Date()
a.enqueue('type', { timestamp: date }, noop)
var msg = a.queue[0].message
var callback = a.queue[0].callback
assert.equal(callback, noop)
assert.equal(msg.type, 'type')
assert.deepEqual(msg.timestamp, date)
assert.deepEqual(msg.context, context)
assert(msg.messageId)
})
it('should not modify the original message', function () {
var message = { event: 'test' }
a.enqueue('type', message, noop)
assert(!message.hasOwnProperty('timestamp'))
})
it('should flush the queue if it hits the max length', function (done) {
a.flushAt = 1
a.flushAfter = null
a.flush = done
a.enqueue('type', {})
})
it('should flush after a period of time', function (done) {
a.flushAt = Infinity
a.flushAfter = 1
a.flush = done
a.enqueue('type', {})
})
it('should reset an existing timer', function (done) {
var i = 0
a.flushAt = Infinity
a.flushAfter = 1
a.flush = function () { i++ }
a.enqueue('type', {})
a.enqueue('type', {})
setTimeout(function () {
assert.equal(1, i)
done()
}, 1)
})
it('should extend the given context', function () {
a.enqueue('type', { event: 'test', context: { name: 'travis' } }, noop)
assert.deepEqual(a.queue[0].message.context, {
library: {
name: 'analytics-node',
version: require('../package.json').version
},
name: 'travis'
})
})
it('should add a message id', function () {
a.enqueue('type', { event: 'test' }, noop)
var msg = a.queue[0].message
assert(msg.messageId)
assert(/node-[a-zA-Z0-9]{32}/.test(msg.messageId))
})
})
describe('#flush', function () {
it('should not fail when no items are in the queue', function (done) {
a.flush(done)
})
it('should send a batch of items', function (done) {
a.flushAt = 2
enqueue(a, [1, 2, 3])
a.flush(function (err, data) {
if (err) return done(err)
assert.deepEqual(data.batch, [1, 2])
assert(data.timestamp instanceof Date)
assert(data.sentAt instanceof Date)
done()
})
})
it('should callback with an HTTP error', function (done) {
enqueue(a, ['error'])
a.flush(function (err, data) {
assert(err)
assert.equal(err.message, 'Bad Request')
done()
})
})
})
describe('#identify', function () {
it('should enqueue a message', function () {
var date = new Date()
a.identify({ userId: 'id', timestamp: date, messageId: id })
assert.deepEqual(a.queue[0].message, {
type: 'identify',
userId: 'id',
timestamp: date,
context: context,
messageId: id,
_metadata: { nodeVersion: process.versions.node }
})
})
it('should validate a message', function () {
assert.throws(a.identify, error('You must pass a message object.'))
})
it('should require a userId or anonymousId', function () {
assert.throws(function () {
a.identify({})
}, error('You must pass either an "anonymousId" or a "userId".'))
})
})
describe('#group', function () {
it('should enqueue a message', function () {
var date = new Date()
a.group({ groupId: 'group', userId: 'user', timestamp: date, messageId: id })
assert.deepEqual(a.queue[0].message, {
type: 'group',
userId: 'user',
groupId: 'group',
timestamp: date,
context: context,
messageId: id,
_metadata: { nodeVersion: process.versions.node }
})
})
it('should validate a message', function () {
assert.throws(a.group, error('You must pass a message object.'))
})
it('should require a userId or anonymousId', function () {
assert.throws(function () {
a.group({})
}, error('You must pass either an "anonymousId" or a "userId".'))
})
it('should require a groupId', function () {
assert.throws(function () {
a.group({ userId: 'id' })
}, error('You must pass a "groupId".'))
})
})
describe('#track', function () {
it('should enqueue a message', function () {
var date = new Date()
a.track({ userId: 'id', event: 'event', timestamp: date, messageId: id })
assert.deepEqual(a.queue[0].message, {
type: 'track',
event: 'event',
userId: 'id',
timestamp: date,
context: context,
messageId: id,
_metadata: { nodeVersion: process.versions.node }
})
})
it('should handle a user ids given as a number', function () {
var date = new Date()
a.track({ userId: 1, event: 'jumped the shark', timestamp: date, messageId: id })
assert.deepEqual(a.queue[0].message, {
userId: 1,
event: 'jumped the shark',
type: 'track',
timestamp: date,
context: context,
messageId: id,
_metadata: { nodeVersion: process.versions.node }
})
})
it('should validate a message', function () {
assert.throws(a.track, error('You must pass a message object.'))
})
it('should require a userId or anonymousId', function () {
assert.throws(function () {
a.track({})
}, error('You must pass either an "anonymousId" or a "userId".'))
})
it('should require an event', function () {
assert.throws(function () {
a.track({ userId: 'id' })
}, error('You must pass an "event".'))
})
})
describe('#page', function () {
it('should enqueue a message', function () {
var date = new Date()
a.page({ userId: 'id', timestamp: date, messageId: id })
assert.deepEqual(a.queue[0].message, {
type: 'page',
userId: 'id',
timestamp: date,
context: context,
messageId: id,
_metadata: { nodeVersion: process.versions.node }
})
})
it('should validate a message', function () {
assert.throws(a.page, error('You must pass a message object.'))
})
it('should require a userId or anonymousId', function () {
assert.throws(function () {
a.page({})
}, error('You must pass either an "anonymousId" or a "userId".'))
})
})
describe('#screen', function () {
it('should enqueue a message', function () {
var date = new Date()
a.screen({ userId: 'id', timestamp: date, messageId: id })
assert.deepEqual(a.queue[0].message, {
type: 'screen',
userId: 'id',
timestamp: date,
context: context,
messageId: id,
_metadata: { nodeVersion: process.versions.node }
})
})
it('should validate a message', function () {
assert.throws(a.screen, error('You must pass a message object.'))
})
it('should require a userId or anonymousId', function () {
assert.throws(function () {
a.screen({})
}, error('You must pass either an "anonymousId" or a "userId".'))
})
})
describe('#alias', function () {
it('should enqueue a message', function () {
var date = new Date()
a.alias({ previousId: 'previous', userId: 'id', timestamp: date, messageId: id })
assert.deepEqual(a.queue[0].message, {
type: 'alias',
previousId: 'previous',
userId: 'id',
timestamp: date,
context: context,
messageId: id,
_metadata: { nodeVersion: process.versions.node }
})
})
it('should validate a message', function () {
assert.throws(a.alias, error('You must pass a message object.'))
})
it('should require a userId', function () {
assert.throws(function () {
a.alias({})
}, error('You must pass a "userId".'))
})
it('should require a previousId', function () {
assert.throws(function () {
a.alias({ userId: 'id' })
}, error('You must pass a "previousId".'))
})
})
})
/**
* Create a queue with `messages`.
*
* @param {Analytics} a
* @param {Array} messages
* @return {Array}
*/
function enqueue (a, messages) {
a.queue = messages.map(function (msg) {
return {
message: msg,
callback: noop
}
})
}
/**
* Assert an error with `message` is thrown.
*
* @param {String} message
* @return {Function}
*/
function error (message) {
return function (err) {
return err.message === message
}
}