234 lines
6.1 KiB
JavaScript
Raw Normal View History

2025-04-24 17:03:28 +08:00
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("#send", function () {
var post;
beforeEach(function () {
post = sinon.stub(request, "post").callsArg(2);
});
afterEach(function () {
post.restore()
});
it("should immidiately return with an empty queue", function () {
var visitor = ua();
var fn = sinon.spy();
visitor.send(fn);
post.called.should.equal(false, "no request should have been sent")
fn.calledOnce.should.equal(true, "callback should have been called once")
fn.thisValues[0].should.equal(visitor, "callback should be called in the context of the visitor instance");
fn.args[0].should.eql([null, 0], "no error, no requests");
});
it("should include data in POST body", function (done) {
var paramSets = [
{first: "123"}
]
var fn = sinon.spy(function () {
fn.calledOnce.should.equal(true, "callback should have been called once")
fn.thisValues[0].should.equal(visitor, "callback should be called in the context of the visitor instance");
fn.args[0].should.eql([null, 1], "no error, 1 requests");
post.callCount.should.equal(paramSets.length, "each param set should have been POSTed");
for (var i = 0; i < paramSets.length; i++) {
var params = paramSets[i];
var args = post.args[i];
var parsedUrl = url.parse(args[0]);
Math.random(); // I have absolutely no idea why it fails unless there was some processing to be done after url.parse…
(parsedUrl.protocol + "//" + parsedUrl.host).should.equal(config.hostname);
args[1].body.should.equal(qs.stringify(params));
}
done();
});
var visitor = ua();
visitor._queue.push.apply(visitor._queue, paramSets);
visitor.send(fn);
});
it("should send individual requests when batchting is false", function(done) {
var paramSets = [
{first: Math.random()},
{second: Math.random()},
{third: Math.random()}
]
var fn = sinon.spy(function () {
fn.calledOnce.should.equal(true, "callback should have been called once")
fn.thisValues[0].should.equal(visitor, "callback should be called in the context of the visitor instance");
fn.args[0].should.eql([null, 3], "no error, 3 requests");
done();
});
var visitor = ua({enableBatching:false});
visitor._queue.push.apply(visitor._queue, paramSets)
visitor.send(fn);
});
describe("#batching is true", function() {
it("should send request to collect path when only one payload", function(done) {
var paramSets = [
{first: Math.random()}
]
var fn = sinon.spy(function () {
fn.args[0].should.eql([null, 1], "no error, 1 requests");
var args = post.args[0];
var parsedUrl = url.parse(args[0]);
parsedUrl.pathname.should.eql(config.path);
done();
});
var visitor = ua({enableBatching:true});
visitor._queue.push.apply(visitor._queue, paramSets)
visitor.send(fn);
});
it("should send request to batch path when more than one payload sent", function(done) {
var paramSets = [
{first: Math.random()},
{second: Math.random()},
{third: Math.random()}
]
var fn = sinon.spy(function () {
fn.args[0].should.eql([null, 1], "no error, 1 requests");
var args = post.args[0];
var parsedUrl = url.parse(args[0]);
parsedUrl.pathname.should.eql(config.batchPath);
done();
});
var visitor = ua({enableBatching:true});
visitor._queue.push.apply(visitor._queue, paramSets)
visitor.send(fn);
});
it("should batch data in Post form", function(done) {
var paramSets = [
{first: Math.random()},
{second: Math.random()},
{third: Math.random()}
]
var fn = sinon.spy(function () {
fn.calledOnce.should.equal(true, "callback should have been called once")
fn.thisValues[0].should.equal(visitor, "callback should be called in the context of the visitor instance");
fn.args[0].should.eql([null, 1], "no error, 1 requests");
var args = post.args[0];
var params = paramSets;
var formParams = args[1].body.split("\n");
formParams.should.have.lengthOf(3);
formParams[0].should.equal(qs.stringify(params[0]));
done();
});
var visitor = ua({enableBatching:true});
visitor._queue.push.apply(visitor._queue, paramSets)
visitor.send(fn);
})
it("should batch data based on batchSize", function(done) {
var paramSets = [
{first: Math.random()},
{second: Math.random()},
{third: Math.random()}
]
var fn = sinon.spy(function () {
fn.calledOnce.should.equal(true, "callback should have been called once")
fn.thisValues[0].should.equal(visitor, "callback should be called in the context of the visitor instance");
fn.args[0].should.eql([null, 2], "no error, 2 requests");
var body = post.args[0][1].body;
body.split("\n").should.have.lengthOf(2);
done();
});
var visitor = ua({enableBatching:true, batchSize: 2});
visitor._queue.push.apply(visitor._queue, paramSets)
visitor.send(fn);
});
});
it("should add custom headers to request header", function (done) {
var fn = sinon.spy(function () {
fn.calledOnce.should.equal(true, "callback should have been called once");
fn.thisValues[0].should.equal(visitor, "callback should be called in the context of the visitor instance");
post.calledOnce.should.equal(true, "request should have been POSTed");
var parsedUrl = url.parse(post.args[0][0]);
var options = post.args[0][1];
(parsedUrl.protocol + "//" + parsedUrl.host).should.equal(config.hostname);
options.should.have.keys("headers","body")
options.headers.should.have.key("User-Agent");
options.headers["User-Agent"].should.equal("Test User Agent");
done();
});
var visitor = ua({
headers: {'User-Agent': 'Test User Agent'}
});
visitor._queue.push({});
visitor.send(fn);
});
})
});