import Raven from 'raven-js'; import RavenConfig from '~/raven/raven_config'; describe('RavenConfig', () => { describe('IGNORE_ERRORS', () => { it('should be an array of strings', () => { const areStrings = RavenConfig.IGNORE_ERRORS.every(error => typeof error === 'string'); expect(areStrings).toBe(true); }); }); describe('IGNORE_URLS', () => { it('should be an array of regexps', () => { const areRegExps = RavenConfig.IGNORE_URLS.every(url => url instanceof RegExp); expect(areRegExps).toBe(true); }); }); describe('SAMPLE_RATE', () => { it('should be a finite number', () => { expect(typeof RavenConfig.SAMPLE_RATE).toEqual('number'); }); }); describe('init', () => { let options; beforeEach(() => { options = { sentryDsn: '//sentryDsn', ravenAssetUrl: '//ravenAssetUrl', currentUserId: 1, whitelistUrls: ['//gitlabUrl'], isProduction: true, }; spyOn(RavenConfig, 'configure'); spyOn(RavenConfig, 'bindRavenErrors'); spyOn(RavenConfig, 'setUser'); RavenConfig.init(options); }); it('should set the options property', () => { expect(RavenConfig.options).toEqual(options); }); it('should call the configure method', () => { expect(RavenConfig.configure).toHaveBeenCalled(); }); it('should call the error bindings method', () => { expect(RavenConfig.bindRavenErrors).toHaveBeenCalled(); }); it('should call setUser', () => { expect(RavenConfig.setUser).toHaveBeenCalled(); }); it('should not call setUser if there is no current user ID', () => { RavenConfig.setUser.calls.reset(); RavenConfig.init({ sentryDsn: '//sentryDsn', ravenAssetUrl: '//ravenAssetUrl', currentUserId: undefined, whitelistUrls: ['//gitlabUrl'], isProduction: true, }); expect(RavenConfig.setUser).not.toHaveBeenCalled(); }); }); describe('configure', () => { let options; let raven; let ravenConfig; beforeEach(() => { options = { sentryDsn: '//sentryDsn', whitelistUrls: ['//gitlabUrl'], isProduction: true, }; ravenConfig = jasmine.createSpyObj('ravenConfig', ['shouldSendSample']); raven = jasmine.createSpyObj('raven', ['install']); spyOn(Raven, 'config').and.returnValue(raven); ravenConfig.options = options; ravenConfig.IGNORE_ERRORS = 'ignore_errors'; ravenConfig.IGNORE_URLS = 'ignore_urls'; RavenConfig.configure.call(ravenConfig); }); it('should call Raven.config', () => { expect(Raven.config).toHaveBeenCalledWith(options.sentryDsn, { whitelistUrls: options.whitelistUrls, environment: 'production', ignoreErrors: ravenConfig.IGNORE_ERRORS, ignoreUrls: ravenConfig.IGNORE_URLS, shouldSendCallback: jasmine.any(Function), }); }); it('should call Raven.install', () => { expect(raven.install).toHaveBeenCalled(); }); it('should set .environment to development if isProduction is false', () => { ravenConfig.options.isProduction = false; RavenConfig.configure.call(ravenConfig); expect(Raven.config).toHaveBeenCalledWith(options.sentryDsn, { whitelistUrls: options.whitelistUrls, environment: 'development', ignoreErrors: ravenConfig.IGNORE_ERRORS, ignoreUrls: ravenConfig.IGNORE_URLS, shouldSendCallback: jasmine.any(Function), }); }); }); describe('setUser', () => { let ravenConfig; beforeEach(() => { ravenConfig = { options: { currentUserId: 1 } }; spyOn(Raven, 'setUserContext'); RavenConfig.setUser.call(ravenConfig); }); it('should call .setUserContext', function () { expect(Raven.setUserContext).toHaveBeenCalledWith({ id: ravenConfig.options.currentUserId, }); }); }); describe('bindRavenErrors', () => { let $document; let $; beforeEach(() => { $document = jasmine.createSpyObj('$document', ['on']); $ = jasmine.createSpy('$').and.returnValue($document); window.$ = $; RavenConfig.bindRavenErrors(); }); it('should call .on', function () { expect($document.on).toHaveBeenCalledWith('ajaxError.raven', RavenConfig.handleRavenErrors); }); }); describe('handleRavenErrors', () => { let event; let req; let config; let err; beforeEach(() => { event = {}; req = { status: 'status', responseText: 'responseText', statusText: 'statusText' }; config = { type: 'type', url: 'url', data: 'data' }; err = {}; spyOn(Raven, 'captureMessage'); RavenConfig.handleRavenErrors(event, req, config, err); }); it('should call Raven.captureMessage', () => { expect(Raven.captureMessage).toHaveBeenCalledWith(err, { extra: { type: config.type, url: config.url, data: config.data, status: req.status, response: req.responseText, error: err, event, }, }); }); describe('if no err is provided', () => { beforeEach(() => { Raven.captureMessage.calls.reset(); RavenConfig.handleRavenErrors(event, req, config); }); it('should use req.statusText as the error value', () => { expect(Raven.captureMessage).toHaveBeenCalledWith(req.statusText, { extra: { type: config.type, url: config.url, data: config.data, status: req.status, response: req.responseText, error: req.statusText, event, }, }); }); }); describe('if no req.responseText is provided', () => { beforeEach(() => { req.responseText = undefined; Raven.captureMessage.calls.reset(); RavenConfig.handleRavenErrors(event, req, config, err); }); it('should use `Unknown response text` as the response', () => { expect(Raven.captureMessage).toHaveBeenCalledWith(err, { extra: { type: config.type, url: config.url, data: config.data, status: req.status, response: 'Unknown response text', error: err, event, }, }); }); }); }); describe('shouldSendSample', () => { let randomNumber; beforeEach(() => { RavenConfig.SAMPLE_RATE = 50; spyOn(Math, 'random').and.callFake(() => randomNumber); }); it('should call Math.random', () => { RavenConfig.shouldSendSample(); expect(Math.random).toHaveBeenCalled(); }); it('should return true if the sample rate is greater than the random number * 100', () => { randomNumber = 0.1; expect(RavenConfig.shouldSendSample()).toBe(true); }); it('should return false if the sample rate is less than the random number * 100', () => { randomNumber = 0.9; expect(RavenConfig.shouldSendSample()).toBe(false); }); it('should return true if the sample rate is equal to the random number * 100', () => { randomNumber = 0.5; expect(RavenConfig.shouldSendSample()).toBe(true); }); }); });