Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add redux-beacon middleware for Matomo Tag Manager
- Loading branch information
1 parent
c7de7a8
commit 30472a2
Showing
8 changed files
with
154 additions
and
37 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
{ | ||
"src/**/*.{js,jsx,ts,tsx}": ["prettier-standard", "git add"] | ||
"src/**/*.{js,jsx,ts,tsx}": ["prettier-standard", "npm run lint", "git add"] | ||
} |
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 |
---|---|---|
|
@@ -13,5 +13,6 @@ module.exports = { | |
statements: 100 | ||
} | ||
}, | ||
testEnvironment: 'node', | ||
testRegex: '.*\\.(test|spec)\\.(t|j)sx?$' | ||
} |
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,12 +1,11 @@ | ||
import debug from 'debug' | ||
import Module from './index' | ||
import MatomoTagManager, { IMatomoTagManagerOptions } from './' | ||
|
||
jest.mock('debug') | ||
const mockedDebug = (debug as any) as jest.Mock<typeof debug> | ||
|
||
test('should send debug message on start', () => { | ||
const mockLogger = jest.fn() | ||
mockedDebug.mockReturnValue(mockLogger as any) | ||
new Module().start() | ||
expect(mockLogger).toBeCalled() | ||
describe('index', () => { | ||
it('exports the MatomoTagManager', () => { | ||
expect(MatomoTagManager).toBeDefined() | ||
}) | ||
it('exports the IMatomoTagManagerOptions', () => { | ||
const options: IMatomoTagManagerOptions = {} | ||
expect(options).toBeDefined() | ||
}) | ||
}) |
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,17 +1,4 @@ | ||
import debugFactory, { IDebugger } from 'debug' | ||
import MatomoTagManager from './matomo-tag-manager' | ||
export default MatomoTagManager | ||
|
||
/** A documented example module */ | ||
export default class Module { | ||
/** The logger used in the module */ | ||
private readonly logger: IDebugger | ||
|
||
/** Creates a new Module */ | ||
constructor () { | ||
this.logger = debugFactory('module-ts-template') | ||
} | ||
|
||
/** Starts the module */ | ||
start () { | ||
this.logger('Starting module') | ||
} | ||
} | ||
export { IMatomoTagManagerOptions } from './matomo-tag-manager' |
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 |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import MatomoTagManager from './matomo-tag-manager' | ||
|
||
describe('matomo-tag-manager', () => { | ||
describe('happy path', () => { | ||
it('pushes events to _mtm by default', () => { | ||
const push = jest.fn() | ||
// @ts-ignore | ||
global.window = { _mtm: { push } } | ||
|
||
const matomoTagManager = MatomoTagManager() | ||
const events = [ | ||
{ | ||
event: 'testEvent' | ||
} | ||
] | ||
|
||
matomoTagManager(events) | ||
|
||
expect(push).toHaveBeenCalledWith(events[0]) | ||
}) | ||
|
||
it('pushes events to a custom set datalayer', () => { | ||
const push = jest.fn() | ||
// @ts-ignore | ||
global.window = { custom: { push } } | ||
|
||
const matomoTagManager = MatomoTagManager({ dataLayerName: 'custom' }) | ||
const events = [ | ||
{ | ||
event: 'testEvent' | ||
} | ||
] | ||
|
||
matomoTagManager(events) | ||
|
||
expect(push).toHaveBeenCalledWith(events[0]) | ||
}) | ||
}) | ||
|
||
describe('sad path', () => { | ||
it('does not do anything if window is not defined', () => { | ||
// @ts-ignore | ||
global.window = undefined | ||
const matomoTagManager = MatomoTagManager() | ||
expect(matomoTagManager).not.toThrow() | ||
}) | ||
|
||
it('throws an error if the dataLayer is not defined', () => { | ||
// @ts-ignore | ||
global.window = {} | ||
const matomoTagManager = MatomoTagManager() | ||
expect(matomoTagManager).toThrow() | ||
}) | ||
|
||
it('throws an error if the dataLayer does not have a push method', () => { | ||
// @ts-ignore | ||
global.window = { _mtm: {} } | ||
const matomoTagManager = MatomoTagManager() | ||
expect(matomoTagManager).toThrow() | ||
}) | ||
|
||
it('does not push events that are not objects', () => { | ||
const push = jest.fn() | ||
// @ts-ignore | ||
global.window = { _mtm: { push } } | ||
|
||
const matomoTagManager = MatomoTagManager() | ||
// tslint:disable-next-line:no-empty | ||
const events = [() => {}] | ||
|
||
matomoTagManager(events) | ||
|
||
expect(push).not.toHaveBeenCalled() | ||
}) | ||
}) | ||
}) |
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 |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { Target } from 'redux-beacon' | ||
|
||
/** Options for the redux-beacon Matomo tag manager */ | ||
export interface IMatomoTagManagerOptions { | ||
/** The dataLayer used for pushing events and variables. By default '_mtm' */ | ||
dataLayerName?: string | ||
} | ||
|
||
const MatomoTagManager = ({ | ||
dataLayerName = '_mtm' | ||
}: IMatomoTagManagerOptions = {}): Target => (events: object[]) => { | ||
// tslint:disable-next-line:strict-type-predicates | ||
if (typeof window === 'undefined') { | ||
return | ||
} | ||
|
||
if ( | ||
!(window as any)[dataLayerName] || | ||
typeof (window as any)[dataLayerName].push !== 'function' | ||
) { | ||
throw new Error( | ||
`redux-beacon error: window.${dataLayerName} is not defined. Have you forgotten to include Matomo Tag Manager and dataLayer?` | ||
) | ||
} | ||
|
||
events.forEach(event => { | ||
// tslint:disable-next-line:strict-type-predicates | ||
if (typeof event === 'object') { | ||
// tslint:disable-next-line:semicolon | ||
;(window as any)[dataLayerName].push(event) | ||
} | ||
}) | ||
} | ||
|
||
export default MatomoTagManager |