diff options
author | Phil Hughes <me@iamphill.com> | 2017-05-05 20:51:38 +0300 |
---|---|---|
committer | Phil Hughes <me@iamphill.com> | 2017-05-05 20:51:38 +0300 |
commit | b81535351023a3b19870ce052d8c3d0563391686 (patch) | |
tree | 0332d42df3b6fb80e752b47121f6a0f4ddb0cf92 /spec | |
parent | c9b246334753c47bef1111bdbfc1a45a1c9b0cfe (diff) | |
parent | e5a7ed3ac36aaa1045353e589dae98a29ca72f1e (diff) |
Merge branch 'add-sentry-js-again-with-vue' into 'master'
Add sentry JS
See merge request !6764
Diffstat (limited to 'spec')
-rw-r--r-- | spec/features/raven_js_spec.rb | 23 | ||||
-rw-r--r-- | spec/javascripts/raven/index_spec.js | 42 | ||||
-rw-r--r-- | spec/javascripts/raven/raven_config_spec.js | 276 |
3 files changed, 341 insertions, 0 deletions
diff --git a/spec/features/raven_js_spec.rb b/spec/features/raven_js_spec.rb new file mode 100644 index 00000000000..e8fa49c18cb --- /dev/null +++ b/spec/features/raven_js_spec.rb @@ -0,0 +1,23 @@ +require 'spec_helper' + +feature 'RavenJS', :feature, :js do + let(:raven_path) { '/raven.bundle.js' } + + it 'should not load raven if sentry is disabled' do + visit new_user_session_path + + expect(has_requested_raven).to eq(false) + end + + it 'should load raven if sentry is enabled' do + stub_application_setting(clientside_sentry_dsn: 'https://key@domain.com/id', clientside_sentry_enabled: true) + + visit new_user_session_path + + expect(has_requested_raven).to eq(true) + end + + def has_requested_raven + page.driver.network_traffic.one? {|request| request.url.end_with?(raven_path)} + end +end diff --git a/spec/javascripts/raven/index_spec.js b/spec/javascripts/raven/index_spec.js new file mode 100644 index 00000000000..b5662cd0331 --- /dev/null +++ b/spec/javascripts/raven/index_spec.js @@ -0,0 +1,42 @@ +import RavenConfig from '~/raven/raven_config'; +import index from '~/raven/index'; + +describe('RavenConfig options', () => { + let sentryDsn; + let currentUserId; + let gitlabUrl; + let isProduction; + let indexReturnValue; + + beforeEach(() => { + sentryDsn = 'sentryDsn'; + currentUserId = 'currentUserId'; + gitlabUrl = 'gitlabUrl'; + isProduction = 'isProduction'; + + window.gon = { + sentry_dsn: sentryDsn, + current_user_id: currentUserId, + gitlab_url: gitlabUrl, + }; + + process.env.NODE_ENV = isProduction; + + spyOn(RavenConfig, 'init'); + + indexReturnValue = index(); + }); + + it('should init with .sentryDsn, .currentUserId, .whitelistUrls and .isProduction', () => { + expect(RavenConfig.init).toHaveBeenCalledWith({ + sentryDsn, + currentUserId, + whitelistUrls: [gitlabUrl], + isProduction, + }); + }); + + it('should return RavenConfig', () => { + expect(indexReturnValue).toBe(RavenConfig); + }); +}); diff --git a/spec/javascripts/raven/raven_config_spec.js b/spec/javascripts/raven/raven_config_spec.js new file mode 100644 index 00000000000..a2d720760fc --- /dev/null +++ b/spec/javascripts/raven/raven_config_spec.js @@ -0,0 +1,276 @@ +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); + }); + }); +}); |