Skip to content

Commit eff5ddd

Browse files
committed
add support for Product List Viewed events
1 parent 5527ffd commit eff5ddd

File tree

7 files changed

+371
-2
lines changed

7 files changed

+371
-2
lines changed

packages/browser-destinations/destinations/algolia-plugins/src/algoliaInsights/generated-types.ts

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/destination-actions/src/destinations/algolia-insights/__tests__/__snapshots__/snapshot.test.ts.snap

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,41 @@ Object {
155155
}
156156
`;
157157

158+
exports[`Testing snapshot for actions-algolia-insights destination: productListViewedEvents action - all fields 1`] = `
159+
Object {
160+
"events": Array [
161+
Object {
162+
"eventName": "rV6HQ[S7QuqZWEj%HvC",
163+
"eventType": "click",
164+
"index": "rV6HQ[S7QuqZWEj%HvC",
165+
"objectIDs": Array [
166+
"rV6HQ[S7QuqZWEj%HvC",
167+
],
168+
"queryID": "rV6HQ[S7QuqZWEj%HvC",
169+
"testType": "rV6HQ[S7QuqZWEj%HvC",
170+
"timestamp": null,
171+
"userToken": "rV6HQ[S7QuqZWEj%HvC",
172+
},
173+
],
174+
}
175+
`;
176+
177+
exports[`Testing snapshot for actions-algolia-insights destination: productListViewedEvents action - required fields 1`] = `
178+
Object {
179+
"events": Array [
180+
Object {
181+
"eventName": "Product List Viewed",
182+
"eventType": "view",
183+
"index": "rV6HQ[S7QuqZWEj%HvC",
184+
"objectIDs": Array [
185+
"rV6HQ[S7QuqZWEj%HvC",
186+
],
187+
"userToken": "rV6HQ[S7QuqZWEj%HvC",
188+
},
189+
],
190+
}
191+
`;
192+
158193
exports[`Testing snapshot for actions-algolia-insights destination: productViewedEvents action - all fields 1`] = `
159194
Object {
160195
"events": Array [

packages/destination-actions/src/destinations/algolia-insights/index.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { AlgoliaApiPermissions, algoliaApiPermissionsUrl } from './algolia-insig
1111
import { productAddedEvents } from './productAddedEvents'
1212

1313
import { productListFilteredEvents, productListFilteredPresets } from './productListFilteredEvents'
14+
import { productListViewedEvents, productListViewedPresets } from './productListViewedEvents'
1415

1516
export const ALGOLIA_INSIGHTS_USER_AGENT = 'algolia-segment-action-destination: 0.1'
1617

@@ -67,14 +68,16 @@ const destination: DestinationDefinition<Settings> = {
6768
purchasePreset,
6869
addToCartPreset,
6970
productViewedPresets,
70-
productListFilteredPresets
71+
productListFilteredPresets,
72+
productListViewedPresets
7173
],
7274
actions: {
7375
productClickedEvents,
7476
conversionEvents,
7577
productViewedEvents,
7678
productAddedEvents,
77-
productListFilteredEvents
79+
productListFilteredEvents,
80+
productListViewedEvents
7881
}
7982
}
8083

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`Testing snapshot for AlgoliaInsights's productListViewedEvents destination action: all fields 1`] = `
4+
Object {
5+
"events": Array [
6+
Object {
7+
"eventName": "lx7Lx",
8+
"eventType": "view",
9+
"index": "lx7Lx",
10+
"objectIDs": Array [
11+
"lx7Lx",
12+
],
13+
"queryID": "lx7Lx",
14+
"testType": "lx7Lx",
15+
"timestamp": null,
16+
"userToken": "lx7Lx",
17+
},
18+
],
19+
}
20+
`;
21+
22+
exports[`Testing snapshot for AlgoliaInsights's productListViewedEvents destination action: required fields 1`] = `
23+
Object {
24+
"events": Array [
25+
Object {
26+
"eventName": "Product List Viewed",
27+
"eventType": "view",
28+
"index": "lx7Lx",
29+
"objectIDs": Array [
30+
"lx7Lx",
31+
],
32+
"timestamp": 1674843786677,
33+
"userToken": "lx7Lx",
34+
},
35+
],
36+
}
37+
`;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import nock from 'nock'
2+
import { createTestEvent, createTestIntegration, SegmentEvent } from '@segment/actions-core'
3+
import Destination, { ALGOLIA_INSIGHTS_USER_AGENT } from '../../index'
4+
import { AlgoliaProductViewedEvent, BaseAlgoliaInsightsURL } from '../../algolia-insight-api'
5+
6+
const testDestination = createTestIntegration(Destination)
7+
8+
const algoliaDestinationActionSettings = {
9+
appId: 'algolia-application-id',
10+
apiKey: 'algolia-api-key'
11+
}
12+
const testAlgoliaDestination = async (event: SegmentEvent): Promise<AlgoliaProductViewedEvent> => {
13+
nock(BaseAlgoliaInsightsURL).post('/1/events').reply(200, {})
14+
const segmentEvent = {
15+
event: { ...event },
16+
settings: algoliaDestinationActionSettings,
17+
useDefaultMappings: true
18+
}
19+
const actionResponse = await testDestination.testAction('productListViewedEvents', segmentEvent)
20+
const actionRequest = actionResponse[0].request
21+
22+
expect(actionResponse.length).toBe(1)
23+
expect(actionRequest.headers.get('X-Algolia-Application-Id')).toBe(algoliaDestinationActionSettings.appId)
24+
expect(actionRequest.headers.get('X-Algolia-API-Key')).toBe(algoliaDestinationActionSettings.apiKey)
25+
expect(actionRequest.headers.get('X-Algolia-Agent')).toBe(ALGOLIA_INSIGHTS_USER_AGENT)
26+
27+
const rawBody = await actionRequest.text()
28+
return JSON.parse(rawBody)['events'][0]
29+
}
30+
31+
describe('AlgoliaInsights.productListViewedEvents', () => {
32+
it('should submit click on track "Product List Viewed" event', async () => {
33+
const event = createTestEvent({
34+
type: 'track',
35+
event: 'Product List Viewed',
36+
properties: {
37+
query_id: '1234',
38+
search_index: 'fashion_1',
39+
products: [
40+
{ product_id: '9876', name: 'foo', price: 10 },
41+
{ product_id: '5432', category: 'bar' }
42+
]
43+
}
44+
})
45+
const algoliaEvent = await testAlgoliaDestination(event)
46+
47+
expect(algoliaEvent.eventName).toBe('Product List Viewed')
48+
expect(algoliaEvent.eventType).toBe('view')
49+
expect(algoliaEvent.index).toBe(event.properties?.search_index)
50+
expect(algoliaEvent.userToken).toBe(event.userId)
51+
expect(algoliaEvent.objectIDs).toEqual(['9876', '5432'])
52+
})
53+
54+
it('should pass timestamp if present', async () => {
55+
const event = createTestEvent({
56+
type: 'track',
57+
event: 'Product List Viewed',
58+
properties: {
59+
search_index: 'fashion_1',
60+
products: [
61+
{ product_id: '9876', name: 'foo', price: 10 },
62+
{ product_id: '5432', category: 'bar' }
63+
]
64+
},
65+
userId: undefined
66+
})
67+
const algoliaEvent = await testAlgoliaDestination(event)
68+
expect(algoliaEvent.timestamp).toBe(new Date(event.timestamp as string).valueOf())
69+
})
70+
71+
it('should pass queryId if present', async () => {
72+
const event = createTestEvent({
73+
type: 'track',
74+
event: 'Product List Viewed',
75+
properties: {
76+
query_id: '1234',
77+
search_index: 'fashion_1',
78+
products: [
79+
{ product_id: '9876', name: 'foo', price: 10 },
80+
{ product_id: '5432', category: 'bar' }
81+
]
82+
},
83+
userId: undefined
84+
})
85+
const algoliaEvent = await testAlgoliaDestination(event)
86+
expect(algoliaEvent.queryID).toBe(event.properties?.query_id)
87+
})
88+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { createTestEvent, createTestIntegration } from '@segment/actions-core'
2+
import { generateTestData } from '../../../../lib/test-data'
3+
import destination from '../../index'
4+
import nock from 'nock'
5+
6+
const testDestination = createTestIntegration(destination)
7+
const actionSlug = 'productListViewedEvents'
8+
const destinationSlug = 'AlgoliaInsights'
9+
const seedName = `${destinationSlug}#${actionSlug}`
10+
11+
describe(`Testing snapshot for ${destinationSlug}'s ${actionSlug} destination action:`, () => {
12+
it('required fields', async () => {
13+
const action = destination.actions[actionSlug]
14+
const [eventData, settingsData] = generateTestData(seedName, destination, action, true)
15+
16+
nock(/.*/).persist().get(/.*/).reply(200)
17+
nock(/.*/).persist().post(/.*/).reply(200)
18+
nock(/.*/).persist().put(/.*/).reply(200)
19+
20+
const event = createTestEvent({
21+
timestamp: new Date('2023-01-27T18:23:06.677Z').toISOString(),
22+
properties: eventData
23+
})
24+
25+
const responses = await testDestination.testAction(actionSlug, {
26+
useDefaultMappings: true,
27+
event: event,
28+
mapping: event.properties,
29+
settings: settingsData,
30+
auth: undefined
31+
})
32+
33+
const request = responses[0].request
34+
const rawBody = await request.text()
35+
36+
try {
37+
const json = JSON.parse(rawBody)
38+
expect(json).toMatchSnapshot()
39+
return
40+
} catch (err) {
41+
expect(rawBody).toMatchSnapshot()
42+
}
43+
44+
expect(request.headers).toMatchSnapshot()
45+
})
46+
47+
it('all fields', async () => {
48+
const action = destination.actions[actionSlug]
49+
const [eventData, settingsData] = generateTestData(seedName, destination, action, false)
50+
51+
nock(/.*/).persist().get(/.*/).reply(200)
52+
nock(/.*/).persist().post(/.*/).reply(200)
53+
nock(/.*/).persist().put(/.*/).reply(200)
54+
55+
const event = createTestEvent({
56+
timestamp: new Date('2023-01-27T18:23:06.677Z').toISOString(),
57+
properties: eventData
58+
})
59+
60+
const responses = await testDestination.testAction(actionSlug, {
61+
useDefaultMappings: true,
62+
event: event,
63+
mapping: event.properties,
64+
settings: settingsData,
65+
auth: undefined
66+
})
67+
68+
const request = responses[0].request
69+
const rawBody = await request.text()
70+
71+
try {
72+
const json = JSON.parse(rawBody)
73+
expect(json).toMatchSnapshot()
74+
return
75+
} catch (err) {
76+
expect(rawBody).toMatchSnapshot()
77+
}
78+
})
79+
})

0 commit comments

Comments
 (0)