Skip to content

Commit

Permalink
add dispatch unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
silesky committed Sep 23, 2022
1 parent 2b64998 commit 862dd37
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 2 deletions.
103 changes: 103 additions & 0 deletions packages/core/src/analytics/__tests__/dispatch.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// import { CoreContext } from '../context'
// import { CoreSegmentEvent, Callback } from '../events/interfaces'

const isOnline = jest.fn().mockReturnValue(true)
const isOffline = jest.fn().mockReturnValue(false)

jest.mock('../../connection', () => ({
isOnline,
isOffline,
}))
const fetcher = jest.fn()
jest.mock('node-fetch', () => fetcher)

const invokeCallback = jest.fn()

jest.mock('../../callback', () => ({
invokeCallback: invokeCallback,
}))

import { EventQueue } from '../../queue/event-queue'
import { Emitter } from '../../emitter'
import { dispatch, getDelayTimeout } from '../dispatch'
import { PriorityQueue } from '../../priority-queue'

let emitter!: Emitter
let queue!: EventQueue
const dispatchSingleSpy = jest.spyOn(EventQueue.prototype, 'dispatchSingle')
const dispatchSpy = jest.spyOn(EventQueue.prototype, 'dispatch')

beforeEach(() => {
queue = new EventQueue(new PriorityQueue(4, []))
emitter = new Emitter()
})

afterEach(() => {
jest.resetAllMocks()
})

describe('Dispatch', () => {
it('should return ctx if offline and retryQueue is false', async () => {
isOnline.mockReturnValue(false)
isOffline.mockReturnValue(true)

const ctx = await dispatch({ type: 'screen' }, queue, emitter, {
retryQueue: false,
})
expect(ctx.event.type).toBe('screen')
const called = Boolean(
dispatchSingleSpy.mock.calls.length || dispatchSpy.mock.calls.length
)
expect(called).toBeFalsy()
})

it('should not dispatch if offline and retryQueue is true', async () => {
isOnline.mockReturnValue(false)
isOffline.mockReturnValue(true)

await dispatch({ type: 'screen' }, queue, emitter, {
retryQueue: true,
})
const called = Boolean(
dispatchSingleSpy.mock.calls.length || dispatchSpy.mock.calls.length
)
expect(called).toBeTruthy()
})

it('should call dispatchSingle with ctx if queue is empty', async () => {
queue.isEmpty = jest.fn().mockReturnValue(true)
await dispatch({ type: 'screen' }, queue, emitter)
expect(dispatchSingleSpy).toBeCalledWith(
expect.objectContaining({ event: { type: 'screen' } })
)
expect(dispatchSpy).not.toBeCalled()
})
it('should call dispatch with ctx if queue is empty', async () => {
queue.isEmpty = jest.fn().mockReturnValue(false)
await dispatch({ type: 'screen' }, queue, emitter)
expect(dispatchSpy).toBeCalledWith(
expect.objectContaining({ event: { type: 'screen' } })
)
expect(dispatchSingleSpy).not.toBeCalled()
})
it('should not invoke callback if no callback is passed', async () => {
await dispatch({ type: 'screen' }, queue, emitter)
expect(invokeCallback).not.toBeCalled()
})
it('should call "invokeCallback" if callback is passed', async () => {
const cb = jest.fn()
await dispatch({ type: 'screen' }, queue, emitter, { callback: cb })
expect(invokeCallback).toBeCalled()
})
})

describe('getDelayTimeout', () => {
it('should work as expected', () => {
const aShortTimeAgo = Date.now() - 200
expect(Math.round(getDelayTimeout(aShortTimeAgo, 500))).toBe(300)
})
it('should have a sensible default', () => {
const aShortTimeAgo = Date.now() - 200
expect(Math.round(getDelayTimeout(aShortTimeAgo))).toBe(100)
})
})
11 changes: 9 additions & 2 deletions packages/core/src/analytics/dispatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ type DispatchOptions = {
retryQueue?: boolean
}

/* The amount of time in ms to wait before invoking the callback. */
export const getDelayTimeout = (
startTimeInEpochMS: number,
timeoutInMS?: number
) => {
const elapsedTime = Date.now() - startTimeInEpochMS
return Math.max((timeoutInMS ?? 300) - elapsedTime, 0)
}
/**
* Push an event into the dispatch queue and invoke any callbacks.
*
Expand Down Expand Up @@ -40,14 +48,13 @@ export async function dispatch(
} else {
dispatched = await queue.dispatch(ctx)
}
const elapsedTime = Date.now() - startTime
const timeoutInMs = options?.timeout

if (options?.callback) {
dispatched = await invokeCallback(
dispatched,
options.callback,
Math.max((timeoutInMs ?? 300) - elapsedTime, 0),
getDelayTimeout(startTime, timeoutInMs),
timeoutInMs
)
}
Expand Down

0 comments on commit 862dd37

Please sign in to comment.