/* globals expect */ /* globals describe */ /* globals it */ /* globals sinon */ var Rollbar = require('../src/react-native/rollbar'); var rollbarConfig = { accessToken: 'POST_CLIENT_ITEM_TOKEN', captureUncaught: true, captureUnhandledRejections: true } var rollbar = new Rollbar(rollbarConfig); describe('sendJsonPayload', function() { var uuid = 'd4c7acef55bf4c9ea95e4fe9428a8287'; before(function (done) { // In react-native environment, stub fetch() instead of XMLHttpRequest window.fetchStub = sinon.stub(window, 'fetch'); done(); }); after(function () { window.fetch.restore(); }); function stubResponse(code, err, message) { window.fetch.returns(Promise.resolve(new Response( JSON.stringify({ err: err, message: message, result: { uuid: uuid }}), { status: code, statusText: message, headers: { 'Content-Type': 'application/json' }} ))); } it('should callback with the right value on success', function(done) { stubResponse(200, 0, 'OK'); var json = JSON.stringify({foo: 'baaar'}); rollbar.sendJsonPayload(json); expect(window.fetchStub.called).to.be.ok(); expect(window.fetchStub.getCall(0).args[1].body).to.eql(json); done(); }); }); const DUMMY_TRACE_ID = 'some-trace-id'; const DUMMY_SPAN_ID = 'some-span-id'; const ValidOpenTracingTracerStub = { scope: () => { return { active: () => { return { setTag: () => { }, context: () => { return { toTraceId: () => DUMMY_TRACE_ID, toSpanId: () => DUMMY_SPAN_ID } } } } } } }; const InvalidOpenTracingTracerStub = { foo: () => { } }; function TestClientGen() { var TestClient = function() { this.transforms = []; this.predicates = []; this.notifier = { addTransform: function(t) { this.transforms.push(t); return this.notifier; }.bind(this) }; this.queue = { addPredicate: function(p) { this.predicates.push(p); return this.queue; }.bind(this) }; this.logCalls = []; var logs = 'log,debug,info,warn,warning,error,critical'.split(','); for (var i=0, len=logs.length; i < len; i++) { var fn = logs[i].slice(0); this[fn] = function(fn, item) { this.logCalls.push({func: fn, item: item}) }.bind(this, fn) } this.options = {}; this.payloadData = {}; this.configure = function(o, payloadData) { this.options = o; this.payloadData = payloadData; }; }; return TestClient; } describe('Rollbar()', function() { it('should have all of the expected methods with a real client', function(done) { var options = {}; var rollbar = new Rollbar(options); expect(rollbar).to.have.property('log'); expect(rollbar).to.have.property('debug'); expect(rollbar).to.have.property('info'); expect(rollbar).to.have.property('warn'); expect(rollbar).to.have.property('warning'); expect(rollbar).to.have.property('error'); expect(rollbar).to.have.property('critical'); done(); }); it('should have all of the expected methods', function(done) { var client = new (TestClientGen())(); var options = {}; var rollbar = new Rollbar(options, client); expect(rollbar).to.have.property('log'); expect(rollbar).to.have.property('debug'); expect(rollbar).to.have.property('info'); expect(rollbar).to.have.property('warn'); expect(rollbar).to.have.property('warning'); expect(rollbar).to.have.property('error'); expect(rollbar).to.have.property('critical'); done(); }); it ('should have some default options', function(done) { var client = new (TestClientGen())(); var options = {}; var rollbar = new Rollbar(options, client); expect(rollbar.options.scrubFields).to.contain('password'); done(); }); it ('should merge with the defaults options', function(done) { var client = new (TestClientGen())(); var options = { scrubFields: [ 'foobar' ] }; var rollbar = new Rollbar(options, client); expect(rollbar.options.scrubFields).to.contain('foobar'); expect(rollbar.options.scrubFields).to.contain('password'); done(); }); it ('should overwrite default if specified', function(done) { var client = new (TestClientGen())(); var options = { scrubFields: [ 'foobar' ], overwriteScrubFields: true, }; var rollbar = new Rollbar(options, client); expect(rollbar.options.scrubFields).to.contain('foobar'); expect(rollbar.options.scrubFields).to.not.contain('password'); done(); }); it ('should replace deprecated options', function(done) { var client = new (TestClientGen())(); var options = { hostWhiteList: ['foo'], hostBlackList: ['bar'] }; var rollbar = new Rollbar(options, client); expect(rollbar.options.hostWhiteList).to.eql(undefined); expect(rollbar.options.hostBlackList).to.eql(undefined); expect(rollbar.options.hostSafeList).to.contain('foo'); expect(rollbar.options.hostBlockList).to.contain('bar'); done(); }); it('should return a uuid when logging', function(done) { var client = new (TestClientGen())(); var options = {}; var rollbar = new Rollbar(options, client); var result = rollbar.log('a messasge', 'another one'); expect(result.uuid).to.be.ok(); done(); }); it('should package up the inputs', function(done) { var client = new (TestClientGen())(); var options = {}; var rollbar = new Rollbar(options, client); var result = rollbar.log('a message', 'another one'); var loggedItem = client.logCalls[0].item; expect(loggedItem.message).to.eql('a message'); expect(loggedItem.custom).to.be.ok(); done(); }); it('should call the client with the right method', function(done) { var client = new (TestClientGen())(); var options = {}; var rollbar = new Rollbar(options, client); var methods = 'log,debug,info,warn,warning,error,critical'.split(','); for (var i=0; i < methods.length; i++) { var msg = 'message:' + i; rollbar[methods[i]](msg); expect(client.logCalls[i].func).to.eql(methods[i]); expect(client.logCalls[i].item.message).to.eql(msg) } done(); }); it('should have a tracer if valid tracer is provided', function (done) { var options = { tracer: ValidOpenTracingTracerStub }; var rollbar = new Rollbar(options); expect(rollbar.client.tracer).to.eql(ValidOpenTracingTracerStub); done(); }); it('should not have a tracer if invalid tracer is provided', function (done) { var options = { tracer: InvalidOpenTracingTracerStub }; var rollbar = new Rollbar(options); expect(rollbar.client.tracer).to.eql(null); done(); }); }); describe('configure', function() { it('should configure client', function(done) { var client = new (TestClientGen())(); var options = { payload: { a: 42, environment: 'testtest' } }; var rollbar = new Rollbar(options, client); expect(rollbar.options.payload.environment).to.eql('testtest'); rollbar.configure({payload: {environment: 'borkbork'}}); expect(rollbar.options.payload.environment).to.eql('borkbork'); expect(client.options.payload.environment).to.eql('borkbork'); done(); }); it('should accept a second parameter and use it as the payload value', function(done) { var client = new (TestClientGen())(); var options = { payload: { a: 42, environment: 'testtest' } }; var rollbar = new Rollbar(options, client); expect(rollbar.options.payload.environment).to.eql('testtest'); rollbar.configure({somekey: 'borkbork'}, {b: 97}); expect(rollbar.options.somekey).to.eql('borkbork'); expect(rollbar.options.payload.b).to.eql(97); expect(client.payloadData.b).to.eql(97); done(); }); it('should accept a second parameter and override the payload with it', function(done) { var client = new (TestClientGen())(); var options = { payload: { a: 42, environment: 'testtest' } }; var rollbar = new Rollbar(options, client); expect(rollbar.options.payload.environment).to.eql('testtest'); rollbar.configure({somekey: 'borkbork', payload: {b: 101}}, {b: 97}); expect(rollbar.options.somekey).to.eql('borkbork'); expect(rollbar.options.payload.b).to.eql(97); expect(client.payloadData.b).to.eql(97); done(); }); it ('should replace deprecated options', function(done) { var client = new (TestClientGen())(); var options = { hostWhiteList: ['foo'], hostBlackList: ['bar'] }; var rollbar = window.rollbar = new Rollbar({ autoInstrument: false }, client); rollbar.configure(options); expect(rollbar.options.hostWhiteList).to.eql(undefined); expect(rollbar.options.hostBlackList).to.eql(undefined); expect(rollbar.options.hostSafeList).to.contain('foo'); expect(rollbar.options.hostBlockList).to.contain('bar'); done(); }); it('should store configured options', function(done) { var client = new (TestClientGen())(); var options = { captureUncaught: true, payload: { a: 42, environment: 'testtest' } }; var rollbar = new Rollbar(options, client); expect(rollbar.options._configuredOptions.payload.environment).to.eql('testtest'); expect(rollbar.options._configuredOptions.captureUncaught).to.eql(true); rollbar.configure({ captureUncaught: false, payload: {environment: 'borkbork'}}); expect(rollbar.options._configuredOptions.payload.environment).to.eql('borkbork'); expect(rollbar.options._configuredOptions.captureUncaught).to.eql(false); done(); }); }); describe('captureEvent', function() { it('should handle missing/default type and level', function(done) { var options = {}; var rollbar = new Rollbar(options); var event = rollbar.captureEvent({foo: 'bar'}); expect(event.type).to.eql('manual'); expect(event.level).to.eql('info'); expect(event.body.foo).to.eql('bar'); done(); }); it('should handle specified type and level', function(done) { var options = {}; var rollbar = new Rollbar(options); var event = rollbar.captureEvent('log', {foo: 'bar'}, 'debug'); expect(event.type).to.eql('log'); expect(event.level).to.eql('debug'); expect(event.body.foo).to.eql('bar'); done(); }); it('should handle extra args', function(done) { var options = {}; var rollbar = new Rollbar(options); var event = rollbar.captureEvent('meaningless', {foo: 'bar'}, 23); expect(event.type).to.eql('manual'); expect(event.level).to.eql('info'); expect(event.body.foo).to.eql('bar'); done(); }); }); describe('callback options', function() { beforeEach(function (done) { // In react-native environment, stub fetch() instead of XMLHttpRequest window.fetchStub = sinon.stub(window, 'fetch'); done(); }); afterEach(function () { window.fetch.restore(); }); function stubResponse(code, err, message) { var uuid = 'd4c7acef55bf4c9ea95e4fe9428a8287'; window.fetch.returns(Promise.resolve(new Response( JSON.stringify({ err: err, message: message, result: { uuid: uuid }}), { status: code, statusText: message, headers: { 'Content-Type': 'application/json' }} ))); } it('should use checkIgnore when set', function(done) { stubResponse(200, 0, 'OK'); var options = { accessToken: 'POST_CLIENT_ITEM_TOKEN', checkIgnore: function(_isUncaught, _args, _payload) { return true; } }; var rollbar = new Rollbar(options); rollbar.log('test'); // generate a payload to ignore expect(window.fetchStub.called).to.not.be.ok(); done(); }); it('should use onSendCallback when set', function(done) { stubResponse(200, 0, 'OK'); var options = { accessToken: 'POST_CLIENT_ITEM_TOKEN', onSendCallback: function(_isUncaught, _args, payload) { payload.foo = 'bar'; } }; var rollbar = new Rollbar(options); rollbar.log('test'); // generate a payload to inspect setTimeout(function() { expect(window.fetchStub.called).to.be.ok(); var body = JSON.parse(window.fetchStub.getCall(0).args[1].body); expect(body.data.foo).to.eql('bar'); done(); }, 1); }); it('should use transform when set', function(done) { stubResponse(200, 0, 'OK'); var options = { accessToken: 'POST_CLIENT_ITEM_TOKEN', transform: function(data, _item) { data.foo = 'baz'; } }; var rollbar = new Rollbar(options); rollbar.log('test'); // generate a payload to inspect setTimeout(function() { expect(window.fetchStub.called).to.be.ok(); var body = JSON.parse(window.fetchStub.getCall(0).args[1].body); expect(body.data.foo).to.eql('baz'); done(); }, 1); }); }); describe('createItem', function() { it('should handle multiple strings', function(done) { var client = new (TestClientGen())(); var options = {}; var rollbar = new Rollbar(options, client); var args = ['first', 'second']; var item = rollbar._createItem(args); expect(item.message).to.eql('first'); expect(item.custom.extraArgs['0']).to.eql('second'); done(); }); it('should handle errors', function(done) { var client = new (TestClientGen())(); var options = {}; var rollbar = new Rollbar(options, client); var args = [new Error('Whoa'), 'first', 'second']; var item = rollbar._createItem(args); expect(item.err).to.eql(args[0]); expect(item.message).to.eql('first'); expect(item.custom.extraArgs['0']).to.eql('second'); done(); }); it('should handle a callback', function(done) { var client = new (TestClientGen())(); var options = {}; var rollbar = new Rollbar(options, client); var myCallbackCalled = false; var myCallback = function() { myCallbackCalled = true; }; var args = [new Error('Whoa'), 'first', myCallback, 'second']; var item = rollbar._createItem(args); expect(item.err).to.eql(args[0]); expect(item.message).to.eql('first'); expect(item.custom.extraArgs).to.eql(['second']); expect(item.callback).to.be.ok(); item.callback(); expect(myCallbackCalled).to.be.ok(); done(); }); it('should handle arrays', function(done) { var client = new (TestClientGen())(); var options = {}; var rollbar = new Rollbar(options, client); var args = [new Error('Whoa'), 'first', [1, 2, 3], 'second']; var item = rollbar._createItem(args); expect(item.err).to.eql(args[0]); expect(item.message).to.eql('first'); expect(item.custom['0']).to.eql(1); expect(item.custom.extraArgs).to.eql(['second']); done(); }); it('should handle objects', function(done) { var client = new (TestClientGen())(); var options = {}; var rollbar = new Rollbar(options, client); var args = [new Error('Whoa'), 'first', {a: 1, b: 2}, 'second']; var item = rollbar._createItem(args); expect(item.err).to.eql(args[0]); expect(item.message).to.eql('first'); expect(item.custom.a).to.eql(1); expect(item.custom.b).to.eql(2); expect(item.custom.extraArgs).to.eql(['second']); done(); }); it('should have a timestamp', function(done) { var client = new (TestClientGen())(); var options = {}; var rollbar = new Rollbar(options, client); var args = [new Error('Whoa'), 'first', {a: 1, b: 2}, 'second']; var item = rollbar._createItem(args); var now = (new Date()).getTime(); expect(item.timestamp).to.be.within(now - 1000, now + 1000); done(); }); it('should have an uuid', function(done) { var client = new (TestClientGen())(); var options = {}; var rollbar = new Rollbar(options, client); var args = [new Error('Whoa'), 'first', {a: 1, b: 2}, 'second']; var item = rollbar._createItem(args); expect(item.uuid).to.be.ok(); var parts = item.uuid.split('-'); expect(parts.length).to.eql(5); // Type 4 UUID expect(parts[2][0]).to.eql('4'); done(); }); it('should handle dates', function(done) { var client = new (TestClientGen())(); var options = {}; var rollbar = new Rollbar(options, client); var y2k = new Date(2000, 0, 1) var args = [new Error('Whoa'), 'first', y2k, {a: 1, b: 2}, 'second']; var item = rollbar._createItem(args); expect(item.custom.extraArgs).to.eql([y2k, 'second']); done(); }); it('should handle numbers', function(done) { var client = new (TestClientGen())(); var options = {}; var rollbar = new Rollbar(options, client); var args = [new Error('Whoa'), 'first', 42, {a: 1, b: 2}, 'second']; var item = rollbar._createItem(args); expect(item.custom.extraArgs).to.eql([42, 'second']); done(); }); it('should handle domexceptions', function(done) { var client = new (TestClientGen())(); var options = {}; var rollbar = new Rollbar(options, client); if (document && document.querySelectorAll) { var e; try { document.querySelectorAll('div:foo'); } catch (ee) { e = ee } var args = [e, 'first', 42, {a: 1, b: 2}, 'second']; var item = rollbar._createItem(args); expect(item.err).to.be.ok(); } done(); }); }); describe('singleton', function() { it('should pass through the underlying client after init', function(done) { var client = new (TestClientGen())(); var options = {}; var rollbar = Rollbar.init(options, client); rollbar.log('hello 1'); Rollbar.log('hello 2'); var loggedItemDirect = client.logCalls[0].item; var loggedItemSingleton = client.logCalls[1].item; expect(loggedItemDirect.message).to.eql('hello 1'); expect(loggedItemSingleton.message).to.eql('hello 2'); done(); }); });