diff --git a/packages/codebytes/src/__tests__/codebyte-test.tsx b/packages/codebytes/src/__tests__/codebyte-test.tsx index 4dfe66c0b..a1d6aedb8 100644 --- a/packages/codebytes/src/__tests__/codebyte-test.tsx +++ b/packages/codebytes/src/__tests__/codebyte-test.tsx @@ -2,14 +2,12 @@ import './mocks'; import { setupRtl } from '@codecademy/gamut-tests'; import userEvent from '@testing-library/user-event'; -import { encode } from 'js-base64'; import React from 'react'; import { CodeByteEditor } from '..'; import { helloWorld, validLanguages } from '../consts'; import { trackClick } from '../helpers'; import { trackUserImpression } from '../libs/eventTracking'; -import { CodeByteEditorProps } from '../types'; const mockEditorTestId = 'mock-editor-test-id'; @@ -38,31 +36,6 @@ jest.mock('../MonacoEditor', () => ({ const renderWrapper = setupRtl(CodeByteEditor, {}); -type RenderWrapperWithProps = CodeByteEditorProps & { mode?: string }; - -const renderWrapperWith = ({ mode, ...rest }: RenderWrapperWithProps) => { - const url = new URL(window.location.href); - - const { text, language } = rest; - if (text) { - url.searchParams.set('text', encode(text)); - } - if (language) { - url.searchParams.set('lang', language); - } - url.searchParams.set('client-name', 'forum'); - url.searchParams.set( - 'page', - 'https://discuss.codecademy.com/some-interesting/post' - ); - if (mode) { - url.searchParams.set('mode', mode); - } - window.history.replaceState({}, '', url.toString()); - - return renderWrapper(rest); -}; - describe('CodeBytes', () => { const initialUrl = window.location.href; @@ -154,11 +127,12 @@ describe('CodeBytes', () => { expect(trackClick).toHaveBeenCalledWith('lang_select', undefined); }); - it('triggers trackClick for the first edit in view mode', () => { + it('triggers trackClick for the first edit', () => { const testString = 'original-value'; const { view } = renderWrapper({ text: testString, language: 'javascript', + trackFirstEdit: true, }); const editor = view.getByTestId(mockEditorTestId); @@ -167,24 +141,14 @@ describe('CodeBytes', () => { expect(trackClick).toHaveBeenCalledWith('edit', undefined); }); - it('triggers trackUserImpression for view mode', () => { - renderWrapperWith({ - text: 'some-value', - language: 'javascript', - }); - - expect(trackUserImpression).toHaveBeenCalledWith({ - page_name: 'forum', - context: 'https://discuss.codecademy.com/some-interesting/post', - target: 'codebyte', - }); - }); - - it('triggers trackUserImpression for compose mode', () => { - renderWrapperWith({ + it('triggers trackUserImpression', () => { + renderWrapper({ text: 'some-value', language: 'javascript', - mode: 'compose', + trackingData: { + page_name: 'forum_compose', + context: 'https://discuss.codecademy.com/some-interesting/post', + }, }); expect(trackUserImpression).toHaveBeenCalledWith({ diff --git a/packages/codebytes/src/__tests__/helpers-test.tsx b/packages/codebytes/src/__tests__/helpers-test.tsx index 7bd1410b2..ffaad23fa 100644 --- a/packages/codebytes/src/__tests__/helpers-test.tsx +++ b/packages/codebytes/src/__tests__/helpers-test.tsx @@ -1,6 +1,4 @@ -import { encode } from 'js-base64'; - -import { CodebytesParams, getOptions, trackClick } from '../helpers'; +import { trackClick } from '../helpers'; import { trackUserClick } from '../libs/eventTracking'; jest.mock('../libs/eventTracking'); @@ -8,46 +6,6 @@ jest.mock('../libs/eventTracking'); const initialUrl = window.location.href; const resetCodebytesParams = () => window.history.replaceState(null, '', initialUrl); -type SetCodebytesParamsProps = Record; -const setCodebytesParams = (params: SetCodebytesParamsProps) => { - if (params.text) { - params.text = encode(params.text); - } - - const url = new URL(window.location.href); - Object.entries(params).forEach(([key, value]) => { - url.searchParams.set(key, value); - }); - - window.history.replaceState({}, '', url.toString()); -}; - -describe('getOptions', () => { - afterEach(() => { - resetCodebytesParams(); - }); - - it('parses props out of the window locations', () => { - const text = ` - const msg = 'Sup?'; - console.log(msg); - `.trim(); - setCodebytesParams({ - lang: 'javascript', - text, - 'copy-mode': '', - 'client-name': 'forum', - page: 'https://discuss.codecademy.com/some-interesting/post', - mode: 'compose', - }); - - expect(getOptions()).toEqual({ - clientName: 'forum', - parentPage: 'https://discuss.codecademy.com/some-interesting/post', - renderMode: 'compose', - }); - }); -}); describe('trackClick', () => { afterEach(() => { @@ -55,66 +13,26 @@ describe('trackClick', () => { (trackUserClick as any).mockReset(); }); - it('proxies to trackUserClick setting the page_name, context, and target', () => { + it('tracks user click when tracking data is provided', () => { const target = 'foobar'; - setCodebytesParams({ - lang: 'javascript', - text: ` - const msg = 'Sup?'; - console.log(msg); - `.trim(), - 'copy-mode': '', - 'client-name': 'forum', - page: 'https://discuss.codecademy.com/some-interesting/post', - mode: '', - }); - trackClick(target); - expect(trackUserClick).toHaveBeenCalledWith({ + const trackingData = { page_name: 'forum', context: 'https://discuss.codecademy.com/some-interesting/post', target, - }); - }); + }; - it('defaults the client name to "Unknown"', () => { - const target = 'foobar'; - setCodebytesParams({ - lang: 'javascript', - text: ` - const msg = 'Sup?'; - console.log(msg); - `.trim(), - 'copy-mode': '', - 'client-name': '', - page: 'https://discuss.codecademy.com/some-interesting/post', - mode: '', - }); - trackClick(target); + trackClick(target, trackingData); expect(trackUserClick).toHaveBeenCalledWith({ - page_name: 'Unknown', + page_name: 'forum', context: 'https://discuss.codecademy.com/some-interesting/post', target, }); }); - it('embeds the render mode into the page_name', () => { - const mode = 'compose'; + it('tracks user click when tracking data is not provided', () => { const target = 'foobar'; - setCodebytesParams({ - lang: 'javascript', - text: ` - const msg = 'Sup?'; - console.log(msg); - `.trim(), - 'copy-mode': '', - 'client-name': 'forum', - page: 'https://discuss.codecademy.com/some-interesting/post', - mode, - }); trackClick(target); expect(trackUserClick).toHaveBeenCalledWith({ - page_name: `forum_${mode}`, - context: 'https://discuss.codecademy.com/some-interesting/post', target, }); }); diff --git a/packages/codebytes/src/codeByteEditor.tsx b/packages/codebytes/src/codeByteEditor.tsx index f669ea8dc..d2c040271 100644 --- a/packages/codebytes/src/codeByteEditor.tsx +++ b/packages/codebytes/src/codeByteEditor.tsx @@ -7,7 +7,7 @@ import React, { useEffect, useState } from 'react'; import { helloWorld, LanguageOption } from './consts'; import { Editor } from './editor'; -import { getOptions, trackClick } from './helpers'; +import { trackClick } from './helpers'; import { LanguageSelection } from './languageSelection'; import { trackUserImpression } from './libs/eventTracking'; import { CodeByteEditorProps } from './types'; @@ -33,6 +33,7 @@ export const CodeByteEditor: React.FC = ({ onLanguageChange, onCopy, trackingData, + trackFirstEdit = false, ...rest }) => { const getInitialText = () => { @@ -47,17 +48,12 @@ export const CodeByteEditor: React.FC = ({ const [hasBeenEdited, setHasBeenEdited] = useState(false); useEffect(() => { - const options = getOptions(); - const page_name = options.renderMode - ? `${options.clientName}_${options.renderMode}` - : options.clientName; - trackUserImpression({ - page_name, - context: options.parentPage, + page_name: trackingData?.page_name ?? 'Unknown', + context: trackingData?.context ?? document.referrer, target: 'codebyte', }); - }, []); + }, [trackingData]); return ( @@ -80,8 +76,7 @@ export const CodeByteEditor: React.FC = ({ onChange={(newText: string) => { setText(newText); onEdit?.(newText, language); - const { renderMode } = getOptions(); - if (!renderMode && hasBeenEdited === false) { + if (trackFirstEdit && hasBeenEdited === false) { setHasBeenEdited(true); trackClick('edit', trackingData); } diff --git a/packages/codebytes/src/helpers/index.ts b/packages/codebytes/src/helpers/index.ts index 25a690d71..be2dff8c9 100644 --- a/packages/codebytes/src/helpers/index.ts +++ b/packages/codebytes/src/helpers/index.ts @@ -2,51 +2,7 @@ import { UserClickData } from '@codecademy/tracking'; import { trackUserClick } from '../libs/eventTracking'; -export type CodebyteOptions = { - clientName: string; - parentPage: string; - renderMode: string; -}; - -export enum CodebytesParams { - Language = 'lang', - Text = 'text', - CopyMode = 'copy-mode', - ClientName = 'client-name', - Page = 'page', - Mode = 'mode', -} - -export const getOptions = (): CodebyteOptions => { - const currentUri = new URL(window.location.href); - - return { - clientName: - currentUri.searchParams.get(CodebytesParams.ClientName) || 'Unknown', - parentPage: - currentUri.searchParams.get(CodebytesParams.Page) || document.referrer, - renderMode: currentUri.searchParams.get(CodebytesParams.Mode) || '', - }; -}; - export const trackClick = ( target: string, trackingData?: Omit -) => { - if (trackingData) { - return trackUserClick({ - ...trackingData, - target, - }); - } - const options = getOptions(); - const page_name = options.renderMode - ? `${options.clientName}_${options.renderMode}` - : options.clientName; - - trackUserClick({ - page_name, - context: options.parentPage, - target, - }); -}; +) => trackUserClick({ ...trackingData, target }); diff --git a/packages/codebytes/src/index.ts b/packages/codebytes/src/index.ts index f7d8a3173..4ea0734c5 100644 --- a/packages/codebytes/src/index.ts +++ b/packages/codebytes/src/index.ts @@ -1,2 +1,3 @@ export * from './codeByteEditor'; export * from './consts'; +export * from './types'; diff --git a/packages/codebytes/src/types.ts b/packages/codebytes/src/types.ts index beb2f0ac1..111dc3504 100644 --- a/packages/codebytes/src/types.ts +++ b/packages/codebytes/src/types.ts @@ -16,4 +16,5 @@ export interface CodeByteEditorProps onEdit?: CodebytesChangeHandler; onLanguageChange?: CodebytesChangeHandler; trackingData?: Omit; + trackFirstEdit?: boolean; }