Skip to content

Commit

Permalink
Add support for registering callbacks when cloning
Browse files Browse the repository at this point in the history
This allows plugins to make changes to any new clones, which may be
necessary if they are monkey patching clients
  • Loading branch information
imjoehaines committed Dec 2, 2022
1 parent 6d1f9b6 commit 0d827d8
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 0 deletions.
6 changes: 6 additions & 0 deletions packages/core/lib/clone-client.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const assign = require('./es-utils/assign')

const onCloneCallbacks = []

module.exports = (client) => {
const clone = new client.Client({}, {}, [], client._notifier)

Expand All @@ -25,5 +27,9 @@ module.exports = (client) => {
clone._delivery = client._delivery
clone._sessionDelegate = client._sessionDelegate

onCloneCallbacks.forEach(callback => { callback(clone) })

return clone
}

module.exports.registerCallback = callback => { onCloneCallbacks.push(callback) }
87 changes: 87 additions & 0 deletions packages/core/test/lib/clone-client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,4 +287,91 @@ describe('@bugsnag/core/lib/clone-client', () => {
expect(cloned._sessionDelegate).toBe(original._sessionDelegate)
})
})

describe('registerCallback', () => {
it('allows registering callbacks that are called when a client is cloned', () => {
const callback1 = jest.fn()
const callback2 = jest.fn()
const callback3 = jest.fn()

clone.registerCallback(callback1)
clone.registerCallback(callback2)
clone.registerCallback(callback3)

const original = new Client({ apiKey })

expect(callback1).not.toHaveBeenCalled()
expect(callback2).not.toHaveBeenCalled()
expect(callback3).not.toHaveBeenCalled()

clone(original)

expect(callback1).toHaveBeenCalledTimes(1)
expect(callback2).toHaveBeenCalledTimes(1)
expect(callback3).toHaveBeenCalledTimes(1)

clone(original)

expect(callback1).toHaveBeenCalledTimes(2)
expect(callback2).toHaveBeenCalledTimes(2)
expect(callback3).toHaveBeenCalledTimes(2)
})

it('passes the clone to the callbacks', () => {
const callback1 = jest.fn()
const callback2 = jest.fn()
const callback3 = jest.fn()

clone.registerCallback(callback1)
clone.registerCallback(callback2)
clone.registerCallback(callback3)

const original = new Client({ apiKey })

expect(callback1).not.toHaveBeenCalled()
expect(callback2).not.toHaveBeenCalled()
expect(callback3).not.toHaveBeenCalled()

const cloned = clone(original)

expect(callback1).toHaveBeenCalledWith(cloned)
expect(callback2).toHaveBeenCalledWith(cloned)
expect(callback3).toHaveBeenCalledWith(cloned)

const cloned2 = clone(original)

expect(callback1).toHaveBeenCalledWith(cloned2)
expect(callback2).toHaveBeenCalledWith(cloned2)
expect(callback3).toHaveBeenCalledWith(cloned2)

// the callbacks should not be called with the original client
expect(callback1).not.toHaveBeenCalledWith(original)
expect(callback2).not.toHaveBeenCalledWith(original)
expect(callback3).not.toHaveBeenCalledWith(original)
})

it('calls callbacks in the order they are registered', () => {
const order: string[] = []

const callback1 = () => { order.push('callback1') }
const callback2 = () => { order.push('callback2') }
const callback3 = () => { order.push('callback3') }

clone.registerCallback(callback1)
clone.registerCallback(callback2)
clone.registerCallback(callback3)

const original = new Client({ apiKey })

expect(order).toEqual([])

clone(original)

expect(order).toEqual(['callback1', 'callback2', 'callback3'])

clone(original)

expect(order).toEqual(['callback1', 'callback2', 'callback3', 'callback1', 'callback2', 'callback3'])
})
})
})

0 comments on commit 0d827d8

Please sign in to comment.