Skip to content

Commit

Permalink
feat(headless): quick view event for insight use case made an Insight…
Browse files Browse the repository at this point in the history
…Panel.ItemAction (#4136)

## [SFINT-5581](https://coveord.atlassian.net/browse/SFINT-5581)

- Quick view event sent in the insight use case updated to be an
`InsightPanel.ItemClick` event according to the latest schemas of the
`@coveo/relay-event-types` library.
- Unit tests added.

[SFINT-5581]:
https://coveord.atlassian.net/browse/SFINT-5581?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
  • Loading branch information
mmitiche authored Jul 8, 2024
1 parent e4e1626 commit eaef9fa
Show file tree
Hide file tree
Showing 7 changed files with 240 additions and 10 deletions.
12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/headless/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"dependencies": {
"@coveo/bueno": "0.45.9",
"@coveo/relay": "0.7.7",
"@coveo/relay-event-types": "8.0.0",
"@coveo/relay-event-types": "9.2.0",
"@microsoft/fetch-event-source": "2.0.1",
"@reduxjs/toolkit": "2.2.4",
"abab": "2.0.6",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {HtmlRequestOptions} from '../../../api/search/html/html-request';
import {configuration} from '../../../app/common-reducers';
import {insightInterfaceReducer as insightInterface} from '../../../features/insight-interface/insight-interface-slice';
import {buildInsightResultPreviewRequest} from '../../../features/insight-search/insight-result-preview-request-builder';
import {logDocumentQuickview} from '../../../features/result-preview/result-preview-analytics-actions';
import {logDocumentQuickview} from '../../../features/result-preview/result-preview-insight-analytics-actions';
import {resultPreviewReducer as resultPreview} from '../../../features/result-preview/result-preview-slice';
import {InsightAppState} from '../../../state/insight-app-state';
import {
Expand All @@ -19,7 +19,9 @@ import {
} from './headless-insight-quickview';

jest.mock('../../core/quickview/headless-core-quickview');
jest.mock('../../../features/result-preview/result-preview-analytics-actions');
jest.mock(
'../../../features/result-preview/result-preview-insight-analytics-actions'
);
jest.mock(
'../../../features/insight-search/insight-result-preview-request-builder'
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
buildInsightResultPreviewRequest,
StateNeededByInsightHtmlEndpoint,
} from '../../../features/insight-search/insight-result-preview-request-builder';
import {logDocumentQuickview} from '../../../features/result-preview/result-preview-analytics-actions';
import {logDocumentQuickview} from '../../../features/result-preview/result-preview-insight-analytics-actions';
import {resultPreviewReducer as resultPreview} from '../../../features/result-preview/result-preview-slice';
import {loadReducerError} from '../../../utils/errors';
import {Controller} from '../../controller/headless-controller';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`#logDocumentQuickview when analyticsMode is \`next\` should call relay.emit properly 1`] = `
[
"InsightPanel.ItemAction",
{
"action": "preview",
"context": {
"caseNumber": "5678",
"targetId": "1234",
"targetType": "Case",
},
"itemMetadata": {
"author": "example author",
"title": "example documentTitle",
"uniqueFieldName": "permanentid",
"uniqueFieldValue": "example contentIDValue",
"url": "example documentUri",
},
"position": 1,
"searchUid": "example searchUid",
},
]
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import {createRelay} from '@coveo/relay';
import {InsightEngine} from '../../app/insight-engine/insight-engine';
import {ThunkExtraArguments} from '../../app/thunk-extra-arguments';
import {buildMockInsightEngine} from '../../test/mock-engine-v2';
import {buildMockInsightState} from '../../test/mock-insight-state';
import {buildMockRaw} from '../../test/mock-raw';
import {buildMockResult} from '../../test/mock-result';
import {buildMockSearchResponse} from '../../test/mock-search-response';
import {buildMockSearchState} from '../../test/mock-search-state';
import {clearMicrotaskQueue} from '../../test/unit-test-utils';
import {getConfigurationInitialState} from '../configuration/configuration-state';
import {logDocumentQuickview} from './result-preview-insight-analytics-actions';

jest.mock('@coveo/relay');
jest.mock('coveo.analytics');

const mockLogDocumentQuickview = jest.fn();
const emit = jest.fn();

jest.mock('coveo.analytics', () => {
const mockCoveoInsightClient = jest.fn(() => ({
disable: () => {},
logDocumentQuickview: mockLogDocumentQuickview,
}));

return {
CoveoInsightClient: mockCoveoInsightClient,
history: {HistoryStore: jest.fn()},
};
});

jest.mocked(createRelay).mockReturnValue({
emit,
getMeta: jest.fn(),
on: jest.fn(),
off: jest.fn(),
updateConfig: jest.fn(),
clearStorage: jest.fn(),
version: 'foo',
});

const exampleSubject = 'example subject';
const exampleDescription = 'example description';
const exampleCaseId = '1234';
const exampleCaseNumber = '5678';
const caseContextState = {
caseContext: {
Case_Subject: exampleSubject,
Case_Description: exampleDescription,
},
caseId: exampleCaseId,
caseNumber: exampleCaseNumber,
};

const expectedDocumentInfo = {
queryPipeline: '',
documentUri: 'example documentUri',
documentUriHash: 'example documentUriHash',
collectionName: 'example collectionName',
sourceName: 'example sourceName',
documentPosition: 1,
documentTitle: 'example documentTitle',
documentUrl: 'example documentUrl',
rankingModifier: 'example rankingModifier',
documentAuthor: 'example author',
};

const expectedDocumentIdentifier = {
contentIDKey: 'permanentid',
contentIDValue: 'example contentIDValue',
};

const resultParams = {
title: 'example documentTitle',
uri: 'example documentUri',
printableUri: 'printable-uri',
clickUri: 'example documentUrl',
uniqueId: 'unique-id',
excerpt: 'excerpt',
firstSentences: 'first-sentences',
flags: 'flags',
rankingModifier: 'example rankingModifier',
raw: buildMockRaw({
author: 'example author',
urihash: 'example documentUriHash',
source: 'example sourceName',
collection: 'example collectionName',
permanentid: 'example contentIDValue',
}),
};

const testResult = buildMockResult(resultParams);

describe('#logDocumentQuickview', () => {
let engine: InsightEngine;
const searchState = buildMockSearchState({
results: [testResult],
response: buildMockSearchResponse({
searchUid: 'example searchUid',
}),
});

afterEach(() => {
jest.clearAllMocks();
});

describe('when analyticsMode is `legacy`', () => {
beforeEach(() => {
engine = buildMockInsightEngine(
buildMockInsightState({
search: searchState,
configuration: {
...getConfigurationInitialState(),
analytics: {
...getConfigurationInitialState().analytics,
analyticsMode: 'legacy',
},
},
})
);
});

it('should call coveo.analytics.logDocumentQuickview properly', async () => {
await logDocumentQuickview(testResult)()(
engine.dispatch,
() => engine.state,
{} as ThunkExtraArguments
);
await clearMicrotaskQueue();

expect(mockLogDocumentQuickview).toHaveBeenCalledTimes(1);
expect(mockLogDocumentQuickview.mock.calls[0][0]).toStrictEqual(
expectedDocumentInfo
);
expect(mockLogDocumentQuickview.mock.calls[0][1]).toStrictEqual(
expectedDocumentIdentifier
);
});
});

describe('when analyticsMode is `next`', () => {
beforeEach(() => {
engine = buildMockInsightEngine(
buildMockInsightState({
search: searchState,
configuration: {
...getConfigurationInitialState(),
analytics: {
...getConfigurationInitialState().analytics,
analyticsMode: 'next',
},
},
insightCaseContext: caseContextState,
})
);
});

it('should call relay.emit properly', async () => {
await logDocumentQuickview(testResult)()(
engine.dispatch,
() => engine.state,
{} as ThunkExtraArguments
);
await clearMicrotaskQueue();

expect(emit).toHaveBeenCalledTimes(1);
expect(emit.mock.calls[0]).toMatchSnapshot();
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {InsightPanel} from '@coveo/relay-event-types';
import {Result} from '../../api/search/search/result';
import {
ClickAction,
analyticsEventItemMetadata,
documentIdentifier,
makeInsightAnalyticsActionFactory,
partialDocumentInformation,
validateResultPayload,
} from '../analytics/analytics-utils';
import {analyticsEventCaseContext} from '../analytics/insight-analytics-utils';

export const logDocumentQuickview = (result: Result): ClickAction => {
return makeInsightAnalyticsActionFactory('')({
prefix: 'analytics/resultPreview/open',
__legacy__getBuilder: (client, state) => {
validateResultPayload(result);
const info = partialDocumentInformation(result, state);
const id = documentIdentifier(result);
client.logDocumentQuickview(info, id);
},
analyticsType: 'InsightPanel.ItemAction',
analyticsPayloadBuilder: (state): InsightPanel.ItemAction => {
const information = partialDocumentInformation(result, state);
return {
action: 'preview',
itemMetadata: analyticsEventItemMetadata(result, state),
position: information.documentPosition,
searchUid: state.search?.response.searchUid || '',
context: analyticsEventCaseContext(state),
};
},
});
};

0 comments on commit eaef9fa

Please sign in to comment.