@simplybusiness/services 0.8.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/dist/cjs/mocks/eventDefinitions.js +39 -0
- package/dist/cjs/mocks/eventDefinitions.js.map +1 -1
- package/dist/cjs/snowplow/Snowplow.js +13 -2
- package/dist/cjs/snowplow/Snowplow.js.map +1 -1
- package/dist/cjs/snowplow/event-definitions/base.js +39 -0
- package/dist/cjs/snowplow/event-definitions/base.js.map +1 -1
- package/dist/cjs/snowplow/event-definitions/index.js +9 -2
- package/dist/cjs/snowplow/event-definitions/index.js.map +1 -1
- package/dist/cjs/snowplow/event-definitions/qcp.js +14 -0
- package/dist/cjs/snowplow/event-definitions/qcp.js.map +1 -1
- package/dist/cjs/snowplow/event-definitions/questionnaire.js +49 -0
- package/dist/cjs/snowplow/event-definitions/questionnaire.js.map +1 -0
- package/dist/cjs/snowplow/event-definitions/redaction.js +152 -0
- package/dist/cjs/snowplow/event-definitions/redaction.js.map +1 -0
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/mocks/eventDefinitions.js +39 -0
- package/dist/esm/mocks/eventDefinitions.js.map +1 -1
- package/dist/esm/snowplow/Snowplow.js +13 -2
- package/dist/esm/snowplow/Snowplow.js.map +1 -1
- package/dist/esm/snowplow/event-definitions/base.js +39 -0
- package/dist/esm/snowplow/event-definitions/base.js.map +1 -1
- package/dist/esm/snowplow/event-definitions/index.js +6 -2
- package/dist/esm/snowplow/event-definitions/index.js.map +1 -1
- package/dist/esm/snowplow/event-definitions/qcp.js +14 -0
- package/dist/esm/snowplow/event-definitions/qcp.js.map +1 -1
- package/dist/esm/snowplow/event-definitions/questionnaire.js +40 -0
- package/dist/esm/snowplow/event-definitions/questionnaire.js.map +1 -0
- package/dist/esm/snowplow/event-definitions/redaction.js +142 -0
- package/dist/esm/snowplow/event-definitions/redaction.js.map +1 -0
- package/dist/esm/snowplow/types.js.map +1 -1
- package/dist/types/mocks/eventDefinitions.d.ts +30 -0
- package/dist/types/snowplow/Snowplow.d.ts +1 -0
- package/dist/types/snowplow/event-definitions/index.d.ts +1 -0
- package/dist/types/snowplow/event-definitions/questionnaire.d.ts +2 -0
- package/dist/types/snowplow/event-definitions/redaction.d.ts +5 -0
- package/dist/types/snowplow/types.d.ts +15 -1
- package/package.json +1 -1
- package/src/mocks/eventDefinitions.ts +44 -0
- package/src/snowplow/Snowplow.ts +16 -2
- package/src/snowplow/event-definitions/base.ts +43 -2
- package/src/snowplow/event-definitions/index.ts +4 -0
- package/src/snowplow/event-definitions/qcp.ts +17 -1
- package/src/snowplow/event-definitions/questionnaire.ts +43 -0
- package/src/snowplow/event-definitions/redaction.ts +144 -0
- package/src/snowplow/index.test.ts +179 -6
- package/src/snowplow/types.ts +17 -15
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { ParamsType } from "../types";
|
|
2
|
+
|
|
3
|
+
const PII_ANSWER = [
|
|
4
|
+
"customer_title",
|
|
5
|
+
"customer_first_name",
|
|
6
|
+
"customer_last_name",
|
|
7
|
+
"customer_email_address",
|
|
8
|
+
"preapp_email_address",
|
|
9
|
+
"customer_telephone_number",
|
|
10
|
+
"customer_alternative_telephone_number",
|
|
11
|
+
"customer_address_1_pre_quote",
|
|
12
|
+
"customer_address_2_pre_quote",
|
|
13
|
+
"customer_town_pre_quote",
|
|
14
|
+
"customer_postcode_pre_quote",
|
|
15
|
+
"customer_address_1",
|
|
16
|
+
"customer_address_2",
|
|
17
|
+
"customer_town",
|
|
18
|
+
"customer_postcode",
|
|
19
|
+
"address_1_pre_quote",
|
|
20
|
+
"address_2_pre_quote",
|
|
21
|
+
"uk_postcode_pre_quote",
|
|
22
|
+
"town_pre_quote",
|
|
23
|
+
"owner_first_name",
|
|
24
|
+
"owner_last_name",
|
|
25
|
+
"beneficiary_first_name",
|
|
26
|
+
"beneficiary_last_name",
|
|
27
|
+
"gender",
|
|
28
|
+
"dynamic_ssn_fein",
|
|
29
|
+
"ssn",
|
|
30
|
+
"fein",
|
|
31
|
+
"sof_county_court_judgement_online_yes",
|
|
32
|
+
"sof_county_court_judgement_online_no",
|
|
33
|
+
"sof_ccj_count",
|
|
34
|
+
"sof_ccj_value",
|
|
35
|
+
"sof_ccj_date",
|
|
36
|
+
"sof_court_judgement_yes",
|
|
37
|
+
"sof_court_judgement_no",
|
|
38
|
+
"ccj_date",
|
|
39
|
+
"sof_single_ccj_no",
|
|
40
|
+
"sof_single_ccj_yes",
|
|
41
|
+
"sof_ccj_yes",
|
|
42
|
+
"sof_ccj_no",
|
|
43
|
+
"ccj_count",
|
|
44
|
+
"sof_bankrupt_yes",
|
|
45
|
+
"sof_bankrupt_no",
|
|
46
|
+
"sof_multiple_bankruptcies_yes",
|
|
47
|
+
"sof_multiple_bankruptcies_no",
|
|
48
|
+
"bankruptcy_date",
|
|
49
|
+
"sof_single_bankruptcy_no",
|
|
50
|
+
"sof_single_bankruptcy_yes",
|
|
51
|
+
"sof_bankruptcy_yes",
|
|
52
|
+
"sof_bankruptcy_no",
|
|
53
|
+
"bankruptcy_discharged",
|
|
54
|
+
"sof_liquidation_yes",
|
|
55
|
+
"sof_liquidation_no",
|
|
56
|
+
"sof_multiple_liquidations",
|
|
57
|
+
"liquidation_date",
|
|
58
|
+
"sof_criminal_offence_yes",
|
|
59
|
+
"sof_criminal_offence_no",
|
|
60
|
+
"sof_criminal_yes",
|
|
61
|
+
"sof_criminal_no",
|
|
62
|
+
"hcp_date_of_birth_1",
|
|
63
|
+
"hcp_date_of_birth_2",
|
|
64
|
+
"hcp_date_of_birth_3",
|
|
65
|
+
"hcp_date_of_birth_4",
|
|
66
|
+
"hcp_date_of_birth_5",
|
|
67
|
+
"hcp_date_of_birth_6",
|
|
68
|
+
"hcp_date_of_birth_7",
|
|
69
|
+
"hcp_date_of_birth_8",
|
|
70
|
+
"hcp_date_of_birth_9",
|
|
71
|
+
"hcp_date_of_birth_10",
|
|
72
|
+
"sof_previous_claims_yes",
|
|
73
|
+
"sof_previous_claims_no",
|
|
74
|
+
"sof_claims_yes",
|
|
75
|
+
"sof_claims_no",
|
|
76
|
+
"sof_property_claims_in_the_last_5_years_yes",
|
|
77
|
+
"sof_property_claims_in_the_last_5_years_no",
|
|
78
|
+
"sof_property_claims_in_the_last_0_to_4_years_yes",
|
|
79
|
+
"sof_property_claims_in_the_last_0_to_4_years_no",
|
|
80
|
+
"claim_count",
|
|
81
|
+
"sof_number_of_claims",
|
|
82
|
+
"number_of_claims_in_last_5_years",
|
|
83
|
+
"number_of_claims_in_time_owned",
|
|
84
|
+
"date_of_incident_1",
|
|
85
|
+
"date_of_incident_2",
|
|
86
|
+
"date_of_incident_3",
|
|
87
|
+
"date_of_incident_4",
|
|
88
|
+
"date_of_incident_5",
|
|
89
|
+
"type_of_incident_1",
|
|
90
|
+
"type_of_incident_2",
|
|
91
|
+
"type_of_incident_3",
|
|
92
|
+
"type_of_incident_4",
|
|
93
|
+
"type_of_incident_5",
|
|
94
|
+
"incident_value_1",
|
|
95
|
+
"incident_value_2",
|
|
96
|
+
"incident_value_3",
|
|
97
|
+
"incident_value_4",
|
|
98
|
+
"incident_value_5",
|
|
99
|
+
"sof_pollution_disease_claims_yes",
|
|
100
|
+
"sof_pollution_disease_claims_no",
|
|
101
|
+
"sof_potential_claims_yes",
|
|
102
|
+
"sof_potential_claims_no",
|
|
103
|
+
"sof_previous_circumstances_yes",
|
|
104
|
+
"sof_previous_circumstances_no",
|
|
105
|
+
"sof_possible_claims_yes",
|
|
106
|
+
"sof_possible_claims_no",
|
|
107
|
+
"date_of_possible_incident",
|
|
108
|
+
"type_of_possible_incident",
|
|
109
|
+
"possible_incident_value",
|
|
110
|
+
"sof_property_claims_yes",
|
|
111
|
+
"sof_property_claims_no",
|
|
112
|
+
"sof_liability_claims_yes",
|
|
113
|
+
"sof_liability_claims_no",
|
|
114
|
+
"van_registration",
|
|
115
|
+
"sof_disqualified_director_yes",
|
|
116
|
+
"sof_disqualified_director_no",
|
|
117
|
+
"sof_insurance_refused_yes",
|
|
118
|
+
"sof_insurance_refused_no",
|
|
119
|
+
"sof_insurance_declined_yes",
|
|
120
|
+
"sof_insurance_declined_no",
|
|
121
|
+
"insurance_refused",
|
|
122
|
+
];
|
|
123
|
+
|
|
124
|
+
const RADIO_ANSWER_FROM_QUESTIONS = [
|
|
125
|
+
"have_secondary_trade_yes",
|
|
126
|
+
"have_secondary_trade_no",
|
|
127
|
+
];
|
|
128
|
+
|
|
129
|
+
const ANSWER_SUFFIX_PATTERN = /_(yes|no)$/;
|
|
130
|
+
|
|
131
|
+
export const redact = (params: ParamsType) => {
|
|
132
|
+
let { question, answer } = params as ParamsType;
|
|
133
|
+
|
|
134
|
+
const piiAnswer = new Set(PII_ANSWER);
|
|
135
|
+
const radioAnswerFromQuestions = new Set(RADIO_ANSWER_FROM_QUESTIONS);
|
|
136
|
+
|
|
137
|
+
if (piiAnswer.has(question)) {
|
|
138
|
+
answer = "REDACTED";
|
|
139
|
+
question = question?.replace(ANSWER_SUFFIX_PATTERN, "");
|
|
140
|
+
} else if (radioAnswerFromQuestions.has(question)) {
|
|
141
|
+
question = question?.replace(ANSWER_SUFFIX_PATTERN, "");
|
|
142
|
+
}
|
|
143
|
+
return { question, answer };
|
|
144
|
+
};
|
|
@@ -118,6 +118,7 @@ describe("Snowplow Analytics Class", () => {
|
|
|
118
118
|
expect(Object.keys(testSnowplow.eventHandlers)).toEqual([
|
|
119
119
|
"navButtonClicked",
|
|
120
120
|
"questionAnswered",
|
|
121
|
+
"helpTextOpened",
|
|
121
122
|
]);
|
|
122
123
|
});
|
|
123
124
|
|
|
@@ -159,20 +160,192 @@ describe("Snowplow Analytics Class", () => {
|
|
|
159
160
|
.mockImplementation(() => {});
|
|
160
161
|
|
|
161
162
|
await testSnowplow.trigger("questionAnswered", {
|
|
162
|
-
vertical: "shop",
|
|
163
163
|
question: "test-question",
|
|
164
|
+
section: "test-section",
|
|
164
165
|
answer: "test-answer",
|
|
165
166
|
});
|
|
166
167
|
|
|
167
168
|
const expectedPayload = {
|
|
168
169
|
schema:
|
|
169
|
-
"iglu:com.simplybusiness/form_question_answered/jsonschema/1-0-
|
|
170
|
+
"iglu:com.simplybusiness/form_question_answered/jsonschema/1-0-3",
|
|
170
171
|
data: {
|
|
171
|
-
site: "",
|
|
172
|
-
vertical: "
|
|
172
|
+
site: "simplybusiness_us",
|
|
173
|
+
vertical: "usa",
|
|
173
174
|
page_index: 1,
|
|
174
|
-
page_name: "
|
|
175
|
-
section_name: "
|
|
175
|
+
page_name: "quick_to_quote",
|
|
176
|
+
section_name: "test-section",
|
|
177
|
+
submitted_from: "quick_to_quote_experiment",
|
|
178
|
+
question: "test-question",
|
|
179
|
+
answer: "test-answer",
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
expect(trackUnstructEventSpy).toHaveBeenCalledTimes(1);
|
|
184
|
+
expect(trackUnstructEventSpy).toHaveBeenCalledWith(expectedPayload);
|
|
185
|
+
expect(innerSpy).toHaveBeenCalledTimes(1);
|
|
186
|
+
expect(innerSpy).toHaveBeenCalledWith(
|
|
187
|
+
{
|
|
188
|
+
event: expectedPayload,
|
|
189
|
+
context: contexts,
|
|
190
|
+
},
|
|
191
|
+
["sb-ava"],
|
|
192
|
+
);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it("triggers an added unstructured event and readact the pii information and replace question name", async () => {
|
|
196
|
+
testSnowplow.addEventHandlers(eventDefinitions as EventDefinition[]);
|
|
197
|
+
|
|
198
|
+
const trackUnstructEventSpy = jest.spyOn(
|
|
199
|
+
testSnowplow,
|
|
200
|
+
"trackUnstructEvent",
|
|
201
|
+
);
|
|
202
|
+
const innerSpy = jest
|
|
203
|
+
.spyOn(SnowplowLib, "trackSelfDescribingEvent")
|
|
204
|
+
.mockImplementation(() => {});
|
|
205
|
+
|
|
206
|
+
await testSnowplow.trigger("questionAnswered", {
|
|
207
|
+
question: "sof_bankrupt_yes",
|
|
208
|
+
section: "agreements",
|
|
209
|
+
answer: "Yes",
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
const expectedPayload = {
|
|
213
|
+
schema:
|
|
214
|
+
"iglu:com.simplybusiness/form_question_answered/jsonschema/1-0-3",
|
|
215
|
+
data: {
|
|
216
|
+
site: "simplybusiness_us",
|
|
217
|
+
vertical: "usa",
|
|
218
|
+
page_index: 1,
|
|
219
|
+
page_name: "quick_to_quote",
|
|
220
|
+
section_name: "agreements",
|
|
221
|
+
submitted_from: "quick_to_quote_experiment",
|
|
222
|
+
question: "sof_bankrupt",
|
|
223
|
+
answer: "REDACTED",
|
|
224
|
+
},
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
expect(trackUnstructEventSpy).toHaveBeenCalledTimes(1);
|
|
228
|
+
expect(trackUnstructEventSpy).toHaveBeenCalledWith(expectedPayload);
|
|
229
|
+
expect(innerSpy).toHaveBeenCalledTimes(1);
|
|
230
|
+
expect(innerSpy).toHaveBeenCalledWith(
|
|
231
|
+
{
|
|
232
|
+
event: expectedPayload,
|
|
233
|
+
context: contexts,
|
|
234
|
+
},
|
|
235
|
+
["sb-ava"],
|
|
236
|
+
);
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
it("triggers an added unstructured event and replace radio answer from questions", async () => {
|
|
240
|
+
testSnowplow.addEventHandlers(eventDefinitions as EventDefinition[]);
|
|
241
|
+
|
|
242
|
+
const trackUnstructEventSpy = jest.spyOn(
|
|
243
|
+
testSnowplow,
|
|
244
|
+
"trackUnstructEvent",
|
|
245
|
+
);
|
|
246
|
+
const innerSpy = jest
|
|
247
|
+
.spyOn(SnowplowLib, "trackSelfDescribingEvent")
|
|
248
|
+
.mockImplementation(() => {});
|
|
249
|
+
|
|
250
|
+
await testSnowplow.trigger("questionAnswered", {
|
|
251
|
+
question: "have_secondary_trade_yes",
|
|
252
|
+
section: "about_your_business",
|
|
253
|
+
answer: "Yes",
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
const expectedPayload = {
|
|
257
|
+
schema:
|
|
258
|
+
"iglu:com.simplybusiness/form_question_answered/jsonschema/1-0-3",
|
|
259
|
+
data: {
|
|
260
|
+
site: "simplybusiness_us",
|
|
261
|
+
vertical: "usa",
|
|
262
|
+
page_index: 1,
|
|
263
|
+
page_name: "quick_to_quote",
|
|
264
|
+
section_name: "about_your_business",
|
|
265
|
+
submitted_from: "quick_to_quote_experiment",
|
|
266
|
+
question: "have_secondary_trade",
|
|
267
|
+
answer: "Yes",
|
|
268
|
+
},
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
expect(trackUnstructEventSpy).toHaveBeenCalledTimes(1);
|
|
272
|
+
expect(trackUnstructEventSpy).toHaveBeenCalledWith(expectedPayload);
|
|
273
|
+
expect(innerSpy).toHaveBeenCalledTimes(1);
|
|
274
|
+
expect(innerSpy).toHaveBeenCalledWith(
|
|
275
|
+
{
|
|
276
|
+
event: expectedPayload,
|
|
277
|
+
context: contexts,
|
|
278
|
+
},
|
|
279
|
+
["sb-ava"],
|
|
280
|
+
);
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
it("triggers an added unstructured help_text_opened event", async () => {
|
|
284
|
+
testSnowplow.addEventHandlers(eventDefinitions as EventDefinition[]);
|
|
285
|
+
|
|
286
|
+
const trackUnstructEventSpy = jest.spyOn(
|
|
287
|
+
testSnowplow,
|
|
288
|
+
"trackUnstructEvent",
|
|
289
|
+
);
|
|
290
|
+
const innerSpy = jest
|
|
291
|
+
.spyOn(SnowplowLib, "trackSelfDescribingEvent")
|
|
292
|
+
.mockImplementation(() => {});
|
|
293
|
+
|
|
294
|
+
await testSnowplow.trigger("helpTextOpened", {
|
|
295
|
+
primaryText: "Sample text",
|
|
296
|
+
label: "Sample label",
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
const expectedPayload = {
|
|
300
|
+
schema: "iglu:com.simplybusiness/help_text_opened/jsonschema/1-1-0",
|
|
301
|
+
data: {
|
|
302
|
+
vertical: "usa",
|
|
303
|
+
site: "simplybusiness_us",
|
|
304
|
+
primary_text: "Sample text",
|
|
305
|
+
label: "Sample label",
|
|
306
|
+
page_name: "quick_to_quote",
|
|
307
|
+
},
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
expect(trackUnstructEventSpy).toHaveBeenCalledTimes(1);
|
|
311
|
+
expect(trackUnstructEventSpy).toHaveBeenCalledWith(expectedPayload);
|
|
312
|
+
expect(innerSpy).toHaveBeenCalledTimes(1);
|
|
313
|
+
expect(innerSpy).toHaveBeenCalledWith(
|
|
314
|
+
{
|
|
315
|
+
event: expectedPayload,
|
|
316
|
+
context: contexts,
|
|
317
|
+
},
|
|
318
|
+
["sb-ava"],
|
|
319
|
+
);
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
it("uses server-supplied context in events", async () => {
|
|
323
|
+
testSnowplow.addEventHandlers(eventDefinitions as EventDefinition[]);
|
|
324
|
+
|
|
325
|
+
const trackUnstructEventSpy = jest.spyOn(
|
|
326
|
+
testSnowplow,
|
|
327
|
+
"trackUnstructEvent",
|
|
328
|
+
);
|
|
329
|
+
const innerSpy = jest
|
|
330
|
+
.spyOn(SnowplowLib, "trackSelfDescribingEvent")
|
|
331
|
+
.mockImplementation(() => {});
|
|
332
|
+
|
|
333
|
+
await testSnowplow.trigger("questionAnswered", {
|
|
334
|
+
question: "test-question",
|
|
335
|
+
section: "test-section",
|
|
336
|
+
answer: "test-answer",
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
const expectedPayload = {
|
|
340
|
+
schema:
|
|
341
|
+
"iglu:com.simplybusiness/form_question_answered/jsonschema/1-0-3",
|
|
342
|
+
data: {
|
|
343
|
+
site: "simplybusiness_us",
|
|
344
|
+
vertical: "usa",
|
|
345
|
+
page_index: 1,
|
|
346
|
+
page_name: "quick_to_quote",
|
|
347
|
+
section_name: "test-section",
|
|
348
|
+
submitted_from: "quick_to_quote_experiment",
|
|
176
349
|
question: "test-question",
|
|
177
350
|
answer: "test-answer",
|
|
178
351
|
},
|
package/src/snowplow/types.ts
CHANGED
|
@@ -21,6 +21,7 @@ export type EnvConfig = BaseConfig & {
|
|
|
21
21
|
export type TrackingProps = BaseConfig & {
|
|
22
22
|
eventMethod: EventMethod;
|
|
23
23
|
cookieDomain?: string;
|
|
24
|
+
pageViewContext?: ChannelContext;
|
|
24
25
|
};
|
|
25
26
|
|
|
26
27
|
export type ChannelContext = {
|
|
@@ -32,21 +33,22 @@ export type ChannelContexts = Record<string, ChannelContext>;
|
|
|
32
33
|
|
|
33
34
|
export type ArrayOneOrMore<T> = [T, ...T[]];
|
|
34
35
|
|
|
35
|
-
export type ParamsType = Record<
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
string
|
|
49
|
-
|
|
36
|
+
export type ParamsType = Record<string, string> & {
|
|
37
|
+
context: ServerContext;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
type ServerContext = {
|
|
41
|
+
site: string;
|
|
42
|
+
vertical: string;
|
|
43
|
+
primary_detail: string;
|
|
44
|
+
journey_name: string;
|
|
45
|
+
journey_id: string;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export type LinkType = Record<string, string> & {
|
|
49
|
+
targetUrl: string;
|
|
50
|
+
elementContent: string;
|
|
51
|
+
};
|
|
50
52
|
|
|
51
53
|
export type EventDefinition = {
|
|
52
54
|
name: string;
|