2025-04-24 17:03:28 +08:00

551 lines
22 KiB
JavaScript

var request = require("request");
var qs = require("querystring");
var uuid = require("uuid");
var should = require("should");
var sinon = require("sinon");
var url = require("url");
var ua = require("../lib/index.js");
var utils = require("../lib/utils.js")
var config = require("../lib/config.js")
describe("ua", function () {
describe("#item", function () {
var _enqueue;
beforeEach(function () {
_enqueue = sinon.stub(ua.Visitor.prototype, "_enqueue", function (type, params, fn) {
if (fn) {
(typeof fn).should.equal('function', "#_enqueue should receive a callback")
fn();
}
return this;
});
});
afterEach(function () {
_enqueue.restore()
});
it("should be available via the #i shortcut", function () {
var visitor = ua()
visitor.i.should.equal(visitor.item)
});
it("should accept arguments (price) when chained to transaction", function () {
var transaction = Math.random().toString();
var price = Math.random();
var visitor = ua().transaction(transaction);
var result = visitor.item(price);
visitor._context = result._context;
result.should.eql(visitor, "should return a visitor that is identical except for the context");
result.should.be.instanceof(ua.Visitor);
result._context.should.eql(_enqueue.args[1][1], "the transaction params should be persisted as the context of the visitor clone")
_enqueue.calledTwice.should.equal(true, "#_enqueue should have been called twice, once for the transaction before");
_enqueue.args[0][0].should.equal("transaction");
_enqueue.args[1][0].should.equal("item");
_enqueue.args[1][1].should.have.keys("ti", "ip")
_enqueue.args[1][1].ti.should.equal(transaction);
_enqueue.args[1][1].ip.should.equal(price);
});
it("should accept arguments (price, fn) when chained to transaction", function () {
var transaction = Math.random().toString();
var price = Math.random();
var fn = sinon.spy()
var visitor = ua().transaction(transaction);
var result = visitor.item(price, fn);
visitor._context = result._context;
result.should.eql(visitor, "should return a visitor that is identical except for the context");
result.should.be.instanceof(ua.Visitor);
result._context.should.eql(_enqueue.args[1][1], "the transaction params should be persisted as the context of the visitor clone")
_enqueue.calledTwice.should.equal(true, "#_enqueue should have been called twice, once for the transaction before");
_enqueue.args[0][0].should.equal("transaction");
_enqueue.args[1][0].should.equal("item");
_enqueue.args[1][1].should.have.keys("ti", "ip")
_enqueue.args[1][1].ti.should.equal(transaction);
_enqueue.args[1][1].ip.should.equal(price);
fn.calledOnce.should.equal(true, "callback should have been called once")
});
it("should accept arguments (price, quantity) when chained to transaction", function () {
var transaction = Math.random().toString();
var price = Math.random();
var quantity = Math.random();
var visitor = ua().transaction(transaction);
var result = visitor.item(price, quantity);
visitor._context = result._context;
result.should.eql(visitor, "should return a visitor that is identical except for the context");
result.should.be.instanceof(ua.Visitor);
result._context.should.eql(_enqueue.args[1][1], "the transaction params should be persisted as the context of the visitor clone")
_enqueue.calledTwice.should.equal(true, "#_enqueue should have been called twice, once for the transaction before");
_enqueue.args[0][0].should.equal("transaction");
_enqueue.args[1][0].should.equal("item");
_enqueue.args[1][1].should.have.keys("ti", "ip", "iq")
_enqueue.args[1][1].ti.should.equal(transaction);
_enqueue.args[1][1].ip.should.equal(price);
_enqueue.args[1][1].iq.should.equal(quantity);
});
it("should accept arguments (price, quantity, fn) when chained to transaction", function () {
var transaction = Math.random().toString();
var price = Math.random();
var quantity = Math.random();
var fn = sinon.spy()
var visitor = ua().transaction(transaction);
var result = visitor.item(price, quantity, fn);
visitor._context = result._context;
result.should.eql(visitor, "should return a visitor that is identical except for the context");
result.should.be.instanceof(ua.Visitor);
result._context.should.eql(_enqueue.args[1][1], "the transaction params should be persisted as the context of the visitor clone")
_enqueue.calledTwice.should.equal(true, "#_enqueue should have been called twice, once for the transaction before");
_enqueue.args[0][0].should.equal("transaction");
_enqueue.args[1][0].should.equal("item");
_enqueue.args[1][1].should.have.keys("ti", "ip", "iq")
_enqueue.args[1][1].ti.should.equal(transaction);
_enqueue.args[1][1].ip.should.equal(price);
_enqueue.args[1][1].iq.should.equal(quantity);
fn.calledOnce.should.equal(true, "callback should have been called once")
});
it("should accept arguments (price, quantity, sku) when chained to transaction", function () {
var transaction = Math.random().toString();
var price = Math.random();
var quantity = Math.random();
var sku = Math.random().toString();
var visitor = ua().transaction(transaction);
var result = visitor.item(price, quantity, sku);
visitor._context = result._context;
result.should.eql(visitor, "should return a visitor that is identical except for the context");
result.should.be.instanceof(ua.Visitor);
result._context.should.eql(_enqueue.args[1][1], "the transaction params should be persisted as the context of the visitor clone")
_enqueue.calledTwice.should.equal(true, "#_enqueue should have been called twice, once for the transaction before");
_enqueue.args[0][0].should.equal("transaction");
_enqueue.args[1][0].should.equal("item");
_enqueue.args[1][1].should.have.keys("ti", "ip", "iq", "ic")
_enqueue.args[1][1].ti.should.equal(transaction);
_enqueue.args[1][1].ip.should.equal(price);
_enqueue.args[1][1].iq.should.equal(quantity);
_enqueue.args[1][1].ic.should.equal(sku);
});
it("should accept arguments (price, quantity, sku, fn) when chained to transaction", function () {
var transaction = Math.random().toString();
var price = Math.random();
var quantity = Math.random();
var sku = Math.random().toString();
var fn = sinon.spy()
var visitor = ua().transaction(transaction);
var result = visitor.item(price, quantity, sku, fn);
visitor._context = result._context;
result.should.eql(visitor, "should return a visitor that is identical except for the context");
result.should.be.instanceof(ua.Visitor);
result._context.should.eql(_enqueue.args[1][1], "the transaction params should be persisted as the context of the visitor clone")
_enqueue.calledTwice.should.equal(true, "#_enqueue should have been called twice, once for the transaction before");
_enqueue.args[0][0].should.equal("transaction");
_enqueue.args[1][0].should.equal("item");
_enqueue.args[1][1].should.have.keys("ti", "ip", "iq", "ic")
_enqueue.args[1][1].ti.should.equal(transaction);
_enqueue.args[1][1].ip.should.equal(price);
_enqueue.args[1][1].iq.should.equal(quantity);
_enqueue.args[1][1].ic.should.equal(sku);
fn.calledOnce.should.equal(true, "callback should have been called once")
});
it("should accept arguments (price, quantity, sku, name) when chained to transaction", function () {
var transaction = Math.random().toString();
var price = Math.random();
var quantity = Math.random();
var sku = Math.random().toString();
var name = Math.random().toString();
var visitor = ua().transaction(transaction);
var result = visitor.item(price, quantity, sku, name);
visitor._context = result._context;
result.should.eql(visitor, "should return a visitor that is identical except for the context");
result.should.be.instanceof(ua.Visitor);
result._context.should.eql(_enqueue.args[1][1], "the transaction params should be persisted as the context of the visitor clone")
_enqueue.calledTwice.should.equal(true, "#_enqueue should have been called twice, once for the transaction before");
_enqueue.args[0][0].should.equal("transaction");
_enqueue.args[1][0].should.equal("item");
_enqueue.args[1][1].should.have.keys("ti", "ip", "iq", "ic", "in")
_enqueue.args[1][1].ti.should.equal(transaction);
_enqueue.args[1][1].ip.should.equal(price);
_enqueue.args[1][1].iq.should.equal(quantity);
_enqueue.args[1][1].ic.should.equal(sku);
_enqueue.args[1][1].in.should.equal(name);
});
it("should accept arguments (price, quantity, sku, name, fn) when chained to transaction", function () {
var transaction = Math.random().toString();
var price = Math.random();
var quantity = Math.random();
var sku = Math.random().toString();
var name = Math.random().toString();
var fn = sinon.spy()
var visitor = ua().transaction(transaction);
var result = visitor.item(price, quantity, sku, name, fn);
visitor._context = result._context;
result.should.eql(visitor, "should return a visitor that is identical except for the context");
result.should.be.instanceof(ua.Visitor);
result._context.should.eql(_enqueue.args[1][1], "the transaction params should be persisted as the context of the visitor clone")
_enqueue.calledTwice.should.equal(true, "#_enqueue should have been called twice, once for the transaction before");
_enqueue.args[0][0].should.equal("transaction");
_enqueue.args[1][0].should.equal("item");
_enqueue.args[1][1].should.have.keys("ti", "ip", "iq", "ic", "in")
_enqueue.args[1][1].ti.should.equal(transaction);
_enqueue.args[1][1].ip.should.equal(price);
_enqueue.args[1][1].iq.should.equal(quantity);
_enqueue.args[1][1].ic.should.equal(sku);
_enqueue.args[1][1].in.should.equal(name);
fn.calledOnce.should.equal(true, "callback should have been called once")
});
it("should accept arguments (price, quantity, sku, name, variation) when chained to transaction", function () {
var transaction = Math.random().toString();
var price = Math.random();
var quantity = Math.random();
var sku = Math.random().toString();
var name = Math.random().toString();
var variation = Math.random().toString();
var visitor = ua().transaction(transaction);
var result = visitor.item(price, quantity, sku, name, variation);
visitor._context = result._context;
result.should.eql(visitor, "should return a visitor that is identical except for the context");
result.should.be.instanceof(ua.Visitor);
result._context.should.eql(_enqueue.args[1][1], "the transaction params should be persisted as the context of the visitor clone")
_enqueue.calledTwice.should.equal(true, "#_enqueue should have been called twice, once for the transaction before");
_enqueue.args[0][0].should.equal("transaction");
_enqueue.args[1][0].should.equal("item");
_enqueue.args[1][1].should.have.keys("ti", "ip", "iq", "ic", "in", "iv")
_enqueue.args[1][1].ti.should.equal(transaction);
_enqueue.args[1][1].ip.should.equal(price);
_enqueue.args[1][1].iq.should.equal(quantity);
_enqueue.args[1][1].ic.should.equal(sku);
_enqueue.args[1][1].in.should.equal(name);
_enqueue.args[1][1].iv.should.equal(variation);
});
it("should accept arguments (price, quantity, sku, name, variation, fn) when chained to transaction", function () {
var transaction = Math.random().toString();
var price = Math.random();
var quantity = Math.random();
var sku = Math.random().toString();
var name = Math.random().toString();
var variation = Math.random().toString();
var fn = sinon.spy()
var visitor = ua().transaction(transaction);
var result = visitor.item(price, quantity, sku, name, variation, fn);
visitor._context = result._context;
result.should.eql(visitor, "should return a visitor that is identical except for the context");
result.should.be.instanceof(ua.Visitor);
result._context.should.eql(_enqueue.args[1][1], "the transaction params should be persisted as the context of the visitor clone")
_enqueue.calledTwice.should.equal(true, "#_enqueue should have been called twice, once for the transaction before");
_enqueue.args[0][0].should.equal("transaction");
_enqueue.args[1][0].should.equal("item");
_enqueue.args[1][1].should.have.keys("ti", "ip", "iq", "ic", "in", "iv")
_enqueue.args[1][1].ti.should.equal(transaction);
_enqueue.args[1][1].ip.should.equal(price);
_enqueue.args[1][1].iq.should.equal(quantity);
_enqueue.args[1][1].ic.should.equal(sku);
_enqueue.args[1][1].in.should.equal(name);
_enqueue.args[1][1].iv.should.equal(variation);
fn.calledOnce.should.equal(true, "callback should have been called once")
});
it("should accept arguments (price, quantity, sku, name, variation, params) when chained to transaction", function () {
var transaction = Math.random().toString();
var price = Math.random();
var quantity = Math.random();
var sku = Math.random().toString();
var name = Math.random().toString();
var variation = Math.random().toString();
var params = {foo: Math.random().toString()};
var visitor = ua().transaction(transaction);
var result = visitor.item(price, quantity, sku, name, variation, params);
visitor._context = result._context;
result.should.eql(visitor, "should return a visitor that is identical except for the context");
result.should.be.instanceof(ua.Visitor);
result._context.should.eql(_enqueue.args[1][1], "the transaction params should be persisted as the context of the visitor clone")
_enqueue.calledTwice.should.equal(true, "#_enqueue should have been called twice, once for the transaction before");
_enqueue.args[0][0].should.equal("transaction");
_enqueue.args[1][0].should.equal("item");
_enqueue.args[1][1].should.have.keys("ti", "ip", "iq", "ic", "in", "iv", "foo")
_enqueue.args[1][1].ti.should.equal(transaction);
_enqueue.args[1][1].ip.should.equal(price);
_enqueue.args[1][1].iq.should.equal(quantity);
_enqueue.args[1][1].ic.should.equal(sku);
_enqueue.args[1][1].in.should.equal(name);
_enqueue.args[1][1].iv.should.equal(variation);
_enqueue.args[1][1].foo.should.equal(params.foo);
});
it("should accept arguments (price, quantity, sku, name, variation, params, fn) when chained to transaction", function () {
var transaction = Math.random().toString();
var price = Math.random();
var quantity = Math.random();
var sku = Math.random().toString();
var name = Math.random().toString();
var variation = Math.random().toString();
var params = {foo: Math.random().toString()};
var fn = sinon.spy()
var visitor = ua().transaction(transaction);
var result = visitor.item(price, quantity, sku, name, variation, params, fn);
visitor._context = result._context;
result.should.eql(visitor, "should return a visitor that is identical except for the context");
result.should.be.instanceof(ua.Visitor);
result._context.should.eql(_enqueue.args[1][1], "the transaction params should be persisted as the context of the visitor clone")
_enqueue.calledTwice.should.equal(true, "#_enqueue should have been called twice, once for the transaction before");
_enqueue.args[0][0].should.equal("transaction");
_enqueue.args[1][0].should.equal("item");
_enqueue.args[1][1].should.have.keys("ti", "ip", "iq", "ic", "in", "iv", "foo")
_enqueue.args[1][1].ti.should.equal(transaction);
_enqueue.args[1][1].ip.should.equal(price);
_enqueue.args[1][1].iq.should.equal(quantity);
_enqueue.args[1][1].ic.should.equal(sku);
_enqueue.args[1][1].in.should.equal(name);
_enqueue.args[1][1].iv.should.equal(variation);
_enqueue.args[1][1].foo.should.equal(params.foo);
fn.calledOnce.should.equal(true, "callback should have been called once")
});
it("should accept arguments (price, quantity, sku, name, variation, params, fn) when params include transaction", function () {
var price = Math.random();
var quantity = Math.random();
var sku = Math.random().toString();
var name = Math.random().toString();
var variation = Math.random().toString();
var params = {ti: Math.random()};
var fn = sinon.spy()
var visitor = ua();
var result = visitor.item(price, quantity, sku, name, variation, params, fn);
visitor._context = result._context;
result.should.eql(visitor, "should return a visitor that is identical except for the context");
result.should.be.instanceof(ua.Visitor);
result._context.should.eql(_enqueue.args[0][1], "the transaction params should be persisted as the context of the visitor clone")
_enqueue.calledOnce.should.equal(true, "#_enqueue should have been called once");
_enqueue.args[0][0].should.equal("item");
_enqueue.args[0][1].should.have.keys("ti", "ip", "iq", "ic", "in", "iv")
_enqueue.args[0][1].ip.should.equal(price);
_enqueue.args[0][1].iq.should.equal(quantity);
_enqueue.args[0][1].ic.should.equal(sku);
_enqueue.args[0][1].in.should.equal(name);
_enqueue.args[0][1].iv.should.equal(variation);
_enqueue.args[0][1].ti.should.equal(params.ti);
fn.calledOnce.should.equal(true, "callback should have been called once")
});
it("should accept arguments (params, fn) when params include transaction", function () {
var params = {
ip: Math.random(),
iq: Math.random(),
ic: Math.random().toString(),
in: Math.random().toString(),
iv: Math.random().toString(),
ti: Math.random()
};
var fn = sinon.spy()
var visitor = ua();
var result = visitor.item(params, fn);
visitor._context = result._context;
result.should.eql(visitor, "should return a visitor that is identical except for the context");
result.should.be.instanceof(ua.Visitor);
result._context.should.eql(_enqueue.args[0][1], "the transaction params should be persisted as the context of the visitor clone")
_enqueue.calledOnce.should.equal(true, "#_enqueue should have been called once");
_enqueue.args[0][0].should.equal("item");
_enqueue.args[0][1].should.have.keys("ti", "ip", "iq", "ic", "in", "iv")
_enqueue.args[0][1].ip.should.equal(params.ip);
_enqueue.args[0][1].iq.should.equal(params.iq);
_enqueue.args[0][1].ic.should.equal(params.ic);
_enqueue.args[0][1].in.should.equal(params.in);
_enqueue.args[0][1].iv.should.equal(params.iv);
_enqueue.args[0][1].ti.should.equal(params.ti);
fn.calledOnce.should.equal(true, "callback should have been called once")
});
it("should accept arguments (params, fn) when chained to a transaction", function () {
var transaction = Math.random().toString();
var params = {
ip: Math.random(),
iq: Math.random(),
ic: Math.random().toString(),
in: Math.random().toString(),
iv: Math.random().toString()
};
var fn = sinon.spy()
var visitor = ua().transaction(transaction);
var result = visitor.item(params, fn);
visitor._context = result._context;
result.should.eql(visitor, "should return a visitor that is identical except for the context");
result.should.be.instanceof(ua.Visitor);
result._context.should.eql(_enqueue.args[1][1], "the transaction params should be persisted as the context of the visitor clone")
_enqueue.calledTwice.should.equal(true, "#_enqueue should have been called twice, once for the transaction");
_enqueue.args[1][0].should.equal("item");
_enqueue.args[1][1].should.have.keys("ti", "ip", "iq", "ic", "in", "iv")
_enqueue.args[1][1].ip.should.equal(params.ip);
_enqueue.args[1][1].iq.should.equal(params.iq);
_enqueue.args[1][1].ic.should.equal(params.ic);
_enqueue.args[1][1].in.should.equal(params.in);
_enqueue.args[1][1].iv.should.equal(params.iv);
_enqueue.args[1][1].ti.should.equal(transaction);
fn.calledOnce.should.equal(true, "callback should have been called once")
});
it("should allow daisy-chaining to re-use arguments", function () {
var transaction = Math.random().toString();
var price = Math.random();
var quantity = Math.random();
var sku = Math.random().toString();
var name = Math.random().toString();
var name2 = Math.random().toString();
var variation = Math.random().toString();
var fn = sinon.spy()
var visitor = ua().transaction(transaction);
var result = visitor.item(price, quantity, sku, name, variation).item({in: name2}, fn);
_enqueue.calledThrice.should.equal(true, "#_enqueue should have been called thrice, once for the transaction before");
_enqueue.args[0][0].should.equal("transaction");
_enqueue.args[1][0].should.equal(_enqueue.args[2][0]);
_enqueue.args[1][1].ti.should.equal(_enqueue.args[2][1].ti, "ti should be equal on both");
_enqueue.args[1][1].ip.should.equal(_enqueue.args[2][1].ip, "ip should be equal on both");
_enqueue.args[1][1].iq.should.equal(_enqueue.args[2][1].iq, "iq should be equal on both");
_enqueue.args[1][1].ic.should.equal(_enqueue.args[2][1].ic, "ic should be equal on both");
_enqueue.args[1][1].iv.should.equal(_enqueue.args[2][1].iv, "iv should be equal on both");
_enqueue.args[2][1].in.should.equal(name2, "name should have changed on second item");
fn.calledOnce.should.equal(true, "callback should have been called once")
});
it("should fail without transaction ID", function () {
var params = {
ip: Math.random(),
iq: Math.random(),
ic: Math.random().toString(),
in: Math.random().toString(),
iv: Math.random().toString()
};
var fn = sinon.spy()
var visitor = ua();
var result = visitor.item(params, fn);
visitor._context = result._context;
result.should.eql(visitor, "should return a visitor that is identical except for the context");
result.should.be.instanceof(ua.Visitor);
result._context.should.eql({}, "the transaction params should not be persisted")
_enqueue.called.should.equal(false, "#_enqueue should have not been called once");
fn.calledOnce.should.equal(true, "callback should have been called once");
fn.args[0][0].should.be.instanceof(Error);
fn.thisValues[0].should.equal(visitor);
});
});
});