Comparing version 0.10.3 to 0.11.0
@@ -41,2 +41,6 @@ declare const mixpanel: mixpanel.Mixpanel; | ||
export interface RemoveData { | ||
[key: string]: string | number | ||
} | ||
interface Mixpanel { | ||
@@ -63,2 +67,4 @@ init(mixpanelToken: string, config?: InitConfig): Mixpanel; | ||
people: People; | ||
groups: Groups; | ||
} | ||
@@ -75,3 +81,3 @@ | ||
unset(distinctId: string, propertyName: string | string[], modifiers?: Modifiers, callback?: Callback): void; | ||
set_once(distinctId: string, propertyName: string, value: string, callback?: Callback): void; | ||
@@ -96,2 +102,5 @@ set_once( distinctId: string, propertyName: string, value: string, modifiers: Modifiers, callback?: Callback): void; | ||
remove(distinctId: string, data: RemoveData, modifiers?: Modifiers, callback?: Callback): void; | ||
remove(distinctId: string, data: RemoveData, callback: Callback): void; | ||
track_charge(distinctId: string, amount: number | string, properties?: PropertyDict, callback?: Callback): void; | ||
@@ -106,4 +115,29 @@ track_charge(distinctId: string, amount: number | string, properties: PropertyDict, modifiers?: Modifiers, callback?: Callback): void; | ||
} | ||
interface Groups { | ||
set(groupKey: string, groupId: string, properties: PropertyDict, callback?: Callback): void; | ||
set(groupKey: string, groupId: string, properties: PropertyDict, modifiers?: Modifiers, callback?: Callback): void; | ||
set(groupKey: string, groupId: string, propertyName: string, value: string | number, modifiers: Modifiers): void; | ||
set(groupKey: string, groupId: string, propertyName: string, value: string | number, callback?: Callback): void; | ||
set(groupKey: string, groupId: string, propertyName: string, value: string | number, modifiers: Modifiers, callback: Callback): void; | ||
unset(groupKey: string, groupId: string, propertyName: string | string[], callback?: Callback): void; | ||
unset(groupKey: string, groupId: string, propertyName: string | string[], modifiers?: Modifiers, callback?: Callback): void; | ||
set_once(groupKey: string, groupId: string, propertyName: string, value: string, callback?: Callback): void; | ||
set_once( groupKey: string, groupId: string, propertyName: string, value: string, modifiers: Modifiers, callback?: Callback): void; | ||
set_once(groupKey: string, groupId: string, properties: PropertyDict, callback?: Callback): void; | ||
set_once(groupKey: string, groupId: string, properties: PropertyDict, modifiers?: Modifiers, callback?: Callback): void; | ||
union(groupKey: string, groupId: string, data: UnionData, modifiers?: Modifiers, callback?: Callback): void; | ||
union(groupKey: string, groupId: string, data: UnionData, callback: Callback): void; | ||
remove(groupKey: string, groupId: string, data: RemoveData, modifiers?: Modifiers, callback?: Callback): void; | ||
remove(groupKey: string, groupId: string, data: RemoveData, callback: Callback): void; | ||
delete_group(groupKey: string, groupId: string, modifiers?: Modifiers, callback?: Callback): void; | ||
delete_group(groupKey: string, groupId: string, callback: Callback): void; | ||
} | ||
} | ||
export = mixpanel; |
@@ -10,45 +10,38 @@ /* | ||
var http = require('http'), | ||
https = require('https'), | ||
querystring = require('querystring'), | ||
Buffer = require('buffer').Buffer, | ||
util = require('util'), | ||
HttpsProxyAgent = require('https-proxy-agent'); | ||
const querystring = require('querystring'); | ||
const Buffer = require('buffer').Buffer; | ||
const http = require('http'); | ||
const https = require('https'); | ||
const HttpsProxyAgent = require('https-proxy-agent'); | ||
var async_all = require('./utils').async_all; | ||
const {async_all, ensure_timestamp} = require('./utils'); | ||
const {MixpanelGroups} = require('./groups'); | ||
const {MixpanelPeople} = require('./people'); | ||
var REQUEST_LIBS = { | ||
http: http, | ||
https: https | ||
const DEFAULT_CONFIG = { | ||
test: false, | ||
debug: false, | ||
verbose: false, | ||
host: 'api.mixpanel.com', | ||
protocol: 'https', | ||
path: '', | ||
}; | ||
var create_proxy_agent = function() { | ||
var proxyPath = process.env.HTTPS_PROXY || process.env.HTTP_PROXY; | ||
return proxyPath ? new HttpsProxyAgent(proxyPath) : null; | ||
} | ||
var create_client = function(token, config) { | ||
var metrics = {}; | ||
var proxyAgent = create_proxy_agent(); | ||
if (!token) { | ||
throw new Error("The Mixpanel Client needs a Mixpanel token: `init(token)`"); | ||
} | ||
// mixpanel constants | ||
var MAX_BATCH_SIZE = 50, | ||
TRACK_AGE_LIMIT = 60 * 60 * 24 * 5; | ||
const MAX_BATCH_SIZE = 50; | ||
const TRACK_AGE_LIMIT = 60 * 60 * 24 * 5; | ||
const REQUEST_LIBS = {http, https}; | ||
const proxyPath = process.env.HTTPS_PROXY || process.env.HTTP_PROXY; | ||
const proxyAgent = proxyPath ? new HttpsProxyAgent(proxyPath) : null; | ||
if(!token) { | ||
throw new Error("The Mixpanel Client needs a Mixpanel token: `init(token)`"); | ||
} | ||
// Default config | ||
metrics.config = { | ||
test: false, | ||
debug: false, | ||
verbose: false, | ||
host: 'api.mixpanel.com', | ||
protocol: 'https', | ||
path: '', | ||
const metrics = { | ||
token, | ||
config: {...DEFAULT_CONFIG}, | ||
}; | ||
metrics.token = token; | ||
/** | ||
@@ -66,18 +59,18 @@ * sends an async GET or POST request to mixpanel | ||
var content = Buffer.from(JSON.stringify(options.data)).toString('base64'), | ||
endpoint = options.endpoint, | ||
method = (options.method || 'GET').toUpperCase(), | ||
query_params = { | ||
'ip': 0, | ||
'verbose': metrics.config.verbose ? 1 : 0 | ||
}, | ||
key = metrics.config.key, | ||
request_lib = REQUEST_LIBS[metrics.config.protocol], | ||
request_options = { | ||
host: metrics.config.host, | ||
port: metrics.config.port, | ||
headers: {}, | ||
method: method | ||
}, | ||
request; | ||
let content = Buffer.from(JSON.stringify(options.data)).toString('base64'); | ||
const endpoint = options.endpoint; | ||
const method = (options.method || 'GET').toUpperCase(); | ||
let query_params = { | ||
'ip': 0, | ||
'verbose': metrics.config.verbose ? 1 : 0 | ||
}; | ||
const key = metrics.config.key; | ||
const request_lib = REQUEST_LIBS[metrics.config.protocol]; | ||
let request_options = { | ||
host: metrics.config.host, | ||
port: metrics.config.port, | ||
headers: {}, | ||
method: method | ||
}; | ||
let request; | ||
@@ -182,14 +175,2 @@ if (!request_lib) { | ||
/** | ||
* Validate type of time property, and convert to Unix timestamp if necessary | ||
* @param {Date|number} time - value to check | ||
* @returns {number} Unix timestamp | ||
*/ | ||
var ensure_timestamp = function(time) { | ||
if (!(time instanceof Date || typeof time === "number")) { | ||
throw new Error("`time` property must be a Date or Unix timestamp and is only required for `import` endpoint"); | ||
} | ||
return time instanceof Date ? Math.floor(time.getTime() / 1000) : time; | ||
}; | ||
/** | ||
* breaks array into equal-sized chunks, with the last chunk being the remainder | ||
@@ -445,484 +426,5 @@ * @param {Array} arr | ||
metrics.people = { | ||
/** people.set_once(distinct_id, prop, to, modifiers, callback) | ||
--- | ||
The same as people.set but in the words of mixpanel: | ||
mixpanel.people.set_once | ||
metrics.groups = new MixpanelGroups(metrics); | ||
metrics.people = new MixpanelPeople(metrics); | ||
" This method allows you to set a user attribute, only if | ||
it is not currently set. It can be called multiple times | ||
safely, so is perfect for storing things like the first date | ||
you saw a user, or the referrer that brought them to your | ||
website for the first time. " | ||
*/ | ||
set_once: function(distinct_id, prop, to, modifiers, callback) { | ||
var $set = {}; | ||
if (typeof(prop) === 'object') { | ||
if (typeof(to) === 'object') { | ||
callback = modifiers; | ||
modifiers = to; | ||
} else { | ||
callback = to; | ||
} | ||
$set = prop; | ||
} else { | ||
$set[prop] = to; | ||
if (typeof(modifiers) === 'function' || !modifiers) { | ||
callback = modifiers; | ||
} | ||
} | ||
modifiers = modifiers || {}; | ||
modifiers.set_once = true; | ||
this._set(distinct_id, $set, callback, modifiers); | ||
}, | ||
/** | ||
people.set(distinct_id, prop, to, modifiers, callback) | ||
--- | ||
set properties on an user record in engage | ||
usage: | ||
mixpanel.people.set('bob', 'gender', 'm'); | ||
mixpanel.people.set('joe', { | ||
'company': 'acme', | ||
'plan': 'premium' | ||
}); | ||
*/ | ||
set: function(distinct_id, prop, to, modifiers, callback) { | ||
var $set = {}; | ||
if (typeof(prop) === 'object') { | ||
if (typeof(to) === 'object') { | ||
callback = modifiers; | ||
modifiers = to; | ||
} else { | ||
callback = to; | ||
} | ||
$set = prop; | ||
} else { | ||
$set[prop] = to; | ||
if (typeof(modifiers) === 'function' || !modifiers) { | ||
callback = modifiers; | ||
} | ||
} | ||
this._set(distinct_id, $set, callback, modifiers); | ||
}, | ||
// used internally by set and set_once | ||
_set: function(distinct_id, $set, callback, options) { | ||
options = options || {}; | ||
var set_key = (options && options.set_once) ? "$set_once" : "$set"; | ||
var data = { | ||
'$token': metrics.token, | ||
'$distinct_id': distinct_id | ||
}; | ||
data[set_key] = $set; | ||
if ('ip' in $set) { | ||
data.$ip = $set.ip; | ||
delete $set.ip; | ||
} | ||
if ($set.$ignore_time) { | ||
data.$ignore_time = $set.$ignore_time; | ||
delete $set.$ignore_time; | ||
} | ||
data = merge_modifiers(data, options); | ||
if (metrics.config.debug) { | ||
console.log("Sending the following data to Mixpanel (Engage):"); | ||
console.log(data); | ||
} | ||
metrics.send_request({ method: "GET", endpoint: "/engage", data: data }, callback); | ||
}, | ||
/** | ||
people.increment(distinct_id, prop, by, modifiers, callback) | ||
--- | ||
increment/decrement properties on an user record in engage | ||
usage: | ||
mixpanel.people.increment('bob', 'page_views', 1); | ||
// or, for convenience, if you're just incrementing a counter by 1, you can | ||
// simply do | ||
mixpanel.people.increment('bob', 'page_views'); | ||
// to decrement a counter, pass a negative number | ||
mixpanel.people.increment('bob', 'credits_left', -1); | ||
// like mixpanel.people.set(), you can increment multiple properties at once: | ||
mixpanel.people.increment('bob', { | ||
counter1: 1, | ||
counter2: 3, | ||
counter3: -2 | ||
}); | ||
*/ | ||
increment: function(distinct_id, prop, by, modifiers, callback) { | ||
var $add = {}; | ||
if (typeof(prop) === 'object') { | ||
if (typeof(by) === 'object') { | ||
callback = modifiers; | ||
modifiers = by; | ||
} else { | ||
callback = by; | ||
} | ||
Object.keys(prop).forEach(function(key) { | ||
var val = prop[key]; | ||
if (isNaN(parseFloat(val))) { | ||
if (metrics.config.debug) { | ||
console.error("Invalid increment value passed to mixpanel.people.increment - must be a number"); | ||
console.error("Passed " + key + ":" + val); | ||
} | ||
return; | ||
} else { | ||
$add[key] = val; | ||
} | ||
}); | ||
} else { | ||
if (typeof(by) === 'number' || !by) { | ||
by = by || 1; | ||
$add[prop] = by; | ||
if (typeof(modifiers) === 'function') { | ||
callback = modifiers; | ||
} | ||
} else if (typeof(by) === 'function') { | ||
callback = by; | ||
$add[prop] = 1; | ||
} else { | ||
callback = modifiers; | ||
modifiers = (typeof(by) === 'object') ? by : {}; | ||
$add[prop] = 1; | ||
} | ||
} | ||
var data = { | ||
'$add': $add, | ||
'$token': metrics.token, | ||
'$distinct_id': distinct_id | ||
}; | ||
data = merge_modifiers(data, modifiers); | ||
if (metrics.config.debug) { | ||
console.log("Sending the following data to Mixpanel (Engage):"); | ||
console.log(data); | ||
} | ||
metrics.send_request({ method: "GET", endpoint: "/engage", data: data }, callback); | ||
}, | ||
/** | ||
people.append(distinct_id, prop, value, modifiers, callback) | ||
--- | ||
Append a value to a list-valued people analytics property. | ||
usage: | ||
// append a value to a list, creating it if needed | ||
mixpanel.people.append('bob', 'pages_visited', 'homepage'); | ||
// like mixpanel.people.set(), you can append multiple properties at once: | ||
mixpanel.people.append('bob', { | ||
list1: 'bob', | ||
list2: 123 | ||
}); | ||
*/ | ||
append: function(distinct_id, prop, value, modifiers, callback) { | ||
var $append = {}; | ||
if (typeof(prop) === 'object') { | ||
if (typeof(value) === 'object') { | ||
callback = modifiers; | ||
modifiers = value; | ||
} else { | ||
callback = value; | ||
} | ||
Object.keys(prop).forEach(function(key) { | ||
$append[key] = prop[key]; | ||
}); | ||
} else { | ||
$append[prop] = value; | ||
if (typeof(modifiers) === 'function') { | ||
callback = modifiers; | ||
} | ||
} | ||
var data = { | ||
'$append': $append, | ||
'$token': metrics.token, | ||
'$distinct_id': distinct_id | ||
}; | ||
data = merge_modifiers(data, modifiers); | ||
if (metrics.config.debug) { | ||
console.log("Sending the following data to Mixpanel (Engage):"); | ||
console.log(data); | ||
} | ||
metrics.send_request({ method: "GET", endpoint: "/engage", data: data }, callback); | ||
}, | ||
/** | ||
people.track_charge(distinct_id, amount, properties, modifiers, callback) | ||
--- | ||
Record that you have charged the current user a certain | ||
amount of money. | ||
usage: | ||
// charge a user $29.99 | ||
mixpanel.people.track_charge('bob', 29.99); | ||
// charge a user $19 on the 1st of february | ||
mixpanel.people.track_charge('bob', 19, { '$time': new Date('feb 1 2012') }); | ||
*/ | ||
track_charge: function(distinct_id, amount, properties, modifiers, callback) { | ||
if (typeof(properties) === 'function' || !properties) { | ||
callback = properties || function() {}; | ||
properties = {}; | ||
} else { | ||
if (typeof(modifiers) === 'function' || !modifiers) { | ||
callback = modifiers || function() {}; | ||
if (properties.$ignore_time || properties.hasOwnProperty("$ip")) { | ||
modifiers = {}; | ||
Object.keys(properties).forEach(function(key) { | ||
modifiers[key] = properties[key]; | ||
delete properties[key]; | ||
}); | ||
} | ||
} | ||
} | ||
if (typeof(amount) !== 'number') { | ||
amount = parseFloat(amount); | ||
if (isNaN(amount)) { | ||
console.error("Invalid value passed to mixpanel.people.track_charge - must be a number"); | ||
return; | ||
} | ||
} | ||
properties.$amount = amount; | ||
if (properties.hasOwnProperty('$time')) { | ||
var time = properties.$time; | ||
if (Object.prototype.toString.call(time) === '[object Date]') { | ||
properties.$time = time.toISOString(); | ||
} | ||
} | ||
var data = { | ||
'$append': { '$transactions': properties }, | ||
'$token': metrics.token, | ||
'$distinct_id': distinct_id | ||
}; | ||
data = merge_modifiers(data, modifiers); | ||
if (metrics.config.debug) { | ||
console.log("Sending the following data to Mixpanel (Engage):"); | ||
console.log(data); | ||
} | ||
metrics.send_request({ method: "GET", endpoint: "/engage", data: data }, callback); | ||
}, | ||
/** | ||
people.clear_charges(distinct_id, modifiers, callback) | ||
--- | ||
Clear all the current user's transactions. | ||
usage: | ||
mixpanel.people.clear_charges('bob'); | ||
*/ | ||
clear_charges: function(distinct_id, modifiers, callback) { | ||
var data = { | ||
'$set': { '$transactions': [] }, | ||
'$token': metrics.token, | ||
'$distinct_id': distinct_id | ||
}; | ||
if (typeof(modifiers) === 'function') { callback = modifiers; } | ||
data = merge_modifiers(data, modifiers); | ||
if (metrics.config.debug) { | ||
console.log("Clearing this user's charges:", distinct_id); | ||
} | ||
metrics.send_request({ method: "GET", endpoint: "/engage", data: data }, callback); | ||
}, | ||
/** | ||
people.delete_user(distinct_id, modifiers, callback) | ||
--- | ||
delete an user record in engage | ||
usage: | ||
mixpanel.people.delete_user('bob'); | ||
*/ | ||
delete_user: function(distinct_id, modifiers, callback) { | ||
var data = { | ||
'$delete': '', | ||
'$token': metrics.token, | ||
'$distinct_id': distinct_id | ||
}; | ||
if (typeof(modifiers) === 'function') { callback = modifiers; } | ||
data = merge_modifiers(data, modifiers); | ||
if (metrics.config.debug) { | ||
console.log("Deleting the user from engage:", distinct_id); | ||
} | ||
metrics.send_request({ method: "GET", endpoint: "/engage", data: data }, callback); | ||
}, | ||
/** | ||
people.union(distinct_id, data, modifiers, callback) | ||
--- | ||
merge value(s) into a list-valued people analytics property. | ||
usage: | ||
mixpanel.people.union('bob', {'browsers': 'firefox'}); | ||
mixpanel.people.union('bob', {'browsers': ['chrome'], os: ['linux']}); | ||
*/ | ||
union: function(distinct_id, data, modifiers, callback) { | ||
var $union = {}; | ||
if (typeof(data) !== 'object' || util.isArray(data)) { | ||
if (metrics.config.debug) { | ||
console.error("Invalid value passed to mixpanel.people.union - data must be an object with scalar or array values"); | ||
} | ||
return; | ||
} | ||
Object.keys(data).forEach(function(key) { | ||
var val = data[key]; | ||
if (util.isArray(val)) { | ||
var merge_values = val.filter(function(v) { | ||
return typeof(v) === 'string' || typeof(v) === 'number'; | ||
}); | ||
if (merge_values.length > 0) { | ||
$union[key] = merge_values; | ||
} | ||
} else if (typeof(val) === 'string' || typeof(val) === 'number') { | ||
$union[key] = [val]; | ||
} else { | ||
if (metrics.config.debug) { | ||
console.error("Invalid argument passed to mixpanel.people.union - values must be a scalar value or array"); | ||
console.error("Passed " + key + ':', val); | ||
} | ||
return; | ||
} | ||
}); | ||
if (Object.keys($union).length === 0) { | ||
return; | ||
} | ||
data = { | ||
'$union': $union, | ||
'$token': metrics.token, | ||
'$distinct_id': distinct_id | ||
}; | ||
if (typeof(modifiers) === 'function') { | ||
callback = modifiers; | ||
} | ||
data = merge_modifiers(data, modifiers); | ||
if (metrics.config.debug) { | ||
console.log("Sending the following data to Mixpanel (Engage):"); | ||
console.log(data); | ||
} | ||
metrics.send_request({ method: "GET", endpoint: "/engage", data: data }, callback); | ||
}, | ||
/** | ||
people.unset(distinct_id, prop, modifiers, callback) | ||
--- | ||
delete a property on an user record in engage | ||
usage: | ||
mixpanel.people.unset('bob', 'page_views'); | ||
mixpanel.people.unset('bob', ['page_views', 'last_login']); | ||
*/ | ||
unset: function(distinct_id, prop, modifiers, callback) { | ||
var $unset = []; | ||
if (util.isArray(prop)) { | ||
$unset = prop; | ||
} else if (typeof(prop) === 'string') { | ||
$unset = [prop]; | ||
} else { | ||
if (metrics.config.debug) { | ||
console.error("Invalid argument passed to mixpanel.people.unset - must be a string or array"); | ||
console.error("Passed: " + prop); | ||
} | ||
return; | ||
} | ||
var data = { | ||
'$unset': $unset, | ||
'$token': metrics.token, | ||
'$distinct_id': distinct_id | ||
}; | ||
if (typeof(modifiers) === 'function') { | ||
callback = modifiers; | ||
} | ||
data = merge_modifiers(data, modifiers); | ||
if (metrics.config.debug) { | ||
console.log("Sending the following data to Mixpanel (Engage):"); | ||
console.log(data); | ||
} | ||
metrics.send_request({ method: "GET", endpoint: "/engage", data: data }, callback); | ||
} | ||
}; | ||
var merge_modifiers = function(data, modifiers) { | ||
if (modifiers) { | ||
if (modifiers.$ignore_alias) { | ||
data.$ignore_alias = modifiers.$ignore_alias; | ||
} | ||
if (modifiers.$ignore_time) { | ||
data.$ignore_time = modifiers.$ignore_time; | ||
} | ||
if (modifiers.hasOwnProperty("$ip")) { | ||
data.$ip = modifiers.$ip; | ||
} | ||
if (modifiers.hasOwnProperty("$time")) { | ||
data.$time = ensure_timestamp(modifiers.$time); | ||
} | ||
} | ||
return data; | ||
}; | ||
/** | ||
@@ -937,13 +439,9 @@ set_config(config) | ||
metrics.set_config = function(config) { | ||
for (var c in config) { | ||
if (config.hasOwnProperty(c)) { | ||
if (c == "host") { // Split host, into host and port. | ||
metrics.config.host = config[c].split(':')[0]; | ||
var port = config[c].split(':')[1]; | ||
if (port) { | ||
metrics.config.port = Number(port); | ||
} | ||
} else { | ||
metrics.config[c] = config[c]; | ||
} | ||
Object.assign(metrics.config, config); | ||
if (config.host) { | ||
// Split host into host and port | ||
const [host, port] = config.host.split(':'); | ||
metrics.config.host = host; | ||
if (port) { | ||
metrics.config.port = Number(port); | ||
} | ||
@@ -950,0 +448,0 @@ } |
@@ -32,1 +32,13 @@ /** | ||
}; | ||
/** | ||
* Validate type of time property, and convert to Unix timestamp if necessary | ||
* @param {Date|number} time - value to check | ||
* @returns {number} Unix timestamp | ||
*/ | ||
exports.ensure_timestamp = function(time) { | ||
if (!(time instanceof Date || typeof time === "number")) { | ||
throw new Error("`time` property must be a Date or Unix timestamp and is only required for `import` endpoint"); | ||
} | ||
return time instanceof Date ? Math.floor(time.getTime() / 1000) : time; | ||
}; |
@@ -10,3 +10,3 @@ { | ||
], | ||
"version": "0.10.3", | ||
"version": "0.11.0", | ||
"homepage": "https://github.com/mixpanel/mixpanel-node", | ||
@@ -24,3 +24,3 @@ "author": "Carl Sverre", | ||
"engines": { | ||
"node": ">=6.9" | ||
"node": ">=8.9" | ||
}, | ||
@@ -27,0 +27,0 @@ "scripts": { |
@@ -36,3 +36,17 @@ var Mixpanel = require('../lib/mixpanel-node'); | ||
test.done(); | ||
} | ||
}, | ||
"host config is split into host and port": function(test) { | ||
const exampleHost = 'api.example.com'; | ||
const examplePort = 70; | ||
const hostWithoutPortConfig = Mixpanel.init('token', {host: exampleHost}).config; | ||
test.equal(hostWithoutPortConfig.port, undefined, "port should not have been added to config"); | ||
test.equal(hostWithoutPortConfig.host, exampleHost, `host should match ${exampleHost}`); | ||
const hostWithPortConfig = Mixpanel.init('token', {host: `${exampleHost}:${examplePort}`}).config; | ||
test.equal(hostWithPortConfig.port, examplePort, "port should have been added to config"); | ||
test.equal(hostWithPortConfig.host, exampleHost, `host should match ${exampleHost}`); | ||
test.done(); | ||
}, | ||
}; |
@@ -1,16 +0,13 @@ | ||
var Mixpanel = require('../lib/mixpanel-node'), | ||
Sinon = require('sinon'); | ||
const Mixpanel = require('../lib/mixpanel-node'); | ||
const Sinon = require('sinon'); | ||
const {create_profile_helpers} = require('../lib/profile_helpers'); | ||
// shared test case | ||
var test_send_request_args = function(test, func, options) { | ||
var expected_data = { | ||
$token: this.token, | ||
$distinct_id: this.distinct_id, | ||
}; | ||
for (var k in options.expected) { | ||
expected_data[k] = options.expected[k]; | ||
} | ||
var args = [this.distinct_id].concat(options.args || []); | ||
const test_send_request_args = function(test, func, {args, expected, use_modifiers, use_callback} = {}) { | ||
let expected_data = {$token: this.token, $distinct_id: this.distinct_id, ...expected}; | ||
let callback; | ||
if (options.use_modifiers) { | ||
args = [this.distinct_id, ...(args ? args : [])]; | ||
if (use_modifiers) { | ||
var modifiers = { | ||
@@ -22,22 +19,23 @@ '$ignore_alias': true, | ||
}; | ||
for (k in modifiers) { | ||
expected_data[k] = modifiers[k]; | ||
} | ||
Object.assign(expected_data, modifiers); | ||
args.push(modifiers); | ||
} | ||
if (options.use_callback) { | ||
var callback = function() {}; | ||
if (use_callback) { | ||
callback = function() {}; | ||
args.push(callback); | ||
} | ||
this.mixpanel.people[func].apply(this.mixpanel.people, args); | ||
this.mixpanel.people[func](...args); | ||
const expectedSendRequestArgs = [{ method: 'GET', endpoint: this.endpoint, data: expected_data }]; | ||
test.ok( | ||
this.mixpanel.send_request.calledWithMatch({ method: 'GET', endpoint: this.endpoint, data: expected_data }), | ||
"people." + func + " didn't call send_request with correct arguments" | ||
this.send_request.calledWithMatch(...expectedSendRequestArgs), | ||
`people.${func} didn't call send_request with correct arguments | ||
Actual arguments: ${JSON.stringify(this.send_request.getCall(0).args)} | ||
expected to include: ${JSON.stringify(expectedSendRequestArgs)}` | ||
); | ||
if (options.use_callback) { | ||
if (use_callback) { | ||
test.ok( | ||
this.mixpanel.send_request.args[0][1] === callback, | ||
"people.set didn't call send_request with a callback" | ||
this.send_request.args[0][1] === callback, | ||
`people.${func} didn't call send_request with a callback` | ||
); | ||
@@ -50,9 +48,10 @@ } | ||
setUp: function(next) { | ||
this.endpoint = '/engage'; | ||
this.distinct_id = 'user1'; | ||
this.token = 'token'; | ||
this.mixpanel = Mixpanel.init(this.token); | ||
Sinon.stub(this.mixpanel, 'send_request'); | ||
this.send_request = Sinon.stub(); | ||
this.distinct_id = "user1"; | ||
this.endpoint = "/engage"; | ||
this.mixpanel = Mixpanel.init(this.token); | ||
this.mixpanel.send_request = this.send_request | ||
@@ -65,4 +64,2 @@ this.test_send_request_args = test_send_request_args; | ||
tearDown: function(next) { | ||
this.mixpanel.send_request.restore(); | ||
next(); | ||
@@ -514,2 +511,51 @@ }, | ||
remove: { | ||
"calls send_request with correct endpoint and data": function(test) { | ||
this.test_send_request_args(test, 'remove', { | ||
args: [{'key1': 'value1', 'key2': 'value2'}], | ||
expected: {$remove: {'key1': 'value1', 'key2': 'value2'}}, | ||
}); | ||
}, | ||
"errors on non-scalar argument types": function(test) { | ||
this.mixpanel.people.remove(this.distinct_id, {'key1': ['value1']}); | ||
this.mixpanel.people.remove(this.distinct_id, {key1: {key: 'val'}}); | ||
this.mixpanel.people.remove(this.distinct_id, 1231241.123); | ||
this.mixpanel.people.remove(this.distinct_id, [5]); | ||
this.mixpanel.people.remove(this.distinct_id, {key1: function() {}}); | ||
this.mixpanel.people.remove(this.distinct_id, {key1: [function() {}]}); | ||
test.ok( | ||
!this.mixpanel.send_request.called, | ||
"people.remove shouldn't call send_request on invalid arguments" | ||
); | ||
test.done(); | ||
}, | ||
"supports being called with a modifiers argument": function(test) { | ||
this.test_send_request_args(test, 'remove', { | ||
args: [{'key1': 'value1'}], | ||
expected: {$remove: {'key1': 'value1'}}, | ||
use_modifiers: true, | ||
}); | ||
}, | ||
"supports being called with a callback": function(test) { | ||
this.test_send_request_args(test, 'remove', { | ||
args: [{'key1': 'value1'}], | ||
expected: {$remove: {'key1': 'value1'}}, | ||
use_callback: true, | ||
}); | ||
}, | ||
"supports being called with a modifiers argument and a callback": function(test) { | ||
this.test_send_request_args(test, 'remove', { | ||
args: [{'key1': 'value1'}], | ||
expected: {$remove: {'key1': 'value1'}}, | ||
use_callback: true, | ||
use_modifiers: true, | ||
}); | ||
}, | ||
}, | ||
union: { | ||
@@ -516,0 +562,0 @@ "calls send_request with correct endpoint and data": function(test) { |
@@ -1,9 +0,9 @@ | ||
var Mixpanel, | ||
Sinon = require('sinon'), | ||
proxyquire = require('proxyquire'), | ||
https = require('https'), | ||
events = require('events'), | ||
httpProxyOrig = process.env.HTTP_PROXY, | ||
httpsProxyOrig = process.env.HTTPS_PROXY, | ||
HttpsProxyAgent; | ||
let Mixpanel; | ||
const Sinon = require('sinon'); | ||
const proxyquire = require('proxyquire'); | ||
const https = require('https'); | ||
const events = require('events'); | ||
const httpProxyOrig = process.env.HTTP_PROXY; | ||
const httpsProxyOrig = process.env.HTTPS_PROXY; | ||
let HttpsProxyAgent; | ||
@@ -14,3 +14,3 @@ exports.send_request = { | ||
Mixpanel = proxyquire('../lib/mixpanel-node', { | ||
'https-proxy-agent': HttpsProxyAgent | ||
'https-proxy-agent': HttpsProxyAgent, | ||
}); | ||
@@ -17,0 +17,0 @@ |
Sorry, the diff of this file is not supported yet
142936
20
3055