Setting the file. One moment. Checkout Field CSV Parser Test Fixture · Rp Source Wordpress · wix/skills · Skills Docslib/checkout-field-csv-parser.test-fixture.js
lib/checkout-field-csv-parser.test-fixture.js
JavaScript·91 lines·5 KB
1'use strict';
2
3const VALID_CSV = [
4 'meta_key,label,type,section,required,options,enabled,sort_order',
5 'gift_message,"Gift ""message""",textarea,additional,no,,yes,10',
6 'delivery_instructions,Delivery instructions,text,additional,no,,yes,20',
7 'preferred_contact_method,Preferred contact method,radio,additional,yes,"Email|Phone|SMS",yes,30',
8 'section_heading,Additional details,heading,additional,no,,yes,5',
9].join('\n');
10
11
const
BAD_CSV_DUPLICATE_KEY
=
[
12 'meta_key,label,type,section,required,options,enabled,sort_order',
13 'gift_message,Gift message,textarea,additional,no,,yes,10',
14 'gift_message,Gift message again,text,additional,no,,yes,20',
15].join('\n');
16
17const BAD_CSV_MISSING_OPTIONS = [
18 'meta_key,label,type,section,required,options,enabled,sort_order',
19 'preferred_contact_method,Preferred contact method,radio,additional,yes,,yes,30',
20].join('\n');
21
22const BAD_CSV_UNTERMINATED_QUOTE = [
23 'meta_key,label,type,section,required,options,enabled,sort_order',
24 'gift_message,"Gift message,textarea,additional,no,,yes,10',
25].join('\n');
26
27const BAD_CSV_INVALID_REQUIRED = [
28 'meta_key,label,type,section,required,options,enabled,sort_order',
29 'gift_message,Gift message,textarea,additional,yse,,yes,10',
30].join('\n');
31
32const BAD_CSV_INVALID_ENABLED = [
33 'meta_key,label,type,section,required,options,enabled,sort_order',
34 'gift_message,Gift message,textarea,additional,no,,maybe,10',
35].join('\n');
36
37const BAD_CSV_INVALID_SORT_ORDER = [
38 'meta_key,label,type,section,required,options,enabled,sort_order',
39 'gift_message,Gift message,textarea,additional,no,,yes,abc',
40].join('\n');
41
42// `parse` here is the handler's real entry point — parse({ inputPath, readFile }) — the exact
43// shape blocked-data-requests.js's attemptFulfillment() calls, not the internal pure text
44// parser, so this self-test actually exercises the contract a real resolveBlockedDataRequest()
45// run depends on.
46async function selfTest(parse) {
47 const readFile = (csvByPath) => async (inputPath) => {
48 if (!(inputPath in csvByPath)) throw new Error(`fixture readFile: no CSV registered for ${inputPath}`);
49 return csvByPath[inputPath];
50 };
51
52 const valid = await parse({ inputPath: '/fake/valid.csv', readFile: readFile({ '/fake/valid.csv': VALID_CSV }) });
53 if (!valid.reconciled) throw new Error('fixture: valid CSV did not reconcile');
54 if (!Number.isInteger(valid.expectedTotal) || valid.sourceCount !== valid.expectedTotal) {
55 throw new Error('fixture: sourceCount/expectedTotal must be present and equal for a fully-read CSV');
56 }
57 if (valid.headingCount !== 1) throw new Error('fixture: heading row was not counted separately');
58 if (valid.fields.length !== 3) throw new Error('fixture: expected 3 non-heading fields');
59 if (valid.fields[0].label !== 'Gift "message"') {
60 throw new Error(`fixture: escaped double-quote in a quoted label was not unescaped correctly, got ${JSON.stringify(valid.fields[0].label)}`);
61 }
62 const contactMethod = valid.fields.find((field) => field.metaKey === 'preferred_contact_method');
63 if (!contactMethod || contactMethod.options.length !== 3 || contactMethod.options[1] !== 'Phone') {
64 throw new Error('fixture: pipe-delimited options did not parse correctly');
65 }
66 if (valid.fields.find((field) => field.fieldType === 'heading')) {
67 throw new Error('fixture: heading row leaked into the returned field list');
68 }
69
70 const duplicate = await parse({ inputPath: '/fake/dup.csv', readFile: readFile({ '/fake/dup.csv': BAD_CSV_DUPLICATE_KEY }) });
71 if (duplicate.reconciled) throw new Error('fixture: duplicate meta_key should not reconcile');
72
73 const missingOptions = await parse({ inputPath: '/fake/missing-options.csv', readFile: readFile({ '/fake/missing-options.csv': BAD_CSV_MISSING_OPTIONS }) });
74 if (missingOptions.reconciled) throw new Error('fixture: choice-type row with no options should not reconcile');
75
76 const unterminated = await parse({ inputPath: '/fake/unterminated.csv', readFile: readFile({ '/fake/unterminated.csv': BAD_CSV_UNTERMINATED_QUOTE }) });
77 if (unterminated.reconciled) throw new Error('fixture: an unterminated quote must not reconcile, not be silently mis-split');
78
79 const invalidRequired = await parse({ inputPath: '/fake/invalid-required.csv', readFile: readFile({ '/fake/invalid-required.csv': BAD_CSV_INVALID_REQUIRED }) });
80 if (invalidRequired.reconciled) throw new Error('fixture: required="yse" (not yes/no) must not reconcile — must not silently coerce to false');
81
82 const invalidEnabled = await parse({ inputPath: '/fake/invalid-enabled.csv', readFile: readFile({ '/fake/invalid-enabled.csv': BAD_CSV_INVALID_ENABLED }) });
83 if (invalidEnabled.reconciled) throw new Error('fixture: enabled="maybe" (not yes/no) must not reconcile — must not silently coerce to false');
84
85 const invalidSortOrder = await parse({ inputPath: '/fake/invalid-sort-order.csv', readFile: readFile({ '/fake/invalid-sort-order.csv': BAD_CSV_INVALID_SORT_ORDER }) });
86 if (invalidSortOrder.reconciled) throw new Error('fixture: sort_order="abc" (not a number) must not reconcile — must not silently coerce to 0');
87
88 return true;
89}
90
91module.exports = selfTest;