-
Notifications
You must be signed in to change notification settings - Fork 253
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
(plugin-electron-client-state-persistence) Add unit tests for disable…
…d NativeClient
- Loading branch information
1 parent
61ce62d
commit d37abc8
Showing
2 changed files
with
129 additions
and
131 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,114 +1,94 @@ | ||
import Client from '@bugsnag/core/client' | ||
import { plugin } from '../' | ||
import { Breadcrumb, Logger } from '@bugsnag/core' | ||
import { Breadcrumb } from '@bugsnag/core' | ||
import stateManager from '@bugsnag/plugin-electron-client-state-manager' | ||
import { makeClientForPlugin } from '@bugsnag/electron-test-helpers' | ||
|
||
const schema = { | ||
enabledErrorTypes: { | ||
defaultValue: () => ({ | ||
unhandledExceptions: true, | ||
unhandledRejections: true, | ||
nativeCrashes: true | ||
}), | ||
allowPartialObject: true, | ||
validate: value => true | ||
} | ||
} | ||
|
||
function makeClient (NativeClient: object, config?: object) { | ||
return makeClientForPlugin({ plugins: [stateManager, plugin(NativeClient)], schema, config }) | ||
} | ||
|
||
describe('plugin: electron client sync', () => { | ||
it('updates context', done => { | ||
const c = new Client({ | ||
apiKey: 'api_key', | ||
plugins: [ | ||
stateManager, | ||
plugin({ | ||
updateContext: (update: any) => { | ||
expect(update).toBe('1234') | ||
done() | ||
} | ||
}) | ||
] | ||
const { client } = makeClient({ | ||
updateContext: (update: any) => { | ||
expect(update).toBe('1234') | ||
done() | ||
} | ||
}) | ||
c.setContext('1234') | ||
client.setContext('1234') | ||
}) | ||
|
||
it('updates metadata', done => { | ||
const c = new Client({ | ||
apiKey: 'api_key', | ||
plugins: [ | ||
stateManager, | ||
plugin({ | ||
updateMetadata: (key: string, updates: any) => { | ||
expect(key).toBe('widget') | ||
expect(updates).toEqual({ | ||
id: '14', | ||
count: 340 | ||
}) | ||
done() | ||
} | ||
const { client } = makeClient({ | ||
updateMetadata: (key: string, updates: any) => { | ||
expect(key).toBe('widget') | ||
expect(updates).toEqual({ | ||
id: '14', | ||
count: 340 | ||
}) | ||
] | ||
done() | ||
} | ||
}) | ||
c.addMetadata('widget', { id: '14', count: 340 }) | ||
expect(c.getMetadata('widget')).toEqual({ id: '14', count: 340 }) | ||
client.addMetadata('widget', { id: '14', count: 340 }) | ||
expect(client.getMetadata('widget')).toEqual({ id: '14', count: 340 }) | ||
}) | ||
|
||
it('clears metadata', done => { | ||
const c = new Client({ | ||
apiKey: 'api_key', | ||
plugins: [ | ||
stateManager, | ||
plugin({ | ||
addMetadata: () => {}, | ||
clearMetadata: () => {} | ||
}) | ||
] | ||
const { client } = makeClient({ | ||
addMetadata: () => {}, | ||
clearMetadata: () => {} | ||
}) | ||
c.addMetadata('widget', { id: '14', count: 340 }) | ||
expect(c.getMetadata('widget')).toEqual({ id: '14', count: 340 }) | ||
c.clearMetadata('widget', 'count') | ||
expect(c.getMetadata('widget', 'count')).toBeUndefined() | ||
c.clearMetadata('widget') | ||
expect(c.getMetadata('widget')).toBeUndefined() | ||
client.addMetadata('widget', { id: '14', count: 340 }) | ||
expect(client.getMetadata('widget')).toEqual({ id: '14', count: 340 }) | ||
client.clearMetadata('widget', 'count') | ||
expect(client.getMetadata('widget', 'count')).toBeUndefined() | ||
client.clearMetadata('widget') | ||
expect(client.getMetadata('widget')).toBeUndefined() | ||
done() | ||
}) | ||
|
||
it('updates user', done => { | ||
const c = new Client({ | ||
apiKey: 'api_key', | ||
plugins: [ | ||
stateManager, | ||
plugin({ | ||
updateUser: (id: string, email: string, name: string) => { | ||
expect(id).toBe('1234') | ||
expect(name).toBe('Ben') | ||
expect(email).toBe('[email protected]') | ||
done() | ||
} | ||
}) | ||
] | ||
const { client } = makeClient({ | ||
updateUser: (id: string, email: string, name: string) => { | ||
expect(id).toBe('1234') | ||
expect(name).toBe('Ben') | ||
expect(email).toBe('[email protected]') | ||
done() | ||
} | ||
}) | ||
c.setUser('1234', '[email protected]', 'Ben') | ||
expect(c.getUser()).toEqual({ id: '1234', name: 'Ben', email: '[email protected]' }) | ||
client.setUser('1234', '[email protected]', 'Ben') | ||
expect(client.getUser()).toEqual({ id: '1234', name: 'Ben', email: '[email protected]' }) | ||
}) | ||
|
||
it('syncs breadcrumbs', (done) => { | ||
const c = new Client({ | ||
apiKey: 'api_key', | ||
plugins: [ | ||
stateManager, | ||
plugin({ | ||
leaveBreadcrumb: ({ message, metadata, type, timestamp }: Breadcrumb) => { | ||
expect(message).toBe('Spin') | ||
expect(type).toBe('manual') | ||
expect(metadata).toEqual({ direction: 'ccw', deg: '90' }) | ||
expect(timestamp).toBeTruthy() | ||
done() | ||
} | ||
}) | ||
] | ||
const { client } = makeClient({ | ||
leaveBreadcrumb: ({ message, metadata, type, timestamp }: Breadcrumb) => { | ||
expect(message).toBe('Spin') | ||
expect(type).toBe('manual') | ||
expect(metadata).toEqual({ direction: 'ccw', deg: '90' }) | ||
expect(timestamp).toBeTruthy() | ||
done() | ||
} | ||
}) | ||
c.leaveBreadcrumb('Spin', { direction: 'ccw', deg: '90' }) | ||
client.leaveBreadcrumb('Spin', { direction: 'ccw', deg: '90' }) | ||
}) | ||
|
||
it('does not sync breadcrumbs that are cancelled by an onBreadcrumb callback', () => { | ||
const NativeClient = { leaveBreadcrumb: jest.fn() } | ||
|
||
const client = new Client({ | ||
apiKey: 'api_key', | ||
plugins: [ | ||
stateManager, | ||
plugin(NativeClient) | ||
] | ||
}) | ||
const { client } = makeClient(NativeClient) | ||
|
||
client.addOnBreadcrumb(breadcrumb => { | ||
if (breadcrumb.message === 'skip me') { | ||
|
@@ -138,13 +118,7 @@ describe('plugin: electron client sync', () => { | |
it('updates feature flags', () => { | ||
const updateFeatureFlags = jest.fn() | ||
|
||
const client = new Client({ | ||
apiKey: 'api_key', | ||
plugins: [ | ||
stateManager, | ||
plugin({ updateFeatureFlags }) | ||
] | ||
}) | ||
const { client } = makeClient({ updateFeatureFlags }) | ||
|
||
client.addFeatureFlag('a', 'b') | ||
client.addFeatureFlags([{ name: 'c', variant: null }, { name: 'd', variant: 'e' }]) | ||
|
@@ -163,13 +137,7 @@ describe('plugin: electron client sync', () => { | |
it('clears a single feature flag', () => { | ||
const updateFeatureFlags = jest.fn() | ||
|
||
const client = new Client({ | ||
apiKey: 'api_key', | ||
plugins: [ | ||
stateManager, | ||
plugin({ updateFeatureFlags }) | ||
] | ||
}) | ||
const { client } = makeClient({ updateFeatureFlags }) | ||
|
||
client.addFeatureFlag('a', 'b') | ||
client.addFeatureFlags([{ name: 'c', variant: null }, { name: 'd', variant: 'e' }]) | ||
|
@@ -193,13 +161,7 @@ describe('plugin: electron client sync', () => { | |
it('clears all feature flags', () => { | ||
const updateFeatureFlags = jest.fn() | ||
|
||
const client = new Client({ | ||
apiKey: 'api_key', | ||
plugins: [ | ||
stateManager, | ||
plugin({ updateFeatureFlags }) | ||
] | ||
}) | ||
const { client } = makeClient({ updateFeatureFlags }) | ||
|
||
client.addFeatureFlag('a', 'b') | ||
client.addFeatureFlags([{ name: 'c', variant: null }, { name: 'd', variant: 'e' }]) | ||
|
@@ -217,81 +179,116 @@ describe('plugin: electron client sync', () => { | |
expect(updateFeatureFlags).toHaveBeenNthCalledWith(3, []) | ||
}) | ||
|
||
function loggingClient (NativeClient: object): [Client, Logger] { | ||
const logger = { | ||
debug: jest.fn(), | ||
warn: jest.fn(), | ||
info: jest.fn(), | ||
error: jest.fn() | ||
} | ||
const client = new Client({ | ||
apiKey: 'api_key', | ||
plugins: [stateManager, plugin(NativeClient)], | ||
logger | ||
}) | ||
return [client, logger] | ||
} | ||
|
||
it('logs errors thrown from updating context', () => { | ||
const [client, logger] = loggingClient({ | ||
// const [client, logger] = loggingClient({ | ||
// updateContext: () => { throw new Error('wrong thing') } | ||
// }) | ||
const { client } = makeClient({ | ||
updateContext: () => { throw new Error('wrong thing') } | ||
}) | ||
|
||
client.setContext('some invalid context') | ||
const error = logger.error as jest.Mock<Function> | ||
const error = client._logger.error as jest.Mock<Function> | ||
expect(error.mock.calls.length).toBe(1) | ||
expect(error.mock.calls[0][0].message).toContain('wrong thing') | ||
}) | ||
|
||
it('logs errors thrown from adding breadcrumbs', () => { | ||
const [client, logger] = loggingClient({ | ||
const { client } = makeClient({ | ||
leaveBreadcrumb: () => { throw new Error('wrong thing') } | ||
}) | ||
client.leaveBreadcrumb('Spin', { direction: 'ccw', deg: '90' }) | ||
const error = logger.error as jest.Mock<Function> | ||
const error = client._logger.error as jest.Mock<Function> | ||
expect(error.mock.calls.length).toBe(1) | ||
expect(error.mock.calls[0][0].message).toContain('wrong thing') | ||
}) | ||
|
||
it('logs errors thrown from adding metadata', () => { | ||
const [client, logger] = loggingClient({ | ||
const { client } = makeClient({ | ||
updateMetadata: () => { throw new Error('wrong thing') } | ||
}) | ||
client.addMetadata('widget', { id: '14', count: 340 }) | ||
const error = logger.error as jest.Mock<Function> | ||
const error = client._logger.error as jest.Mock<Function> | ||
expect(error.mock.calls.length).toBe(1) | ||
expect(error.mock.calls[0][0].message).toContain('wrong thing') | ||
}) | ||
|
||
it('logs errors thrown from clearing metadata', () => { | ||
const [client, logger] = loggingClient({ | ||
const { client } = makeClient({ | ||
updateMetadata: () => { throw new Error('wrong thing') } | ||
}) | ||
client.clearMetadata('widget') | ||
const error = logger.error as jest.Mock<Function> | ||
const error = client._logger.error as jest.Mock<Function> | ||
expect(error.mock.calls.length).toBe(1) | ||
expect(error.mock.calls[0][0].message).toContain('wrong thing') | ||
}) | ||
|
||
it('logs errors thrown from updating user info', () => { | ||
const [client, logger] = loggingClient({ | ||
const { client } = makeClient({ | ||
updateUser: () => { throw new Error('wrong thing') } | ||
}) | ||
client.setUser('404', '[email protected]', undefined) | ||
const error = logger.error as jest.Mock<Function> | ||
const error = client._logger.error as jest.Mock<Function> | ||
expect(error.mock.calls.length).toBe(1) | ||
expect(error.mock.calls[0][0].message).toContain('wrong thing') | ||
}) | ||
|
||
it('logs errors thrown from updating feature flags', () => { | ||
const [client, logger] = loggingClient({ | ||
const { client } = makeClient({ | ||
updateFeatureFlags: () => { throw new Error('wrong thing') } | ||
}) | ||
|
||
client.addFeatureFlag('a', 'b') | ||
|
||
const error = logger.error as jest.Mock<Function> | ||
const error = client._logger.error as jest.Mock<Function> | ||
|
||
expect(error.mock.calls.length).toBe(1) | ||
expect(error.mock.calls[0][0].message).toContain('wrong thing') | ||
}) | ||
|
||
it('does not sync data to the NativeClient if enabledErrorTypes.nativeCrashes is disabled', () => { | ||
const NativeClient = { | ||
leaveBreadcrumb: jest.fn(), | ||
updateUser: jest.fn(), | ||
updateContext: jest.fn(), | ||
updateMetadata: jest.fn(), | ||
updateFeatureFlags: jest.fn() | ||
} | ||
|
||
const { client } = makeClient(NativeClient, { enabledErrorTypes: { nativeCrashes: false } }) | ||
client.leaveBreadcrumb('no sync') | ||
client.setUser('1234', '[email protected]', 'Ben') | ||
client.setContext('no sync') | ||
client.addMetadata('no sync', { id: '14', count: 340 }) | ||
client.addFeatureFlag('no', 'sync') | ||
|
||
expect(NativeClient.leaveBreadcrumb).not.toHaveBeenCalled() | ||
expect(NativeClient.updateUser).not.toHaveBeenCalled() | ||
expect(NativeClient.updateContext).not.toHaveBeenCalled() | ||
expect(NativeClient.updateMetadata).not.toHaveBeenCalled() | ||
expect(NativeClient.updateFeatureFlags).not.toHaveBeenCalled() | ||
}) | ||
|
||
it('does not sync data to the NativeClient if autoDetectErrors is disabled', () => { | ||
const NativeClient = { | ||
leaveBreadcrumb: jest.fn(), | ||
updateUser: jest.fn(), | ||
updateContext: jest.fn(), | ||
updateMetadata: jest.fn(), | ||
updateFeatureFlags: jest.fn() | ||
} | ||
|
||
const { client } = makeClient(NativeClient, { autoDetectErrors: false }) | ||
client.leaveBreadcrumb('no sync') | ||
client.setUser('1234', '[email protected]', 'Ben') | ||
client.setContext('no sync') | ||
client.addMetadata('no sync', { id: '14', count: 340 }) | ||
client.addFeatureFlag('no', 'sync') | ||
|
||
expect(NativeClient.leaveBreadcrumb).not.toHaveBeenCalled() | ||
expect(NativeClient.updateUser).not.toHaveBeenCalled() | ||
expect(NativeClient.updateContext).not.toHaveBeenCalled() | ||
expect(NativeClient.updateMetadata).not.toHaveBeenCalled() | ||
expect(NativeClient.updateFeatureFlags).not.toHaveBeenCalled() | ||
}) | ||
}) |