@internetarchive/donation-form 1.0.3-webdev-8122.0 → 1.0.3-webdev-8114.1

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.
@@ -22,7 +22,6 @@ export declare class ContactForm extends LitElement {
22
22
  countryCodeAlpha2Field: HTMLSelectElement;
23
23
  errorMessage: HTMLDivElement;
24
24
  form: HTMLFormElement;
25
- /** @keyof countries */
26
25
  selectedCountry: string;
27
26
  donorEmail: string;
28
27
  updated(changed: PropertyValues): void;
@@ -30,6 +29,7 @@ export declare class ContactForm extends LitElement {
30
29
  focus(): void;
31
30
  /** @inheritdoc */
32
31
  render(): TemplateResult;
32
+ private get regionAndPostalCodeRequired();
33
33
  private get countrySelectorTemplate();
34
34
  /** @inheritdoc */
35
35
  createRenderRoot(): this;
@@ -12,7 +12,6 @@ import { countries } from './countries';
12
12
  let ContactForm = class ContactForm extends LitElement {
13
13
  constructor() {
14
14
  super(...arguments);
15
- /** @keyof countries */
16
15
  this.selectedCountry = 'US';
17
16
  this.donorEmail = '';
18
17
  }
@@ -41,7 +40,7 @@ let ContactForm = class ContactForm extends LitElement {
41
40
  }
42
41
  });
43
42
  if (!isValid) {
44
- this.errorMessage.innerText = 'Please enter any missing contact information below';
43
+ this.errorMessage.innerText = 'Please enter any missing or invalid contact information below';
45
44
  }
46
45
  else {
47
46
  this.errorMessage.innerText = '';
@@ -65,6 +64,7 @@ let ContactForm = class ContactForm extends LitElement {
65
64
  fieldType: 'email',
66
65
  name: 'email',
67
66
  autocomplete: 'email',
67
+ minlength: 5,
68
68
  maxlength: 255,
69
69
  icon: emailImg,
70
70
  })}
@@ -78,6 +78,7 @@ let ContactForm = class ContactForm extends LitElement {
78
78
  placeholder: 'First name',
79
79
  name: 'fname',
80
80
  required: true,
81
+ validationPattern: '.*\\S{2,}.*',
81
82
  maxlength: 255,
82
83
  autocomplete: 'given-name',
83
84
  icon: userIcon,
@@ -90,6 +91,7 @@ let ContactForm = class ContactForm extends LitElement {
90
91
  name: 'lname',
91
92
  autocomplete: 'family-name',
92
93
  required: true,
94
+ validationPattern: '.*\\S{2,}.*',
93
95
  maxlength: 255,
94
96
  })}
95
97
  </div>
@@ -103,6 +105,7 @@ let ContactForm = class ContactForm extends LitElement {
103
105
  autocomplete: 'address-line1',
104
106
  icon: localePinImg,
105
107
  name: 'street-address',
108
+ validationPattern: '.*?\\S.{2,}\\S.*?',
106
109
  })}
107
110
  </div>
108
111
  <div class="row">
@@ -121,6 +124,7 @@ let ContactForm = class ContactForm extends LitElement {
121
124
  autocomplete: 'address-level2',
122
125
  required: true,
123
126
  name: 'locality',
127
+ validationPattern: '.*\\S{2,}.*',
124
128
  })}
125
129
  </div>
126
130
  <div class="row">
@@ -128,18 +132,17 @@ let ContactForm = class ContactForm extends LitElement {
128
132
  id: 'donation-contact-form-region',
129
133
  placeholder: 'State / Province',
130
134
  autocomplete: 'address-level1',
131
- required: true,
135
+ required: this.regionAndPostalCodeRequired,
132
136
  name: 'region',
137
+ validationPattern: '.*\\S{2,}.*',
133
138
  })}
134
139
  ${this.generateInput({
135
140
  id: 'donation-contact-form-postal-code',
136
141
  placeholder: 'Zip / Postal',
137
142
  autocomplete: 'postal-code',
138
- required: true,
143
+ required: this.regionAndPostalCodeRequired,
139
144
  name: 'postal',
140
- maxlength: 9,
141
- // must start with a character, then may contain spaces
142
- validationPattern: '[a-zA-Z\\-\\d]+[a-zA-Z\\-\\d\\s]*',
145
+ validationPattern: '^\\d{5}(-\\d{4})?$',
143
146
  iconSpaceOption: SpacerOption.CompressSpace,
144
147
  })}
145
148
  </div>
@@ -149,30 +152,18 @@ let ContactForm = class ContactForm extends LitElement {
149
152
  ${this.getStyles}
150
153
  `;
151
154
  }
155
+ get regionAndPostalCodeRequired() {
156
+ return this.selectedCountry === 'US';
157
+ }
152
158
  get countrySelectorTemplate() {
153
159
  return html `
154
160
  <badged-input>
155
161
  <select
156
162
  id="donation-contact-form-countryCodeAlpha2"
157
163
  @change=${(e) => {
158
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
159
- const currCountry = this.selectedCountry;
160
- this.selectedCountry = ((_a = e.target) === null || _a === void 0 ? void 0 : _a.value)
161
- ? (_b = e.target) === null || _b === void 0 ? void 0 : _b.value
162
- : currCountry;
163
- // update required visual cue on region/state/province & postal code fields
164
- if (this.selectedCountry === 'US') {
165
- (_c = this.postalBadgedInput) === null || _c === void 0 ? void 0 : _c.setAttribute('required', '');
166
- (_d = this.postalCodeField) === null || _d === void 0 ? void 0 : _d.setAttribute('required', '');
167
- (_e = this.regionBadgedInput) === null || _e === void 0 ? void 0 : _e.setAttribute('required', '');
168
- (_f = this.regionField) === null || _f === void 0 ? void 0 : _f.setAttribute('required', '');
169
- }
170
- else {
171
- (_g = this.postalBadgedInput) === null || _g === void 0 ? void 0 : _g.removeAttribute('required');
172
- (_h = this.postalCodeField) === null || _h === void 0 ? void 0 : _h.removeAttribute('required');
173
- (_j = this.regionBadgedInput) === null || _j === void 0 ? void 0 : _j.removeAttribute('required');
174
- (_k = this.regionField) === null || _k === void 0 ? void 0 : _k.removeAttribute('required');
175
- }
164
+ const newValue = e.target.value;
165
+ if (countries[newValue])
166
+ this.selectedCountry = newValue;
176
167
  }}
177
168
  >
178
169
  ${Object.keys(countries).map(key => {
@@ -222,6 +213,7 @@ let ContactForm = class ContactForm extends LitElement {
222
213
  aria-label=${options.placeholder}
223
214
  placeholder=${options.placeholder}
224
215
  maxlength=${ifDefined(options.maxlength)}
216
+ minlength=${ifDefined(options.minlength)}
225
217
  autocomplete=${(_d = options.autocomplete) !== null && _d !== void 0 ? _d : 'on'}
226
218
  pattern=${ifDefined(options.validationPattern)}
227
219
  @focus=${this.inputFocused}
@@ -238,8 +230,6 @@ let ContactForm = class ContactForm extends LitElement {
238
230
  }
239
231
  get billingInfo() {
240
232
  const billingInfo = new BillingInfo({
241
- firstName: this.firstNameField.value,
242
- lastName: this.lastNameField.value,
243
233
  streetAddress: this.streetAddressField.value,
244
234
  extendedAddress: this.extendedAddressField.value,
245
235
  locality: this.localityField.value,
@@ -1 +1 @@
1
- {"version":3,"file":"contact-form.js","sourceRoot":"","sources":["../../../../src/form-elements/contact-form/contact-form.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, html, css, TemplateResult, PropertyValues } from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nimport {\n BillingInfo,\n CustomerInfo,\n DonorContactInfo,\n} from '@internetarchive/donation-form-data-models';\nimport { AutoCompleteFieldOptions } from './autocomplete-field-options';\nimport { SpacerOption } from '../badged-input';\nimport { BadgedInput } from '../badged-input';\nimport '../badged-input';\n\nimport emailImg from '@internetarchive/icon-email/index.js';\nimport localePinImg from '@internetarchive/icon-locale-pin/index.js';\nimport userIcon from '@internetarchive/icon-user/index.js';\n\nimport { countries } from './countries';\n\n@customElement('contact-form')\nexport class ContactForm extends LitElement {\n @query('badged-input.donation-contact-form-email') emailBadgedInput!: BadgedInput;\n @query('#donation-contact-form-email') emailField!: HTMLInputElement;\n\n @query('badged-input.donation-contact-form-first-name') firstNameBadgedInput!: BadgedInput;\n @query('#donation-contact-form-first-name') firstNameField!: HTMLInputElement;\n\n @query('badged-input.donation-contact-form-last-name') lastNameBadgedInput!: BadgedInput;\n @query('#donation-contact-form-last-name') lastNameField!: HTMLInputElement;\n\n @query('badged-input.donation-contact-form-postal-code') postalBadgedInput!: BadgedInput;\n @query('#donation-contact-form-postal-code') postalCodeField!: HTMLInputElement;\n\n @query('badged-input.donation-contact-form-street-address')\n streetAddressBadgedInput!: BadgedInput;\n @query('#donation-contact-form-street-address') streetAddressField!: HTMLInputElement;\n\n @query('badged-input.donation-contact-form-extended-address')\n extendedAddressBadgedInput!: BadgedInput;\n @query('#donation-contact-form-extended-address') extendedAddressField!: HTMLInputElement;\n\n @query('badged-input.donation-contact-form-locality') localityBadgedInput!: BadgedInput;\n @query('#donation-contact-form-locality') localityField!: HTMLInputElement;\n\n @query('badged-input.donation-contact-form-region') regionBadgedInput!: BadgedInput;\n @query('#donation-contact-form-region') regionField!: HTMLInputElement;\n\n @query('#donation-contact-form-countryCodeAlpha2') countryCodeAlpha2Field!: HTMLSelectElement;\n\n @query('#donation-contact-form-error-message') errorMessage!: HTMLDivElement;\n @query('form') form!: HTMLFormElement;\n\n /** @keyof countries */\n @property({ type: String }) selectedCountry = 'US';\n\n @property({ type: String }) donorEmail = '';\n\n updated(changed: PropertyValues): void {\n if (changed.has('donorEmail')) {\n this.emailField.value = this.donorEmail ?? '';\n }\n }\n\n reportValidity(): boolean {\n const fieldBadgedInputs: Array<[HTMLInputElement, BadgedInput]> = [\n [this.emailField, this.emailBadgedInput],\n [this.firstNameField, this.firstNameBadgedInput],\n [this.lastNameField, this.lastNameBadgedInput],\n [this.regionField, this.regionBadgedInput],\n [this.localityField, this.localityBadgedInput],\n [this.streetAddressField, this.streetAddressBadgedInput],\n [this.postalCodeField, this.postalBadgedInput],\n ];\n\n let isValid = true;\n fieldBadgedInputs.forEach(([inputElement, badgedInput]) => {\n const fieldValid = inputElement.checkValidity();\n isValid = isValid && fieldValid;\n if (!fieldValid) {\n badgedInput.error = true;\n }\n });\n\n if (!isValid) {\n this.errorMessage.innerText = 'Please enter any missing contact information below';\n } else {\n this.errorMessage.innerText = '';\n }\n\n return isValid;\n }\n\n focus(): void {\n this.emailField.focus();\n }\n\n /** @inheritdoc */\n render(): TemplateResult {\n return html`\n <div id=\"donation-contact-form-error-message\"></div>\n <form>\n <fieldset>\n <div class=\"row\">\n ${this.generateInput({\n id: 'donation-contact-form-email',\n placeholder: 'Email',\n required: true,\n fieldType: 'email',\n name: 'email',\n autocomplete: 'email',\n maxlength: 255,\n icon: emailImg,\n })}\n </div>\n </fieldset>\n\n <fieldset>\n <div class=\"row\">\n ${this.generateInput({\n id: 'donation-contact-form-first-name',\n placeholder: 'First name',\n name: 'fname',\n required: true,\n maxlength: 255,\n autocomplete: 'given-name',\n icon: userIcon,\n })}\n </div>\n <div class=\"row\">\n ${this.generateInput({\n id: 'donation-contact-form-last-name',\n placeholder: 'Last name',\n name: 'lname',\n autocomplete: 'family-name',\n required: true,\n maxlength: 255,\n })}\n </div>\n </fieldset>\n <fieldset>\n <div class=\"row\">\n ${this.generateInput({\n id: 'donation-contact-form-street-address',\n placeholder: 'Address Line 1',\n required: true,\n autocomplete: 'address-line1',\n icon: localePinImg,\n name: 'street-address',\n })}\n </div>\n <div class=\"row\">\n ${this.generateInput({\n id: 'donation-contact-form-extended-address',\n placeholder: 'Address Line 2 (optional)',\n autocomplete: 'address-line2',\n required: false,\n name: 'extended-address',\n })}\n </div>\n <div class=\"row\">\n ${this.generateInput({\n id: 'donation-contact-form-locality',\n placeholder: 'City',\n autocomplete: 'address-level2',\n required: true,\n name: 'locality',\n })}\n </div>\n <div class=\"row\">\n ${this.generateInput({\n id: 'donation-contact-form-region',\n placeholder: 'State / Province',\n autocomplete: 'address-level1',\n required: true,\n name: 'region',\n })}\n ${this.generateInput({\n id: 'donation-contact-form-postal-code',\n placeholder: 'Zip / Postal',\n autocomplete: 'postal-code',\n required: true,\n name: 'postal',\n maxlength: 9,\n // must start with a character, then may contain spaces\n validationPattern: '[a-zA-Z\\\\-\\\\d]+[a-zA-Z\\\\-\\\\d\\\\s]*',\n iconSpaceOption: SpacerOption.CompressSpace,\n })}\n </div>\n <div class=\"row\">${this.countrySelectorTemplate}</div>\n </fieldset>\n </form>\n ${this.getStyles}\n `;\n }\n\n private get countrySelectorTemplate(): TemplateResult {\n return html`\n <badged-input>\n <select\n id=\"donation-contact-form-countryCodeAlpha2\"\n @change=${(e: Event) => {\n const currCountry = this.selectedCountry;\n this.selectedCountry = (e.target as HTMLInputElement)?.value\n ? ((e.target as HTMLInputElement)?.value as string)\n : currCountry;\n // update required visual cue on region/state/province & postal code fields\n if (this.selectedCountry === 'US') {\n this.postalBadgedInput?.setAttribute('required', '');\n this.postalCodeField?.setAttribute('required', '');\n this.regionBadgedInput?.setAttribute('required', '');\n this.regionField?.setAttribute('required', '');\n } else {\n this.postalBadgedInput?.removeAttribute('required');\n this.postalCodeField?.removeAttribute('required');\n this.regionBadgedInput?.removeAttribute('required');\n this.regionField?.removeAttribute('required');\n }\n }}\n >\n ${Object.keys(countries).map(key => {\n const name = countries[key];\n return html`\n <option value=${key} ?selected=${key === this.selectedCountry}>${name}</option>\n `;\n })}\n </select>\n </badged-input>\n `;\n }\n\n /** @inheritdoc */\n createRenderRoot(): this {\n // Render template without shadow DOM. Note that shadow DOM features like\n // encapsulated CSS and slots are unavailable.\n // Form autofill does not work properly in the shadow DOM\n // so we need our form fields in the light DOM\n return this;\n }\n\n // reset the error state when the user focuses the input\n private inputFocused(e: KeyboardEvent): void {\n this.errorMessage.innerText = '';\n const input = e.target as HTMLInputElement;\n const inputIdentifier = input.id;\n const badgedInput = this.querySelector(`badged-input.${inputIdentifier}`) as BadgedInput;\n badgedInput.error = false;\n }\n\n private generateInput(options: {\n id: string;\n placeholder: string;\n required?: boolean;\n fieldType?: 'text' | 'email';\n autocomplete?: AutoCompleteFieldOptions;\n maxlength?: number;\n name: string;\n icon?: TemplateResult;\n iconSpaceOption?: SpacerOption;\n validationPattern?: string;\n }): TemplateResult {\n const required = options.required ?? true;\n const fieldType = options.fieldType ?? 'text';\n const iconOption = options.iconSpaceOption ?? SpacerOption.LeaveSpace;\n\n return html`\n <badged-input\n class=${options.id}\n .icon=${options.icon}\n .iconSpaceOption=${iconOption}\n ?required=${options.required}\n >\n <label for=${options.id}>${options.placeholder}</label>\n <input\n type=${fieldType}\n id=${options.id}\n class=\"donation-contact-form-input\"\n name=${options.name}\n aria-label=${options.placeholder}\n placeholder=${options.placeholder}\n maxlength=${ifDefined(options.maxlength)}\n autocomplete=${options.autocomplete ?? 'on'}\n pattern=${ifDefined(options.validationPattern)}\n @focus=${this.inputFocused}\n ?required=${required}\n />\n </badged-input>\n `;\n }\n\n get donorContactInfo(): DonorContactInfo {\n return new DonorContactInfo({\n billing: this.billingInfo,\n customer: this.contactInfo,\n });\n }\n\n get billingInfo(): BillingInfo {\n const billingInfo = new BillingInfo({\n firstName: this.firstNameField.value,\n lastName: this.lastNameField.value,\n streetAddress: this.streetAddressField.value,\n extendedAddress: this.extendedAddressField.value,\n locality: this.localityField.value,\n region: this.regionField.value,\n postalCode: this.postalCodeField.value,\n countryCodeAlpha2: this.countryCodeAlpha2Field.value,\n });\n return billingInfo;\n }\n\n get contactInfo(): CustomerInfo {\n return new CustomerInfo({\n email: this.emailField.value,\n firstName: this.firstNameField.value,\n lastName: this.lastNameField.value,\n });\n }\n\n /**\n * This is not the normal LitElement styles block.\n *\n * This element uses the clear DOM instead of the shadow DOM so it can't use\n * the shadowRoot's isolated styling. This is a bit of a workaround to keep all of\n * the styling local by writing out our own <style> tag and just be careful about\n * the selectors since they will leak outside of this component.\n *\n * @readonly\n * @private\n * @type {TemplateResult}\n * @memberof ContactForm\n */\n private get getStyles(): TemplateResult {\n const noIconSpacerWidth = css`var(--badgedInputNoIconSpacerWidth, 3rem)`;\n const iconSpacerWidth = css`var(--badgedInputIconSpacerWidth, 5rem)`;\n\n const fieldSetSpacing = css`var(--fieldSetSpacing, 1rem)`;\n const fieldFontFamily = css`var(--fontFamily, \"Helvetica Neue\", Helvetica, Arial, sans-serif)`;\n const fieldFontSize = css`var(--contactFieldFontSize, 1.6rem)`;\n const fieldFontColor = css`var(--inputFieldFontColor, #333)`;\n\n const iconFieldWidth = css`calc(100% - ${iconSpacerWidth})`;\n const noIconFieldWidth = css`calc(100% - ${noIconSpacerWidth})`;\n\n return html`\n <style>\n /*\n **NOTE**\n This element is in the lightDOM so be sure to prefix all styles\n with \"contact-form\" so styles don't leak.\n */\n contact-form fieldset {\n border: 0;\n padding: 0;\n margin: 0;\n margin-bottom: ${fieldSetSpacing};\n background-color: white;\n }\n\n /* These 1px and 0 margins in the next few selectors are to account for the\n double outlines caused by the fields being right next to each other */\n contact-form .row {\n display: flex;\n margin: -1px 0 0 0;\n }\n\n contact-form fieldset .row:first-child {\n margin-top: 0;\n }\n\n contact-form badged-input.donation-contact-form-region {\n width: 60%;\n }\n\n contact-form badged-input.donation-contact-form-postal-code {\n width: 40%;\n }\n\n contact-form #donation-contact-form-region {\n width: ${iconFieldWidth};\n }\n\n contact-form #donation-contact-form-postal-code {\n width: ${noIconFieldWidth};\n }\n\n contact-form #donation-contact-form-error-message {\n color: red;\n font-size: 1.4rem;\n margin-bottom: 0.6rem;\n }\n\n contact-form #donation-contact-form-last-name {\n width: ${noIconFieldWidth};\n }\n\n /* only show for screen readers */\n contact-form label {\n position: absolute;\n left: -10000px;\n top: auto;\n width: 1px;\n height: 1px;\n overflow: hidden;\n }\n\n contact-form .donation-contact-form-input {\n width: ${iconFieldWidth};\n border: 0;\n outline: 0;\n background: transparent;\n font-weight: bold;\n color: ${fieldFontColor};\n font-size: ${fieldFontSize};\n padding: 0;\n font-family: ${fieldFontFamily};\n }\n\n contact-form .donation-contact-form-input::placeholder {\n color: revert;\n }\n\n contact-form #donation-contact-form-countryCodeAlpha2 {\n width: calc(100%);\n height: 100%;\n box-sizing: border-box;\n font-weight: bold;\n font-size: ${fieldFontSize};\n font-family: ${fieldFontFamily};\n border: 0;\n background: #fff;\n }\n </style>\n `;\n }\n}\n"]}
1
+ {"version":3,"file":"contact-form.js","sourceRoot":"","sources":["../../../../src/form-elements/contact-form/contact-form.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, html, css, TemplateResult, PropertyValues } from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nimport {\n BillingInfo,\n CustomerInfo,\n DonorContactInfo,\n} from '@internetarchive/donation-form-data-models';\nimport { AutoCompleteFieldOptions } from './autocomplete-field-options';\nimport { SpacerOption } from '../badged-input';\nimport { BadgedInput } from '../badged-input';\nimport '../badged-input';\n\nimport emailImg from '@internetarchive/icon-email/index.js';\nimport localePinImg from '@internetarchive/icon-locale-pin/index.js';\nimport userIcon from '@internetarchive/icon-user/index.js';\n\nimport { countries } from './countries';\n\n@customElement('contact-form')\nexport class ContactForm extends LitElement {\n @query('badged-input.donation-contact-form-email') emailBadgedInput!: BadgedInput;\n @query('#donation-contact-form-email') emailField!: HTMLInputElement;\n\n @query('badged-input.donation-contact-form-first-name') firstNameBadgedInput!: BadgedInput;\n @query('#donation-contact-form-first-name') firstNameField!: HTMLInputElement;\n\n @query('badged-input.donation-contact-form-last-name') lastNameBadgedInput!: BadgedInput;\n @query('#donation-contact-form-last-name') lastNameField!: HTMLInputElement;\n\n @query('badged-input.donation-contact-form-postal-code') postalBadgedInput!: BadgedInput;\n @query('#donation-contact-form-postal-code') postalCodeField!: HTMLInputElement;\n\n @query('badged-input.donation-contact-form-street-address')\n streetAddressBadgedInput!: BadgedInput;\n @query('#donation-contact-form-street-address') streetAddressField!: HTMLInputElement;\n\n @query('badged-input.donation-contact-form-extended-address')\n extendedAddressBadgedInput!: BadgedInput;\n @query('#donation-contact-form-extended-address') extendedAddressField!: HTMLInputElement;\n\n @query('badged-input.donation-contact-form-locality') localityBadgedInput!: BadgedInput;\n @query('#donation-contact-form-locality') localityField!: HTMLInputElement;\n\n @query('badged-input.donation-contact-form-region') regionBadgedInput!: BadgedInput;\n @query('#donation-contact-form-region') regionField!: HTMLInputElement;\n\n @query('#donation-contact-form-countryCodeAlpha2') countryCodeAlpha2Field!: HTMLSelectElement;\n\n @query('#donation-contact-form-error-message') errorMessage!: HTMLDivElement;\n @query('form') form!: HTMLFormElement;\n\n @property({ type: String }) selectedCountry = 'US';\n\n @property({ type: String }) donorEmail = '';\n\n updated(changed: PropertyValues): void {\n if (changed.has('donorEmail')) {\n this.emailField.value = this.donorEmail ?? '';\n }\n }\n\n reportValidity(): boolean {\n const fieldBadgedInputs: Array<[HTMLInputElement, BadgedInput]> = [\n [this.emailField, this.emailBadgedInput],\n [this.firstNameField, this.firstNameBadgedInput],\n [this.lastNameField, this.lastNameBadgedInput],\n [this.regionField, this.regionBadgedInput],\n [this.localityField, this.localityBadgedInput],\n [this.streetAddressField, this.streetAddressBadgedInput],\n [this.postalCodeField, this.postalBadgedInput],\n ];\n\n let isValid = true;\n fieldBadgedInputs.forEach(([inputElement, badgedInput]) => {\n const fieldValid = inputElement.checkValidity();\n isValid = isValid && fieldValid;\n if (!fieldValid) {\n badgedInput.error = true;\n }\n });\n\n if (!isValid) {\n this.errorMessage.innerText = 'Please enter any missing or invalid contact information below';\n } else {\n this.errorMessage.innerText = '';\n }\n\n return isValid;\n }\n\n focus(): void {\n this.emailField.focus();\n }\n\n /** @inheritdoc */\n render(): TemplateResult {\n return html`\n <div id=\"donation-contact-form-error-message\"></div>\n <form>\n <fieldset>\n <div class=\"row\">\n ${this.generateInput({\n id: 'donation-contact-form-email',\n placeholder: 'Email',\n required: true,\n fieldType: 'email',\n name: 'email',\n autocomplete: 'email',\n minlength: 5,\n maxlength: 255,\n icon: emailImg,\n })}\n </div>\n </fieldset>\n\n <fieldset>\n <div class=\"row\">\n ${this.generateInput({\n id: 'donation-contact-form-first-name',\n placeholder: 'First name',\n name: 'fname',\n required: true,\n validationPattern: '.*\\\\S{2,}.*',\n maxlength: 255,\n autocomplete: 'given-name',\n icon: userIcon,\n })}\n </div>\n <div class=\"row\">\n ${this.generateInput({\n id: 'donation-contact-form-last-name',\n placeholder: 'Last name',\n name: 'lname',\n autocomplete: 'family-name',\n required: true,\n validationPattern: '.*\\\\S{2,}.*',\n maxlength: 255,\n })}\n </div>\n </fieldset>\n <fieldset>\n <div class=\"row\">\n ${this.generateInput({\n id: 'donation-contact-form-street-address',\n placeholder: 'Address Line 1',\n required: true,\n autocomplete: 'address-line1',\n icon: localePinImg,\n name: 'street-address',\n validationPattern: '.*?\\\\S.{2,}\\\\S.*?',\n })}\n </div>\n <div class=\"row\">\n ${this.generateInput({\n id: 'donation-contact-form-extended-address',\n placeholder: 'Address Line 2 (optional)',\n autocomplete: 'address-line2',\n required: false,\n name: 'extended-address',\n })}\n </div>\n <div class=\"row\">\n ${this.generateInput({\n id: 'donation-contact-form-locality',\n placeholder: 'City',\n autocomplete: 'address-level2',\n required: true,\n name: 'locality',\n validationPattern: '.*\\\\S{2,}.*',\n })}\n </div>\n <div class=\"row\">\n ${this.generateInput({\n id: 'donation-contact-form-region',\n placeholder: 'State / Province',\n autocomplete: 'address-level1',\n required: this.regionAndPostalCodeRequired,\n name: 'region',\n validationPattern: '.*\\\\S{2,}.*',\n })}\n ${this.generateInput({\n id: 'donation-contact-form-postal-code',\n placeholder: 'Zip / Postal',\n autocomplete: 'postal-code',\n required: this.regionAndPostalCodeRequired,\n name: 'postal',\n validationPattern: '^\\\\d{5}(-\\\\d{4})?$',\n iconSpaceOption: SpacerOption.CompressSpace,\n })}\n </div>\n <div class=\"row\">${this.countrySelectorTemplate}</div>\n </fieldset>\n </form>\n ${this.getStyles}\n `;\n }\n\n private get regionAndPostalCodeRequired(): boolean {\n return this.selectedCountry === 'US';\n }\n\n private get countrySelectorTemplate(): TemplateResult {\n return html`\n <badged-input>\n <select\n id=\"donation-contact-form-countryCodeAlpha2\"\n @change=${(e: Event) => {\n const newValue = (e.target as HTMLSelectElement).value;\n if (countries[newValue]) this.selectedCountry = newValue;\n }}\n >\n ${Object.keys(countries).map(key => {\n const name = countries[key];\n return html`\n <option value=${key} ?selected=${key === this.selectedCountry}>${name}</option>\n `;\n })}\n </select>\n </badged-input>\n `;\n }\n\n /** @inheritdoc */\n createRenderRoot(): this {\n // Render template without shadow DOM. Note that shadow DOM features like\n // encapsulated CSS and slots are unavailable.\n // Form autofill does not work properly in the shadow DOM\n // so we need our form fields in the light DOM\n return this;\n }\n\n // reset the error state when the user focuses the input\n private inputFocused(e: KeyboardEvent): void {\n this.errorMessage.innerText = '';\n const input = e.target as HTMLInputElement;\n const inputIdentifier = input.id;\n const badgedInput = this.querySelector(`badged-input.${inputIdentifier}`) as BadgedInput;\n badgedInput.error = false;\n }\n\n private generateInput(options: {\n id: string;\n placeholder: string;\n required?: boolean;\n fieldType?: 'text' | 'email';\n autocomplete?: AutoCompleteFieldOptions;\n minlength?: number;\n maxlength?: number;\n name: string;\n icon?: TemplateResult;\n iconSpaceOption?: SpacerOption;\n validationPattern?: string;\n }): TemplateResult {\n const required = options.required ?? true;\n const fieldType = options.fieldType ?? 'text';\n const iconOption = options.iconSpaceOption ?? SpacerOption.LeaveSpace;\n\n return html`\n <badged-input\n class=${options.id}\n .icon=${options.icon}\n .iconSpaceOption=${iconOption}\n ?required=${options.required}\n >\n <label for=${options.id}>${options.placeholder}</label>\n <input\n type=${fieldType}\n id=${options.id}\n class=\"donation-contact-form-input\"\n name=${options.name}\n aria-label=${options.placeholder}\n placeholder=${options.placeholder}\n maxlength=${ifDefined(options.maxlength)}\n minlength=${ifDefined(options.minlength)}\n autocomplete=${options.autocomplete ?? 'on'}\n pattern=${ifDefined(options.validationPattern)}\n @focus=${this.inputFocused}\n ?required=${required}\n />\n </badged-input>\n `;\n }\n\n get donorContactInfo(): DonorContactInfo {\n return new DonorContactInfo({\n billing: this.billingInfo,\n customer: this.contactInfo,\n });\n }\n\n get billingInfo(): BillingInfo {\n const billingInfo = new BillingInfo({\n streetAddress: this.streetAddressField.value,\n extendedAddress: this.extendedAddressField.value,\n locality: this.localityField.value,\n region: this.regionField.value,\n postalCode: this.postalCodeField.value,\n countryCodeAlpha2: this.countryCodeAlpha2Field.value,\n });\n return billingInfo;\n }\n\n get contactInfo(): CustomerInfo {\n return new CustomerInfo({\n email: this.emailField.value,\n firstName: this.firstNameField.value,\n lastName: this.lastNameField.value,\n });\n }\n\n /**\n * This is not the normal LitElement styles block.\n *\n * This element uses the clear DOM instead of the shadow DOM so it can't use\n * the shadowRoot's isolated styling. This is a bit of a workaround to keep all of\n * the styling local by writing out our own <style> tag and just be careful about\n * the selectors since they will leak outside of this component.\n *\n * @readonly\n * @private\n * @type {TemplateResult}\n * @memberof ContactForm\n */\n private get getStyles(): TemplateResult {\n const noIconSpacerWidth = css`var(--badgedInputNoIconSpacerWidth, 3rem)`;\n const iconSpacerWidth = css`var(--badgedInputIconSpacerWidth, 5rem)`;\n\n const fieldSetSpacing = css`var(--fieldSetSpacing, 1rem)`;\n const fieldFontFamily = css`var(--fontFamily, \"Helvetica Neue\", Helvetica, Arial, sans-serif)`;\n const fieldFontSize = css`var(--contactFieldFontSize, 1.6rem)`;\n const fieldFontColor = css`var(--inputFieldFontColor, #333)`;\n\n const iconFieldWidth = css`calc(100% - ${iconSpacerWidth})`;\n const noIconFieldWidth = css`calc(100% - ${noIconSpacerWidth})`;\n\n return html`\n <style>\n /*\n **NOTE**\n This element is in the lightDOM so be sure to prefix all styles\n with \"contact-form\" so styles don't leak.\n */\n contact-form fieldset {\n border: 0;\n padding: 0;\n margin: 0;\n margin-bottom: ${fieldSetSpacing};\n background-color: white;\n }\n\n /* These 1px and 0 margins in the next few selectors are to account for the\n double outlines caused by the fields being right next to each other */\n contact-form .row {\n display: flex;\n margin: -1px 0 0 0;\n }\n\n contact-form fieldset .row:first-child {\n margin-top: 0;\n }\n\n contact-form badged-input.donation-contact-form-region {\n width: 60%;\n }\n\n contact-form badged-input.donation-contact-form-postal-code {\n width: 40%;\n }\n\n contact-form #donation-contact-form-region {\n width: ${iconFieldWidth};\n }\n\n contact-form #donation-contact-form-postal-code {\n width: ${noIconFieldWidth};\n }\n\n contact-form #donation-contact-form-error-message {\n color: red;\n font-size: 1.4rem;\n margin-bottom: 0.6rem;\n }\n\n contact-form #donation-contact-form-last-name {\n width: ${noIconFieldWidth};\n }\n\n /* only show for screen readers */\n contact-form label {\n position: absolute;\n left: -10000px;\n top: auto;\n width: 1px;\n height: 1px;\n overflow: hidden;\n }\n\n contact-form .donation-contact-form-input {\n width: ${iconFieldWidth};\n border: 0;\n outline: 0;\n background: transparent;\n font-weight: bold;\n color: ${fieldFontColor};\n font-size: ${fieldFontSize};\n padding: 0;\n font-family: ${fieldFontFamily};\n }\n\n contact-form .donation-contact-form-input::placeholder {\n color: revert;\n }\n\n contact-form #donation-contact-form-countryCodeAlpha2 {\n width: calc(100%);\n height: 100%;\n box-sizing: border-box;\n font-weight: bold;\n font-size: ${fieldFontSize};\n font-family: ${fieldFontFamily};\n border: 0;\n background: #fff;\n }\n </style>\n `;\n }\n}\n"]}
@@ -48,8 +48,6 @@ export class GooglePayFlowHandler {
48
48
  lastName,
49
49
  });
50
50
  const billing = new BillingInfo({
51
- firstName,
52
- lastName,
53
51
  streetAddress: billingInfo === null || billingInfo === void 0 ? void 0 : billingInfo.address1,
54
52
  extendedAddress: billingInfo === null || billingInfo === void 0 ? void 0 : billingInfo.address2,
55
53
  locality: billingInfo === null || billingInfo === void 0 ? void 0 : billingInfo.locality,
@@ -1 +1 @@
1
- {"version":3,"file":"googlepay-flow-handler.js","sourceRoot":"","sources":["../../../../src/payment-flow-handlers/handlers/googlepay-flow-handler.ts"],"names":[],"mappings":";AACA,OAAO,EAEL,eAAe,EACf,YAAY,EACZ,WAAW,GACZ,MAAM,4CAA4C,CAAC;AAEpD,OAAO,EAAW,gBAAgB,EAAe,MAAM,YAAY,CAAC;AAcpE,MAAM,OAAO,oBAAoB;IAQ/B,YAAY,OAGX;QANO,YAAO,GACb,gBAAgB,EAA8B,CAAC;QAM/C,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;QACjD,IAAI,CAAC,wBAAwB,GAAG,OAAO,CAAC,wBAAwB,CAAC;IACnE,CAAC;IAED,EAAE,CACA,KAAQ,EACR,QAAuC;QAEvC,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC1C,CAAC;IAED,4CAA4C;IACtC,gBAAgB,CAAC,YAAiC;;;YACtD,MAAM,OAAO,GAAG,MAAM,CAAA,MAAA,IAAI,CAAC,gBAAgB,0CAAE,gBAAgB,CAAC,gBAAgB,CAAC,GAAG,EAAE,CAAA,CAAC;YACrF,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;YAE9C,MAAM,kBAAkB,GAAG,MAAM,QAAQ,CAAC,wBAAwB,CAAC;gBACjE,aAAa,EAAE,IAAI;gBACnB,eAAe,EAAE;oBACf,YAAY,EAAE,KAAK;oBACnB,gBAAgB,EAAE,OAAO;oBACzB,UAAU,EAAE,GAAG,YAAY,CAAC,KAAK,EAAE;iBACpC;aACF,CAAC,CAAC;YAEH,MAAM,iBAAiB,GAAG,kBAAkB,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;YACtE,iBAAiB,CAAC,UAAU,CAAC,sBAAsB,GAAG,IAAI,CAAC;YAC3D,iBAAiB,CAAC,UAAU,CAAC,wBAAwB,GAAG;gBACtD,MAAM,EAAE,MAAM;gBACd,mBAAmB,EAAE,KAAK;aAC3B,CAAC;YAEF,IAAI,CAAC;gBACH,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC,eAAe,CAAC,kBAAkB,CAAC,CAAC;gBACrF,MAAM,MAAM,GACV,MAAM,QAAQ,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;gBAE5C,MAAM,WAAW,GAAG,MAAA,WAAW,CAAC,iBAAiB,CAAC,IAAI,0CAAE,cAAc,CAAC;gBACvE,MAAM,IAAI,GAAG,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,IAAI,CAAC;gBAC/B,IAAI,SAAS,GAAuB,IAAI,CAAC;gBACzC,IAAI,QAAQ,GAAuB,EAAE,CAAC;gBACtC,MAAM,SAAS,GAAG,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,WAAW,CAAC,GAAG,CAAC,CAAC;gBACzC,IAAI,SAAS,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE,CAAC;oBAClC,SAAS,GAAG,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,MAAM,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;oBACvC,QAAQ,GAAG,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,MAAM,CAAC,SAAS,CAAC,CAAC;gBACrC,CAAC;gBAED,MAAM,QAAQ,GAAG,IAAI,YAAY,CAAC;oBAChC,KAAK,EAAE,WAAW,CAAC,KAAK;oBACxB,SAAS;oBACT,QAAQ;iBACT,CAAC,CAAC;gBAEH,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC;oBAC9B,SAAS;oBACT,QAAQ;oBACR,aAAa,EAAE,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,QAAQ;oBACpC,eAAe,EAAE,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,QAAQ;oBACtC,QAAQ,EAAE,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,QAAQ;oBAC/B,MAAM,EAAE,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,kBAAkB;oBACvC,UAAU,EAAE,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,UAAU;oBACnC,iBAAiB,EAAE,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,WAAW;iBAC5C,CAAC,CAAC;gBAEH,IAAI,CAAC,wBAAwB,CAAC,2BAA2B,CAAC;oBACxD,KAAK,EAAE,MAAM,CAAC,KAAK;oBACnB,eAAe,EAAE,eAAe,CAAC,SAAS;oBAC1C,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG;oBACvB,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW;oBACnC,YAAY,EAAE,YAAY;oBAC1B,YAAY,EAAE,QAAQ;oBACtB,WAAW,EAAE,OAAO;iBACrB,CAAC,CAAC;YACL,CAAC;YAAC,WAAM,CAAC;gBACP,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;gBACtC,IAAI,CAAC,wBAAwB,CAAC,UAAU,EAAE,CAAC;YAC7C,CAAC;QACH,CAAC;KAAA;CACF","sourcesContent":["import { BraintreeManagerInterface } from '../../braintree-manager/braintree-interfaces';\nimport {\n DonationPaymentInfo,\n PaymentProvider,\n CustomerInfo,\n BillingInfo,\n} from '@internetarchive/donation-form-data-models';\nimport { DonationFlowModalManagerInterface } from '../donation-flow-modal-manager';\nimport { Emitter, createNanoEvents, Unsubscribe } from 'nanoevents';\n\nexport interface GooglePayFlowHandlerInterface {\n paymentInitiated(donationInfo: DonationPaymentInfo): Promise<void>;\n on<E extends keyof GooglePayFlowHandlerEvents>(\n event: E,\n callback: GooglePayFlowHandlerEvents[E],\n ): Unsubscribe;\n}\n\nexport interface GooglePayFlowHandlerEvents {\n paymentCancelled: () => void;\n}\n\nexport class GooglePayFlowHandler implements GooglePayFlowHandlerInterface {\n private donationFlowModalManager: DonationFlowModalManagerInterface;\n\n private braintreeManager: BraintreeManagerInterface;\n\n private emitter: Emitter<GooglePayFlowHandlerEvents> =\n createNanoEvents<GooglePayFlowHandlerEvents>();\n\n constructor(options: {\n braintreeManager: BraintreeManagerInterface;\n donationFlowModalManager: DonationFlowModalManagerInterface;\n }) {\n this.braintreeManager = options.braintreeManager;\n this.donationFlowModalManager = options.donationFlowModalManager;\n }\n\n on<E extends keyof GooglePayFlowHandlerEvents>(\n event: E,\n callback: GooglePayFlowHandlerEvents[E],\n ): Unsubscribe {\n return this.emitter.on(event, callback);\n }\n\n // GooglePayFlowHandlerInterface conformance\n async paymentInitiated(donationInfo: DonationPaymentInfo): Promise<void> {\n const handler = await this.braintreeManager?.paymentProviders.googlePayHandler.get();\n const instance = await handler.instance.get();\n\n const paymentDataRequest = await instance.createPaymentDataRequest({\n emailRequired: true,\n transactionInfo: {\n currencyCode: 'USD',\n totalPriceStatus: 'FINAL',\n totalPrice: `${donationInfo.total}`,\n },\n });\n\n const cardPaymentMethod = paymentDataRequest.allowedPaymentMethods[0];\n cardPaymentMethod.parameters.billingAddressRequired = true;\n cardPaymentMethod.parameters.billingAddressParameters = {\n format: 'FULL',\n phoneNumberRequired: false,\n };\n\n try {\n const paymentData = await handler.paymentsClient.loadPaymentData(paymentDataRequest);\n const result: braintree.GooglePaymentTokenizePayload =\n await instance.parseResponse(paymentData);\n\n const billingInfo = paymentData.paymentMethodData.info?.billingAddress;\n const name = billingInfo?.name;\n let firstName: string | undefined = name;\n let lastName: string | undefined = '';\n const lastSpace = name?.lastIndexOf(' ');\n if (lastSpace && lastSpace !== -1) {\n firstName = name?.substr(0, lastSpace);\n lastName = name?.substr(lastSpace);\n }\n\n const customer = new CustomerInfo({\n email: paymentData.email,\n firstName,\n lastName,\n });\n\n const billing = new BillingInfo({\n firstName,\n lastName,\n streetAddress: billingInfo?.address1,\n extendedAddress: billingInfo?.address2,\n locality: billingInfo?.locality,\n region: billingInfo?.administrativeArea,\n postalCode: billingInfo?.postalCode,\n countryCodeAlpha2: billingInfo?.countryCode,\n });\n\n this.donationFlowModalManager.startDonationSubmissionFlow({\n nonce: result.nonce,\n paymentProvider: PaymentProvider.GooglePay,\n bin: result.details.bin,\n binName: result.binData.issuingBank,\n donationInfo: donationInfo,\n customerInfo: customer,\n billingInfo: billing,\n });\n } catch {\n this.emitter.emit('paymentCancelled');\n this.donationFlowModalManager.closeModal();\n }\n }\n}\n"]}
1
+ {"version":3,"file":"googlepay-flow-handler.js","sourceRoot":"","sources":["../../../../src/payment-flow-handlers/handlers/googlepay-flow-handler.ts"],"names":[],"mappings":"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","sourcesContent":["import { BraintreeManagerInterface } from '../../braintree-manager/braintree-interfaces';\nimport {\n DonationPaymentInfo,\n PaymentProvider,\n CustomerInfo,\n BillingInfo,\n} from '@internetarchive/donation-form-data-models';\nimport { DonationFlowModalManagerInterface } from '../donation-flow-modal-manager';\nimport { Emitter, createNanoEvents, Unsubscribe } from 'nanoevents';\n\nexport interface GooglePayFlowHandlerInterface {\n paymentInitiated(donationInfo: DonationPaymentInfo): Promise<void>;\n on<E extends keyof GooglePayFlowHandlerEvents>(\n event: E,\n callback: GooglePayFlowHandlerEvents[E],\n ): Unsubscribe;\n}\n\nexport interface GooglePayFlowHandlerEvents {\n paymentCancelled: () => void;\n}\n\nexport class GooglePayFlowHandler implements GooglePayFlowHandlerInterface {\n private donationFlowModalManager: DonationFlowModalManagerInterface;\n\n private braintreeManager: BraintreeManagerInterface;\n\n private emitter: Emitter<GooglePayFlowHandlerEvents> =\n createNanoEvents<GooglePayFlowHandlerEvents>();\n\n constructor(options: {\n braintreeManager: BraintreeManagerInterface;\n donationFlowModalManager: DonationFlowModalManagerInterface;\n }) {\n this.braintreeManager = options.braintreeManager;\n this.donationFlowModalManager = options.donationFlowModalManager;\n }\n\n on<E extends keyof GooglePayFlowHandlerEvents>(\n event: E,\n callback: GooglePayFlowHandlerEvents[E],\n ): Unsubscribe {\n return this.emitter.on(event, callback);\n }\n\n // GooglePayFlowHandlerInterface conformance\n async paymentInitiated(donationInfo: DonationPaymentInfo): Promise<void> {\n const handler = await this.braintreeManager?.paymentProviders.googlePayHandler.get();\n const instance = await handler.instance.get();\n\n const paymentDataRequest = await instance.createPaymentDataRequest({\n emailRequired: true,\n transactionInfo: {\n currencyCode: 'USD',\n totalPriceStatus: 'FINAL',\n totalPrice: `${donationInfo.total}`,\n },\n });\n\n const cardPaymentMethod = paymentDataRequest.allowedPaymentMethods[0];\n cardPaymentMethod.parameters.billingAddressRequired = true;\n cardPaymentMethod.parameters.billingAddressParameters = {\n format: 'FULL',\n phoneNumberRequired: false,\n };\n\n try {\n const paymentData = await handler.paymentsClient.loadPaymentData(paymentDataRequest);\n const result: braintree.GooglePaymentTokenizePayload =\n await instance.parseResponse(paymentData);\n\n const billingInfo = paymentData.paymentMethodData.info?.billingAddress;\n const name = billingInfo?.name;\n let firstName: string | undefined = name;\n let lastName: string | undefined = '';\n const lastSpace = name?.lastIndexOf(' ');\n if (lastSpace && lastSpace !== -1) {\n firstName = name?.substr(0, lastSpace);\n lastName = name?.substr(lastSpace);\n }\n\n const customer = new CustomerInfo({\n email: paymentData.email,\n firstName,\n lastName,\n });\n\n const billing = new BillingInfo({\n streetAddress: billingInfo?.address1,\n extendedAddress: billingInfo?.address2,\n locality: billingInfo?.locality,\n region: billingInfo?.administrativeArea,\n postalCode: billingInfo?.postalCode,\n countryCodeAlpha2: billingInfo?.countryCode,\n });\n\n this.donationFlowModalManager.startDonationSubmissionFlow({\n nonce: result.nonce,\n paymentProvider: PaymentProvider.GooglePay,\n bin: result.details.bin,\n binName: result.binData.issuingBank,\n donationInfo: donationInfo,\n customerInfo: customer,\n billingInfo: billing,\n });\n } catch {\n this.emitter.emit('paymentCancelled');\n this.donationFlowModalManager.closeModal();\n }\n }\n}\n"]}
@@ -81,8 +81,6 @@ export class PayPalFlowHandler {
81
81
  });
82
82
  const shippingAddress = details.shippingAddress;
83
83
  const billingInfo = new BillingInfo({
84
- firstName: details === null || details === void 0 ? void 0 : details.firstName,
85
- lastName: details === null || details === void 0 ? void 0 : details.lastName,
86
84
  streetAddress: shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.line1,
87
85
  extendedAddress: shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.line2,
88
86
  locality: shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.city,
@@ -1 +1 @@
1
- {"version":3,"file":"paypal-flow-handler.js","sourceRoot":"","sources":["../../../../src/payment-flow-handlers/handlers/paypal-flow-handler.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,gBAAgB,EAAwB,MAAM,YAAY,CAAC;AAMpE,OAAO,EAEL,YAAY,EACZ,mBAAmB,EAEnB,YAAY,EACZ,WAAW,EACX,eAAe,GAEhB,MAAM,4CAA4C,CAAC;AAGpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAEL,wBAAwB,GACzB,MAAM,gCAAgC,CAAC;AAYxC;;;;GAIG;AACH,MAAM,yBAAyB;IAK7B,YAAY,OAIX;QACC,IAAI,CAAC,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC;QAC7D,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;QAC7C,IAAI,CAAC,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAC/D,CAAC;CACF;AASD;;;;;;;GAOG;AACH,MAAM,OAAO,iBAAiB;IAa5B,kBAAkB,CAAC,YAAiC;QAClD,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,IAAI,CAAC,gBAAgB,CAAC,YAAY,GAAG,YAAY,CAAC;QACpD,CAAC;IACH,CAAC;IAED,wBAAwB,CAAC,YAAiC;QACxD,IAAI,IAAI,CAAC,+BAA+B,EAAE,CAAC;YACzC,IAAI,CAAC,+BAA+B,CAAC,sBAAsB,CAAC,YAAY,GAAG,YAAY,CAAC;QAC1F,CAAC;IACH,CAAC;IAED,YAAY,OAGX;QAjBO,YAAO,GAAqC,gBAAgB,EAA2B,CAAC;QAkB9F,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;QACjD,IAAI,CAAC,wBAAwB,GAAG,OAAO,CAAC,wBAAwB,CAAC;IACnE,CAAC;IAED,EAAE,CACA,KAAQ,EACR,QAAoC;QAEpC,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC1C,CAAC;IAEK,oBAAoB,CACxB,UAA2C,EAE3C,OAAe;;YAEf,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,sBAAsB,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;QACjE,CAAC;KAAA;IAED;;;OAGG;IACG,uBAAuB,CAC3B,UAA2C,EAC3C,OAA+B;;YAE/B,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC,YAAY,CAAC;YACxD,IAAI,CAAC,wBAAwB,CAAC,yBAAyB,CAAC;gBACtD,YAAY;gBACZ,MAAM,EAAE,KAAK;gBACb,YAAY,EAAE,KAAK,EAAE,0BAA0B;gBAC/C,iBAAiB,EAAE,GAAG,EAAE;oBACtB,IAAI,CAAC,sBAAsB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;gBACnD,CAAC;gBACD,gBAAgB,EAAE,GAAG,EAAE;oBACrB,IAAI,CAAC,wBAAwB,CAAC,UAAU,EAAE,CAAC;oBAC3C,IAAI,CAAC,sBAAsB,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;gBAC9C,CAAC;aACF,CAAC,CAAC;QACL,CAAC;KAAA;IAEK,sBAAsB,CAC1B,UAA2C,EAC3C,OAA+B;;YAE/B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,wBAAwB,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;YAC5D,IAAI,CAAC,wBAAwB,CAAC,mBAAmB,EAAE,CAAC;YAEpD,MAAM,YAAY,GAAG,UAAU,CAAC,YAAY,CAAC,YAAY,CAAC;YAE1D,MAAM,OAAO,GAAG,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,CAAC;YAEjC,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC;gBACpC,KAAK,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,KAAK;gBACrB,SAAS,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS;gBAC7B,QAAQ,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,QAAQ;aAC5B,CAAC,CAAC;YAEH,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;YAEhD,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC;gBAClC,SAAS,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS;gBAC7B,QAAQ,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,QAAQ;gBAC3B,aAAa,EAAE,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,KAAK;gBACrC,eAAe,EAAE,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,KAAK;gBACvC,QAAQ,EAAE,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,IAAI;gBAC/B,MAAM,EAAE,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,KAAK;gBAC9B,UAAU,EAAE,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,UAAU;gBACvC,iBAAiB,EAAE,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,WAAW;aAChD,CAAC,CAAC;YAEH,MAAM,kBAAkB,GAAG,IAAI,CAAC,+BAA+B;gBAC7D,CAAC,CAAC,IAAI,CAAC,+BAA+B,CAAC,sBAAsB,CAAC,cAAc;gBAC5E,CAAC,CAAC,SAAS,CAAC;YAEd,MAAM,QAAQ,GAAqB,MAAM,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC;gBAC5E,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,eAAe,EAAE,eAAe,CAAC,MAAM;gBACvC,YAAY,EAAE,UAAU,CAAC,YAAY;gBACrC,YAAY,EAAE,YAAY;gBAC1B,WAAW,EAAE,WAAW;gBACxB,0BAA0B,EAAE,kBAAkB;aAC/C,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACtB,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAsB,CAAC;gBAC9C,IAAI,CAAC,wBAAwB,CAAC,cAAc,CAAC;oBAC3C,OAAO,EAAE,KAAK,CAAC,OAAO;iBACvB,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,MAAM,eAAe,GAAG,QAAQ,CAAC,KAAwB,CAAC;YAE1D,QAAQ,YAAY,EAAE,CAAC;gBACrB,KAAK,YAAY,CAAC,OAAO;oBACvB,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;oBAC/C,MAAM;gBACR,KAAK,YAAY,CAAC,OAAO;oBACvB,2BAA2B;oBAC3B,IAAI,CAAC,wBAAwB,CAAC,iBAAiB,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC;oBACrE,MAAM;gBACR,KAAK,YAAY,CAAC,MAAM;oBACtB,IAAI,IAAI,CAAC,+BAA+B,EAAE,CAAC;wBACzC,IAAI,CAAC,wBAAwB,CAAC,iBAAiB,CAAC;4BAC9C,eAAe,EAAE,IAAI,CAAC,+BAA+B,CAAC,sBAAsB;4BAC5E,qBAAqB,EAAE,eAAe;yBACvC,CAAC,CAAC;oBACL,CAAC;yBAAM,CAAC;wBACN,yFAAyF;wBACzF,IAAI,CAAC,wBAAwB,CAAC,cAAc,CAAC;4BAC3C,OAAO,EAAE,mCAAmC;yBAC7C,CAAC,CAAC;oBACL,CAAC;oBACD,MAAM;YACV,CAAC;QACH,CAAC;KAAA;IAEK,sBAAsB,CAC1B,UAA2C,EAE3C,IAAY;;YAEZ,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,wBAAwB,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;QAChE,CAAC;KAAA;IAEK,kBAAkB,CACtB,UAA2C,EAC3C,KAAa;;YAEb,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,oBAAoB,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;YAC3D,OAAO,CAAC,KAAK,CACX,yCAAyC,EACzC,UAAU,EACV,UAAU,CAAC,YAAY,EACvB,KAAK,CACN,CAAC;QACJ,CAAC;KAAA;IAEK,kBAAkB,CAAC,YAAiC;;;YACxD,MAAM,OAAO,GAAG,MAAM,CAAA,MAAA,IAAI,CAAC,gBAAgB,0CAAE,gBAAgB,CAAC,aAAa,CAAC,GAAG,EAAE,CAAA,CAAC;YAElF,IAAI,CAAC,gBAAgB,GAAG,MAAM,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,kBAAkB,CAAC;gBACxD,QAAQ,EAAE,gBAAgB;gBAC1B,KAAK,EAAE;oBACL,KAAK,EAAE,MAAkC,EAAE,6EAA6E;oBACxH,KAAK,EAAE,QAAoC;oBAC3C,KAAK,EAAE,MAAkC;oBACzC,IAAI,EAAE,QAAmC;oBACzC,OAAO,EAAE,KAAK;iBACf;gBACD,YAAY,EAAE,YAAY;aAC3B,CAAC,CAAA,CAAC;YAEH,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBAC1B,IAAI,CAAC,gBAAgB,CAAC,QAAQ,GAAG,IAAI,CAAC;YACxC,CAAC;QACH,CAAC;KAAA;IAEa,eAAe,CAC3B,cAAsC,EACtC,sBAAuC;;YAEvC,IAAI,CAAC,wBAAwB,CAAC,eAAe,CAAC;gBAC5C,aAAa,EAAE,sBAAsB,CAAC,MAAM;gBAC5C,aAAa,EAAE,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC;gBAClD,UAAU,EAAE,GAAG,EAAE;oBACf,IAAI,CAAC,wBAAwB,CAAC,iBAAiB,CAAC;wBAC9C,eAAe,EAAE,sBAAsB;qBACxC,CAAC,CAAC;gBACL,CAAC;gBACD,OAAO,EAAE,kBAAkB,CAAC,gBAAgB;gBAC5C,uBAAuB,EAAE,GAAG,EAAE;oBAC5B,IAAI,CAAC,wBAAwB,CAAC,iBAAiB,CAAC;wBAC9C,eAAe,EAAE,sBAAsB;qBACxC,CAAC,CAAC;gBACL,CAAC;aACF,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,wBAAwB,CAAC,sBAAsB,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC;YAE9F,MAAM,kBAAkB,GAAG,IAAI,mBAAmB,CAAC;gBACjD,MAAM,EAAE,MAAM;gBACd,YAAY,EAAE,YAAY,CAAC,MAAM;gBACjC,SAAS,EAAE,KAAK;aACjB,CAAC,CAAC;YAEH,IAAI,CAAC,IAAI,CAAC,+BAA+B,EAAE,CAAC;gBAC1C,IAAI,CAAC,wBAAwB,CAAC;oBAC5B,YAAY,EAAE,kBAAkB;oBAChC,cAAc;oBACd,sBAAsB;iBACvB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;KAAA;IAEO,mBAAmB,CAAC,MAAc;QACxC,IAAI,IAAI,CAAC,+BAA+B,EAAE,CAAC;YACzC,IAAI,CAAC,+BAA+B,CAAC,sBAAsB,CAAC,YAAY,CAAC,MAAM,GAAG,MAAM,CAAC;QAC3F,CAAC;IACH,CAAC;IAEa,wBAAwB,CAAC,OAItC;;;YACC,MAAM,OAAO,GAAG,MAAM,CAAA,MAAA,IAAI,CAAC,gBAAgB,0CAAE,gBAAgB,CAAC,aAAa,CAAC,GAAG,EAAE,CAAA,CAAC;YAElF,MAAM,sBAAsB,GAAG,MAAM,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,kBAAkB,CAAC;gBAC/D,QAAQ,EAAE,uBAAuB;gBACjC,KAAK,EAAE;oBACL,KAAK,EAAE,MAAkC;oBACzC,KAAK,EAAE,QAAoC;oBAC3C,KAAK,EAAE,MAAkC;oBACzC,IAAI,EAAE,YAAuC;oBAC7C,OAAO,EAAE,KAAK;iBACf;gBACD,YAAY,EAAE,OAAO,CAAC,YAAY;aACnC,CAAC,CAAA,CAAC;YAEH,IAAI,sBAAsB,EAAE,CAAC;gBAC3B,sBAAsB,CAAC,QAAQ,GAAG,IAAI,CAAC;gBACvC,IAAI,CAAC,+BAA+B,GAAG,IAAI,yBAAyB,CAAC;oBACnE,sBAAsB,EAAE,sBAAsB;oBAC9C,cAAc,EAAE,OAAO,CAAC,cAAc;oBACtC,sBAAsB,EAAE,OAAO,CAAC,sBAAsB;iBACvD,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;KAAA;CACF","sourcesContent":["import { createNanoEvents, Emitter, Unsubscribe } from 'nanoevents';\n\nimport {\n PayPalButtonDataSourceInterface,\n PayPalButtonDataSourceDelegate,\n} from '../../braintree-manager/payment-providers/paypal/paypal-button-datasource';\nimport {\n DonationResponse,\n DonationType,\n DonationPaymentInfo,\n SuccessResponse,\n CustomerInfo,\n BillingInfo,\n PaymentProvider,\n ErrorResponse,\n} from '@internetarchive/donation-form-data-models';\nimport { BraintreeManagerInterface } from '../../braintree-manager/braintree-interfaces';\n\nimport { UpsellModalCTAMode } from '../../modals/upsell-modal-content';\nimport {\n DonationFlowModalManagerInterface,\n DonationFlowModalManager,\n} from '../donation-flow-modal-manager';\n\nexport interface PayPalFlowHandlerInterface {\n updateDonationInfo(donationInfo: DonationPaymentInfo): void;\n updateUpsellDonationInfo(donationInfo: DonationPaymentInfo): void;\n renderPayPalButton(donationInfo: DonationPaymentInfo): Promise<void>;\n on<E extends keyof PayPalFlowHandlerEvents>(\n event: E,\n callback: PayPalFlowHandlerEvents[E],\n ): Unsubscribe;\n}\n\n/**\n * This is a class to combine the data from the one-time purchase to the upsell\n *\n * @class UpsellDataSourceContainer\n */\nclass UpsellDataSourceContainer {\n upsellButtonDataSource: PayPalButtonDataSourceInterface;\n oneTimePayload: paypal.TokenizePayload;\n oneTimeSuccessResponse: SuccessResponse;\n\n constructor(options: {\n upsellButtonDataSource: PayPalButtonDataSourceInterface;\n oneTimePayload: paypal.TokenizePayload;\n oneTimeSuccessResponse: SuccessResponse;\n }) {\n this.upsellButtonDataSource = options.upsellButtonDataSource;\n this.oneTimePayload = options.oneTimePayload;\n this.oneTimeSuccessResponse = options.oneTimeSuccessResponse;\n }\n}\n\nexport interface PayPalFlowHandlerEvents {\n payPalPaymentStarted: (dataSource: PayPalButtonDataSourceInterface, options: object) => void;\n payPalPaymentCancelled: (dataSource: PayPalButtonDataSourceInterface, data: object) => void;\n payPalPaymentError: (dataSource: PayPalButtonDataSourceInterface, error: string) => void;\n payPalPaymentConfirmed: (dataSource: PayPalButtonDataSourceInterface, data: object) => void;\n}\n\n/**\n * This class manages the user-flow for PayPal.\n *\n * @export\n * @class PayPalFlowHandler\n * @implements {PayPalFlowHandlerInterface}\n * @implements {PayPalButtonDataSourceDelegate}\n */\nexport class PayPalFlowHandler\n implements PayPalFlowHandlerInterface, PayPalButtonDataSourceDelegate\n{\n private upsellButtonDataSourceContainer?: UpsellDataSourceContainer;\n\n private buttonDataSource?: PayPalButtonDataSourceInterface;\n\n private donationFlowModalManager: DonationFlowModalManagerInterface;\n\n private braintreeManager: BraintreeManagerInterface;\n\n private emitter: Emitter<PayPalFlowHandlerEvents> = createNanoEvents<PayPalFlowHandlerEvents>();\n\n updateDonationInfo(donationInfo: DonationPaymentInfo): void {\n if (this.buttonDataSource) {\n this.buttonDataSource.donationInfo = donationInfo;\n }\n }\n\n updateUpsellDonationInfo(donationInfo: DonationPaymentInfo): void {\n if (this.upsellButtonDataSourceContainer) {\n this.upsellButtonDataSourceContainer.upsellButtonDataSource.donationInfo = donationInfo;\n }\n }\n\n constructor(options: {\n braintreeManager: BraintreeManagerInterface;\n donationFlowModalManager: DonationFlowModalManagerInterface;\n }) {\n this.braintreeManager = options.braintreeManager;\n this.donationFlowModalManager = options.donationFlowModalManager;\n }\n\n on<E extends keyof PayPalFlowHandlerEvents>(\n event: E,\n callback: PayPalFlowHandlerEvents[E],\n ): Unsubscribe {\n return this.emitter.on(event, callback);\n }\n\n async payPalPaymentStarted(\n dataSource: PayPalButtonDataSourceInterface,\n\n options: object,\n ): Promise<void> {\n this.emitter.emit('payPalPaymentStarted', dataSource, options);\n }\n\n /**\n * Once we have the dataSource & payload, we ask patron to confirm donation.\n * Once confirmed, we move forward to: `payPalPaymentConfirmed`\n */\n async payPalPaymentAuthorized(\n dataSource: PayPalButtonDataSourceInterface,\n payload: paypal.TokenizePayload,\n ): Promise<void> {\n const { donationType, total } = dataSource.donationInfo;\n this.donationFlowModalManager.showConfirmationStepModal({\n donationType,\n amount: total,\n currencyType: 'USD', // defaults to USD for now\n confirmDonationCB: () => {\n this.payPalPaymentConfirmed(dataSource, payload);\n },\n cancelDonationCB: () => {\n this.donationFlowModalManager.closeModal();\n this.payPalPaymentCancelled(dataSource, {});\n },\n });\n }\n\n async payPalPaymentConfirmed(\n dataSource: PayPalButtonDataSourceInterface,\n payload: paypal.TokenizePayload,\n ): Promise<void> {\n this.emitter.emit('payPalPaymentConfirmed', dataSource, {});\n this.donationFlowModalManager.showProcessingModal();\n\n const donationType = dataSource.donationInfo.donationType;\n\n const details = payload?.details;\n\n const customerInfo = new CustomerInfo({\n email: details?.email,\n firstName: details?.firstName,\n lastName: details?.lastName,\n });\n\n const shippingAddress = details.shippingAddress;\n\n const billingInfo = new BillingInfo({\n firstName: details?.firstName,\n lastName: details?.lastName,\n streetAddress: shippingAddress?.line1,\n extendedAddress: shippingAddress?.line2,\n locality: shippingAddress?.city,\n region: shippingAddress?.state,\n postalCode: shippingAddress?.postalCode,\n countryCodeAlpha2: shippingAddress?.countryCode,\n });\n\n const oneTimeTransaction = this.upsellButtonDataSourceContainer\n ? this.upsellButtonDataSourceContainer.oneTimeSuccessResponse.transaction_id\n : undefined;\n\n const response: DonationResponse = await this.braintreeManager.submitDonation({\n nonce: payload.nonce,\n paymentProvider: PaymentProvider.PayPal,\n donationInfo: dataSource.donationInfo,\n customerInfo: customerInfo,\n billingInfo: billingInfo,\n upsellOnetimeTransactionId: oneTimeTransaction,\n });\n\n if (!response.success) {\n const error = response.value as ErrorResponse;\n this.donationFlowModalManager.showErrorModal({\n message: error.message,\n });\n return;\n }\n\n const successResponse = response.value as SuccessResponse;\n\n switch (donationType) {\n case DonationType.OneTime:\n this.showUpsellModal(payload, successResponse);\n break;\n case DonationType.Monthly:\n // show thank you, redirect\n this.donationFlowModalManager.showThankYouModal({ successResponse });\n break;\n case DonationType.Upsell:\n if (this.upsellButtonDataSourceContainer) {\n this.donationFlowModalManager.showThankYouModal({\n successResponse: this.upsellButtonDataSourceContainer.oneTimeSuccessResponse,\n upsellSuccessResponse: successResponse,\n });\n } else {\n // we're in the upsell flow, but no upsell data source container.. this should not happen\n this.donationFlowModalManager.showErrorModal({\n message: 'Error setting up monthly donation',\n });\n }\n break;\n }\n }\n\n async payPalPaymentCancelled(\n dataSource: PayPalButtonDataSourceInterface,\n\n data: object,\n ): Promise<void> {\n this.emitter.emit('payPalPaymentCancelled', dataSource, data);\n }\n\n async payPalPaymentError(\n dataSource: PayPalButtonDataSourceInterface,\n error: string,\n ): Promise<void> {\n this.emitter.emit('payPalPaymentError', dataSource, error);\n console.error(\n 'PaymentSector:payPalPaymentError error:',\n dataSource,\n dataSource.donationInfo,\n error,\n );\n }\n\n async renderPayPalButton(donationInfo: DonationPaymentInfo): Promise<void> {\n const handler = await this.braintreeManager?.paymentProviders.paypalHandler.get();\n\n this.buttonDataSource = await handler?.renderPayPalButton({\n selector: '#paypal-button',\n style: {\n color: 'blue' as paypal.ButtonColorOption, // I'm not sure why I can't access the enum directly here.. I get a UMD error\n label: 'paypal' as paypal.ButtonLabelOption,\n shape: 'rect' as paypal.ButtonShapeOption,\n size: 'medium' as paypal.ButtonSizeOption,\n tagline: false,\n },\n donationInfo: donationInfo,\n });\n\n if (this.buttonDataSource) {\n this.buttonDataSource.delegate = this;\n }\n }\n\n private async showUpsellModal(\n oneTimePayload: paypal.TokenizePayload,\n oneTimeSuccessResponse: SuccessResponse,\n ): Promise<void> {\n this.donationFlowModalManager.showUpsellModal({\n oneTimeAmount: oneTimeSuccessResponse.amount,\n amountChanged: this.upsellAmountChanged.bind(this),\n noSelected: () => {\n this.donationFlowModalManager.showThankYouModal({\n successResponse: oneTimeSuccessResponse,\n });\n },\n ctaMode: UpsellModalCTAMode.PayPalUpsellSlot,\n userClosedModalCallback: () => {\n this.donationFlowModalManager.showThankYouModal({\n successResponse: oneTimeSuccessResponse,\n });\n },\n });\n\n const amount = DonationFlowModalManager.getDefaultUpsellAmount(oneTimeSuccessResponse.amount);\n\n const upsellDonationInfo = new DonationPaymentInfo({\n amount: amount,\n donationType: DonationType.Upsell,\n coverFees: false,\n });\n\n if (!this.upsellButtonDataSourceContainer) {\n this.renderUpsellPayPalButton({\n donationInfo: upsellDonationInfo,\n oneTimePayload,\n oneTimeSuccessResponse,\n });\n }\n }\n\n private upsellAmountChanged(amount: number): void {\n if (this.upsellButtonDataSourceContainer) {\n this.upsellButtonDataSourceContainer.upsellButtonDataSource.donationInfo.amount = amount;\n }\n }\n\n private async renderUpsellPayPalButton(options: {\n donationInfo: DonationPaymentInfo;\n oneTimePayload: paypal.TokenizePayload;\n oneTimeSuccessResponse: SuccessResponse;\n }): Promise<void> {\n const handler = await this.braintreeManager?.paymentProviders.paypalHandler.get();\n\n const upsellButtonDataSource = await handler?.renderPayPalButton({\n selector: '#paypal-upsell-button',\n style: {\n color: 'blue' as paypal.ButtonColorOption,\n label: 'paypal' as paypal.ButtonLabelOption,\n shape: 'rect' as paypal.ButtonShapeOption,\n size: 'responsive' as paypal.ButtonSizeOption,\n tagline: false,\n },\n donationInfo: options.donationInfo,\n });\n\n if (upsellButtonDataSource) {\n upsellButtonDataSource.delegate = this;\n this.upsellButtonDataSourceContainer = new UpsellDataSourceContainer({\n upsellButtonDataSource: upsellButtonDataSource,\n oneTimePayload: options.oneTimePayload,\n oneTimeSuccessResponse: options.oneTimeSuccessResponse,\n });\n } else {\n console.error('error rendering paypal upsell button');\n }\n }\n}\n"]}
1
+ {"version":3,"file":"paypal-flow-handler.js","sourceRoot":"","sources":["../../../../src/payment-flow-handlers/handlers/paypal-flow-handler.ts"],"names":[],"mappings":"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","sourcesContent":["import { createNanoEvents, Emitter, Unsubscribe } from 'nanoevents';\n\nimport {\n PayPalButtonDataSourceInterface,\n PayPalButtonDataSourceDelegate,\n} from '../../braintree-manager/payment-providers/paypal/paypal-button-datasource';\nimport {\n DonationResponse,\n DonationType,\n DonationPaymentInfo,\n SuccessResponse,\n CustomerInfo,\n BillingInfo,\n PaymentProvider,\n ErrorResponse,\n} from '@internetarchive/donation-form-data-models';\nimport { BraintreeManagerInterface } from '../../braintree-manager/braintree-interfaces';\n\nimport { UpsellModalCTAMode } from '../../modals/upsell-modal-content';\nimport {\n DonationFlowModalManagerInterface,\n DonationFlowModalManager,\n} from '../donation-flow-modal-manager';\n\nexport interface PayPalFlowHandlerInterface {\n updateDonationInfo(donationInfo: DonationPaymentInfo): void;\n updateUpsellDonationInfo(donationInfo: DonationPaymentInfo): void;\n renderPayPalButton(donationInfo: DonationPaymentInfo): Promise<void>;\n on<E extends keyof PayPalFlowHandlerEvents>(\n event: E,\n callback: PayPalFlowHandlerEvents[E],\n ): Unsubscribe;\n}\n\n/**\n * This is a class to combine the data from the one-time purchase to the upsell\n *\n * @class UpsellDataSourceContainer\n */\nclass UpsellDataSourceContainer {\n upsellButtonDataSource: PayPalButtonDataSourceInterface;\n oneTimePayload: paypal.TokenizePayload;\n oneTimeSuccessResponse: SuccessResponse;\n\n constructor(options: {\n upsellButtonDataSource: PayPalButtonDataSourceInterface;\n oneTimePayload: paypal.TokenizePayload;\n oneTimeSuccessResponse: SuccessResponse;\n }) {\n this.upsellButtonDataSource = options.upsellButtonDataSource;\n this.oneTimePayload = options.oneTimePayload;\n this.oneTimeSuccessResponse = options.oneTimeSuccessResponse;\n }\n}\n\nexport interface PayPalFlowHandlerEvents {\n payPalPaymentStarted: (dataSource: PayPalButtonDataSourceInterface, options: object) => void;\n payPalPaymentCancelled: (dataSource: PayPalButtonDataSourceInterface, data: object) => void;\n payPalPaymentError: (dataSource: PayPalButtonDataSourceInterface, error: string) => void;\n payPalPaymentConfirmed: (dataSource: PayPalButtonDataSourceInterface, data: object) => void;\n}\n\n/**\n * This class manages the user-flow for PayPal.\n *\n * @export\n * @class PayPalFlowHandler\n * @implements {PayPalFlowHandlerInterface}\n * @implements {PayPalButtonDataSourceDelegate}\n */\nexport class PayPalFlowHandler\n implements PayPalFlowHandlerInterface, PayPalButtonDataSourceDelegate\n{\n private upsellButtonDataSourceContainer?: UpsellDataSourceContainer;\n\n private buttonDataSource?: PayPalButtonDataSourceInterface;\n\n private donationFlowModalManager: DonationFlowModalManagerInterface;\n\n private braintreeManager: BraintreeManagerInterface;\n\n private emitter: Emitter<PayPalFlowHandlerEvents> = createNanoEvents<PayPalFlowHandlerEvents>();\n\n updateDonationInfo(donationInfo: DonationPaymentInfo): void {\n if (this.buttonDataSource) {\n this.buttonDataSource.donationInfo = donationInfo;\n }\n }\n\n updateUpsellDonationInfo(donationInfo: DonationPaymentInfo): void {\n if (this.upsellButtonDataSourceContainer) {\n this.upsellButtonDataSourceContainer.upsellButtonDataSource.donationInfo = donationInfo;\n }\n }\n\n constructor(options: {\n braintreeManager: BraintreeManagerInterface;\n donationFlowModalManager: DonationFlowModalManagerInterface;\n }) {\n this.braintreeManager = options.braintreeManager;\n this.donationFlowModalManager = options.donationFlowModalManager;\n }\n\n on<E extends keyof PayPalFlowHandlerEvents>(\n event: E,\n callback: PayPalFlowHandlerEvents[E],\n ): Unsubscribe {\n return this.emitter.on(event, callback);\n }\n\n async payPalPaymentStarted(\n dataSource: PayPalButtonDataSourceInterface,\n\n options: object,\n ): Promise<void> {\n this.emitter.emit('payPalPaymentStarted', dataSource, options);\n }\n\n /**\n * Once we have the dataSource & payload, we ask patron to confirm donation.\n * Once confirmed, we move forward to: `payPalPaymentConfirmed`\n */\n async payPalPaymentAuthorized(\n dataSource: PayPalButtonDataSourceInterface,\n payload: paypal.TokenizePayload,\n ): Promise<void> {\n const { donationType, total } = dataSource.donationInfo;\n this.donationFlowModalManager.showConfirmationStepModal({\n donationType,\n amount: total,\n currencyType: 'USD', // defaults to USD for now\n confirmDonationCB: () => {\n this.payPalPaymentConfirmed(dataSource, payload);\n },\n cancelDonationCB: () => {\n this.donationFlowModalManager.closeModal();\n this.payPalPaymentCancelled(dataSource, {});\n },\n });\n }\n\n async payPalPaymentConfirmed(\n dataSource: PayPalButtonDataSourceInterface,\n payload: paypal.TokenizePayload,\n ): Promise<void> {\n this.emitter.emit('payPalPaymentConfirmed', dataSource, {});\n this.donationFlowModalManager.showProcessingModal();\n\n const donationType = dataSource.donationInfo.donationType;\n\n const details = payload?.details;\n\n const customerInfo = new CustomerInfo({\n email: details?.email,\n firstName: details?.firstName,\n lastName: details?.lastName,\n });\n\n const shippingAddress = details.shippingAddress;\n\n const billingInfo = new BillingInfo({\n streetAddress: shippingAddress?.line1,\n extendedAddress: shippingAddress?.line2,\n locality: shippingAddress?.city,\n region: shippingAddress?.state,\n postalCode: shippingAddress?.postalCode,\n countryCodeAlpha2: shippingAddress?.countryCode,\n });\n\n const oneTimeTransaction = this.upsellButtonDataSourceContainer\n ? this.upsellButtonDataSourceContainer.oneTimeSuccessResponse.transaction_id\n : undefined;\n\n const response: DonationResponse = await this.braintreeManager.submitDonation({\n nonce: payload.nonce,\n paymentProvider: PaymentProvider.PayPal,\n donationInfo: dataSource.donationInfo,\n customerInfo: customerInfo,\n billingInfo: billingInfo,\n upsellOnetimeTransactionId: oneTimeTransaction,\n });\n\n if (!response.success) {\n const error = response.value as ErrorResponse;\n this.donationFlowModalManager.showErrorModal({\n message: error.message,\n });\n return;\n }\n\n const successResponse = response.value as SuccessResponse;\n\n switch (donationType) {\n case DonationType.OneTime:\n this.showUpsellModal(payload, successResponse);\n break;\n case DonationType.Monthly:\n // show thank you, redirect\n this.donationFlowModalManager.showThankYouModal({ successResponse });\n break;\n case DonationType.Upsell:\n if (this.upsellButtonDataSourceContainer) {\n this.donationFlowModalManager.showThankYouModal({\n successResponse: this.upsellButtonDataSourceContainer.oneTimeSuccessResponse,\n upsellSuccessResponse: successResponse,\n });\n } else {\n // we're in the upsell flow, but no upsell data source container.. this should not happen\n this.donationFlowModalManager.showErrorModal({\n message: 'Error setting up monthly donation',\n });\n }\n break;\n }\n }\n\n async payPalPaymentCancelled(\n dataSource: PayPalButtonDataSourceInterface,\n\n data: object,\n ): Promise<void> {\n this.emitter.emit('payPalPaymentCancelled', dataSource, data);\n }\n\n async payPalPaymentError(\n dataSource: PayPalButtonDataSourceInterface,\n error: string,\n ): Promise<void> {\n this.emitter.emit('payPalPaymentError', dataSource, error);\n console.error(\n 'PaymentSector:payPalPaymentError error:',\n dataSource,\n dataSource.donationInfo,\n error,\n );\n }\n\n async renderPayPalButton(donationInfo: DonationPaymentInfo): Promise<void> {\n const handler = await this.braintreeManager?.paymentProviders.paypalHandler.get();\n\n this.buttonDataSource = await handler?.renderPayPalButton({\n selector: '#paypal-button',\n style: {\n color: 'blue' as paypal.ButtonColorOption, // I'm not sure why I can't access the enum directly here.. I get a UMD error\n label: 'paypal' as paypal.ButtonLabelOption,\n shape: 'rect' as paypal.ButtonShapeOption,\n size: 'medium' as paypal.ButtonSizeOption,\n tagline: false,\n },\n donationInfo: donationInfo,\n });\n\n if (this.buttonDataSource) {\n this.buttonDataSource.delegate = this;\n }\n }\n\n private async showUpsellModal(\n oneTimePayload: paypal.TokenizePayload,\n oneTimeSuccessResponse: SuccessResponse,\n ): Promise<void> {\n this.donationFlowModalManager.showUpsellModal({\n oneTimeAmount: oneTimeSuccessResponse.amount,\n amountChanged: this.upsellAmountChanged.bind(this),\n noSelected: () => {\n this.donationFlowModalManager.showThankYouModal({\n successResponse: oneTimeSuccessResponse,\n });\n },\n ctaMode: UpsellModalCTAMode.PayPalUpsellSlot,\n userClosedModalCallback: () => {\n this.donationFlowModalManager.showThankYouModal({\n successResponse: oneTimeSuccessResponse,\n });\n },\n });\n\n const amount = DonationFlowModalManager.getDefaultUpsellAmount(oneTimeSuccessResponse.amount);\n\n const upsellDonationInfo = new DonationPaymentInfo({\n amount: amount,\n donationType: DonationType.Upsell,\n coverFees: false,\n });\n\n if (!this.upsellButtonDataSourceContainer) {\n this.renderUpsellPayPalButton({\n donationInfo: upsellDonationInfo,\n oneTimePayload,\n oneTimeSuccessResponse,\n });\n }\n }\n\n private upsellAmountChanged(amount: number): void {\n if (this.upsellButtonDataSourceContainer) {\n this.upsellButtonDataSourceContainer.upsellButtonDataSource.donationInfo.amount = amount;\n }\n }\n\n private async renderUpsellPayPalButton(options: {\n donationInfo: DonationPaymentInfo;\n oneTimePayload: paypal.TokenizePayload;\n oneTimeSuccessResponse: SuccessResponse;\n }): Promise<void> {\n const handler = await this.braintreeManager?.paymentProviders.paypalHandler.get();\n\n const upsellButtonDataSource = await handler?.renderPayPalButton({\n selector: '#paypal-upsell-button',\n style: {\n color: 'blue' as paypal.ButtonColorOption,\n label: 'paypal' as paypal.ButtonLabelOption,\n shape: 'rect' as paypal.ButtonShapeOption,\n size: 'responsive' as paypal.ButtonSizeOption,\n tagline: false,\n },\n donationInfo: options.donationInfo,\n });\n\n if (upsellButtonDataSource) {\n upsellButtonDataSource.delegate = this;\n this.upsellButtonDataSourceContainer = new UpsellDataSourceContainer({\n upsellButtonDataSource: upsellButtonDataSource,\n oneTimePayload: options.oneTimePayload,\n oneTimeSuccessResponse: options.oneTimeSuccessResponse,\n });\n } else {\n console.error('error rendering paypal upsell button');\n }\n }\n}\n"]}
@@ -1,7 +1,5 @@
1
1
  import { BillingInfo } from '@internetarchive/donation-form-data-models';
2
2
  export const mockBillingInfo = new BillingInfo({
3
- firstName: 'Fooey',
4
- lastName: 'McBarrison',
5
3
  streetAddress: '123 Fake St',
6
4
  extendedAddress: 'Apt 123',
7
5
  locality: 'San Francisco',
@@ -1 +1 @@
1
- {"version":3,"file":"mock-billing-info.js","sourceRoot":"","sources":["../../../../test/mocks/models/mock-billing-info.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,4CAA4C,CAAC;AAEzE,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,WAAW,CAAC;IAC7C,SAAS,EAAE,OAAO;IAClB,QAAQ,EAAE,YAAY;IACtB,aAAa,EAAE,aAAa;IAC5B,eAAe,EAAE,SAAS;IAC1B,QAAQ,EAAE,eAAe;IACzB,MAAM,EAAE,IAAI;IACZ,UAAU,EAAE,OAAO;IACnB,iBAAiB,EAAE,IAAI;CACxB,CAAC,CAAC","sourcesContent":["import { BillingInfo } from '@internetarchive/donation-form-data-models';\n\nexport const mockBillingInfo = new BillingInfo({\n firstName: 'Fooey',\n lastName: 'McBarrison',\n streetAddress: '123 Fake St',\n extendedAddress: 'Apt 123',\n locality: 'San Francisco',\n region: 'CA',\n postalCode: '12345',\n countryCodeAlpha2: 'US',\n});\n"]}
1
+ {"version":3,"file":"mock-billing-info.js","sourceRoot":"","sources":["../../../../test/mocks/models/mock-billing-info.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,4CAA4C,CAAC;AAEzE,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,WAAW,CAAC;IAC7C,aAAa,EAAE,aAAa;IAC5B,eAAe,EAAE,SAAS;IAC1B,QAAQ,EAAE,eAAe;IACzB,MAAM,EAAE,IAAI;IACZ,UAAU,EAAE,OAAO;IACnB,iBAAiB,EAAE,IAAI;CACxB,CAAC,CAAC","sourcesContent":["import { BillingInfo } from '@internetarchive/donation-form-data-models';\n\nexport const mockBillingInfo = new BillingInfo({\n streetAddress: '123 Fake St',\n extendedAddress: 'Apt 123',\n locality: 'San Francisco',\n region: 'CA',\n postalCode: '12345',\n countryCodeAlpha2: 'US',\n});\n"]}
@@ -193,8 +193,6 @@ describe('Donation Flow Modal Manager', () => {
193
193
  value: {
194
194
  amount: 5,
195
195
  billing: {
196
- firstName: 'Fooey',
197
- lastName: 'McBarrison',
198
196
  countryCodeAlpha2: 'US',
199
197
  extendedAddress: 'Apt 123',
200
198
  locality: 'San Francisco',
@@ -1 +1 @@
1
- {"version":3,"file":"donation-flow-modal-manager.test.js","sourceRoot":"","sources":["../../../../test/tests/flow-handlers/donation-flow-modal-manager.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, fixture, expect } from '@open-wc/testing';\nimport { DonationFlowModalManager } from '../../../src/payment-flow-handlers/donation-flow-modal-manager';\nimport { MockModalManager } from '../../mocks/mock-modal-manager';\nimport '../../mocks/mock-modal-manager';\nimport { MockBraintreeManager } from '../../mocks/mock-braintree-manager';\nimport { mockSuccessResponse } from '../../mocks/models/mock-success-response';\nimport {\n PaymentProvider,\n DonationPaymentInfo,\n DonationType,\n} from '@internetarchive/donation-form-data-models';\nimport { mockBillingInfo } from '../../mocks/models/mock-billing-info';\nimport { mockCustomerInfo } from '../../mocks/models/mock-customer-info';\nimport { DonationControllerEventLoggerInterface } from '../../../src/@types/analytics-handler';\nimport sinon from 'sinon';\n\nlet analytics: DonationControllerEventLoggerInterface;\n\ndescribe('Donation Flow Modal Manager', () => {\n beforeEach(() => {\n analytics = {\n logEvent: sinon.fake(),\n logDonationFlowEvent: sinon.fake(),\n };\n });\n afterEach(() => {\n sinon.restore();\n });\n it('can close the modal', async () => {\n const mockModalManager = (await fixture(html`\n <mock-modal-manager></mock-modal-manager>\n `)) as MockModalManager;\n const mockBraintreeManager = new MockBraintreeManager();\n const manager = new DonationFlowModalManager({\n braintreeManager: mockBraintreeManager,\n modalManager: mockModalManager,\n analytics,\n });\n manager.closeModal();\n expect(mockModalManager.closeCalled).to.be.true;\n });\n\n it('can calculate the proper default upsell amount', async () => {\n const defaultAmount = 8;\n let amount = DonationFlowModalManager.getDefaultUpsellAmount(1);\n expect(amount).to.equal(defaultAmount);\n amount = DonationFlowModalManager.getDefaultUpsellAmount(10);\n expect(amount).to.equal(defaultAmount);\n amount = DonationFlowModalManager.getDefaultUpsellAmount(10.01);\n expect(amount).to.equal(10);\n amount = DonationFlowModalManager.getDefaultUpsellAmount(25);\n expect(amount).to.equal(10);\n amount = DonationFlowModalManager.getDefaultUpsellAmount(25.01);\n expect(amount).to.equal(25);\n amount = DonationFlowModalManager.getDefaultUpsellAmount(100);\n expect(amount).to.equal(25);\n amount = DonationFlowModalManager.getDefaultUpsellAmount(100.01);\n expect(amount).to.equal(50);\n });\n\n it('can show the processing modal', async () => {\n const mockModalManager = (await fixture(html`\n <mock-modal-manager></mock-modal-manager>\n `)) as MockModalManager;\n const mockBraintreeManager = new MockBraintreeManager();\n const manager = new DonationFlowModalManager({\n braintreeManager: mockBraintreeManager,\n modalManager: mockModalManager,\n analytics,\n });\n manager.showProcessingModal();\n const modalOptions = mockModalManager.showModalOptions;\n expect(modalOptions?.config.headerColor).to.equal('#497fbf');\n expect(modalOptions?.config.showProcessingIndicator).to.be.true;\n expect(modalOptions?.config.processingImageMode).to.equal('processing');\n expect(modalOptions?.config.closeOnBackdropClick).to.be.false;\n expect(modalOptions?.config.showCloseButton).to.be.false;\n expect(modalOptions?.config.title?.strings[0]).to.contain('Processing...');\n });\n\n it('can show the error modal', async () => {\n const mockModalManager = (await fixture(html`\n <mock-modal-manager></mock-modal-manager>\n `)) as MockModalManager;\n const mockBraintreeManager = new MockBraintreeManager();\n const manager = new DonationFlowModalManager({\n braintreeManager: mockBraintreeManager,\n modalManager: mockModalManager,\n analytics,\n });\n manager.showErrorModal({ message: 'foo-error' });\n const modalOptions = mockModalManager.showModalOptions;\n expect(modalOptions?.config.headerColor).to.equal('#691916');\n expect(modalOptions?.config.showProcessingIndicator).to.be.false;\n expect(modalOptions?.config.closeOnBackdropClick).to.be.true;\n expect(modalOptions?.config.showCloseButton).to.be.true;\n expect(modalOptions?.config.headline?.strings[0]).to.contain(\n \"There's been a problem completing your donation.\",\n );\n expect(modalOptions?.config.message?.values[0]).to.equal('foo-error');\n });\n\n it('shows the thank you modal and calls `donationSuccessful` to take user to thank you page', async () => {\n const mockModalManager = (await fixture(html`\n <mock-modal-manager></mock-modal-manager>\n `)) as MockModalManager;\n const mockBraintreeManager = new MockBraintreeManager();\n const logEvent = sinon.fake();\n const logDonationFlowEvent = sinon.fake();\n const manager = new DonationFlowModalManager({\n braintreeManager: mockBraintreeManager,\n modalManager: mockModalManager,\n analytics: {\n logEvent,\n logDonationFlowEvent,\n },\n });\n manager.showThankYouModal({\n successResponse: mockSuccessResponse,\n });\n const modalOptions = mockModalManager.showModalOptions;\n expect(modalOptions?.config.headerColor).to.equal('#55A183');\n expect(modalOptions?.config.processingImageMode).to.equal('complete');\n expect(modalOptions?.config.showProcessingIndicator).to.be.true;\n expect(modalOptions?.config.closeOnBackdropClick).to.be.true;\n expect(modalOptions?.config.showCloseButton).to.be.true;\n expect(modalOptions?.config.title?.strings[0]).to.contain('Thank You!');\n const response = mockBraintreeManager.donationSuccessfulOptions?.successResponse;\n expect(response).to.deep.equal(mockSuccessResponse);\n });\n\n it('donation submitted analytics gets sent when drawing thank you modal', async () => {\n const mockModalManager = (await fixture(html`\n <mock-modal-manager></mock-modal-manager>\n `)) as MockModalManager;\n const mockBraintreeManager = new MockBraintreeManager();\n const logEvent = sinon.fake();\n const logDonationFlowEvent = sinon.fake();\n const manager = new DonationFlowModalManager({\n braintreeManager: mockBraintreeManager,\n modalManager: mockModalManager,\n analytics: {\n logEvent,\n logDonationFlowEvent,\n },\n });\n const successResponse = mockSuccessResponse;\n successResponse.paymentProvider = PaymentProvider.GooglePay;\n manager.showThankYouModal({\n successResponse: mockSuccessResponse,\n });\n\n // fires analytics\n expect(logDonationFlowEvent.callCount).to.equal(1);\n expect(logDonationFlowEvent.args[0][0]).to.equal(`Donated-GooglePay`);\n expect(logDonationFlowEvent.args[0][1]).to.equal(DonationType.OneTime);\n });\n\n it('can show the confirmation modal', async () => {\n const mockModalManager = (await fixture(html`\n <mock-modal-manager></mock-modal-manager>\n `)) as MockModalManager;\n const mockBraintreeManager = new MockBraintreeManager();\n const manager = new DonationFlowModalManager({\n braintreeManager: mockBraintreeManager,\n modalManager: mockModalManager,\n analytics,\n });\n manager.showConfirmationStepModal({\n donationType: DonationType.Upsell,\n amount: 8,\n currencyType: 'USD',\n cancelDonationCB: () => console.log('donation cancelled'),\n confirmDonationCB: () => console.log('donation confirmed'),\n });\n\n const modalOptions = mockModalManager.showModalOptions;\n expect(modalOptions?.config.headerColor).to.equal('#55A183');\n expect(modalOptions?.config.closeOnBackdropClick).to.be.false;\n expect(modalOptions?.config.showCloseButton).to.be.true;\n expect(modalOptions?.config?.title?.values).to.contain('Confirm monthly donation');\n });\n\n it('can start the donation submission flow', async () => {\n const mockModalManager = (await fixture(html`\n <mock-modal-manager></mock-modal-manager>\n `)) as MockModalManager;\n const mockBraintreeManager = new MockBraintreeManager();\n const manager = new DonationFlowModalManager({\n braintreeManager: mockBraintreeManager,\n modalManager: mockModalManager,\n analytics,\n });\n const result = await manager.startDonationSubmissionFlow({\n nonce: 'foo',\n paymentProvider: PaymentProvider.CreditCard,\n donationInfo: new DonationPaymentInfo({\n donationType: DonationType.OneTime,\n amount: 5,\n coverFees: false,\n }),\n billingInfo: mockBillingInfo,\n customerInfo: mockCustomerInfo,\n });\n\n expect(result).to.deep.equal({\n success: true,\n value: {\n amount: 5,\n billing: {\n firstName: 'Fooey',\n lastName: 'McBarrison',\n countryCodeAlpha2: 'US',\n extendedAddress: 'Apt 123',\n locality: 'San Francisco',\n postalCode: '12345',\n region: 'CA',\n streetAddress: '123 Fake St',\n },\n customer: {\n email: 'foo@bar.com',\n firstName: 'Fooey',\n lastName: 'McBarrison',\n },\n customer_id: 'bar',\n donationType: 'one-time',\n paymentMethodNonce: 'foo',\n paymentProvider: 'Credit Card',\n transaction_id: 'foo',\n },\n });\n });\n});\n"]}
1
+ {"version":3,"file":"donation-flow-modal-manager.test.js","sourceRoot":"","sources":["../../../../test/tests/flow-handlers/donation-flow-modal-manager.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, fixture, expect } from '@open-wc/testing';\nimport { DonationFlowModalManager } from '../../../src/payment-flow-handlers/donation-flow-modal-manager';\nimport { MockModalManager } from '../../mocks/mock-modal-manager';\nimport '../../mocks/mock-modal-manager';\nimport { MockBraintreeManager } from '../../mocks/mock-braintree-manager';\nimport { mockSuccessResponse } from '../../mocks/models/mock-success-response';\nimport {\n PaymentProvider,\n DonationPaymentInfo,\n DonationType,\n} from '@internetarchive/donation-form-data-models';\nimport { mockBillingInfo } from '../../mocks/models/mock-billing-info';\nimport { mockCustomerInfo } from '../../mocks/models/mock-customer-info';\nimport { DonationControllerEventLoggerInterface } from '../../../src/@types/analytics-handler';\nimport sinon from 'sinon';\n\nlet analytics: DonationControllerEventLoggerInterface;\n\ndescribe('Donation Flow Modal Manager', () => {\n beforeEach(() => {\n analytics = {\n logEvent: sinon.fake(),\n logDonationFlowEvent: sinon.fake(),\n };\n });\n afterEach(() => {\n sinon.restore();\n });\n it('can close the modal', async () => {\n const mockModalManager = (await fixture(html`\n <mock-modal-manager></mock-modal-manager>\n `)) as MockModalManager;\n const mockBraintreeManager = new MockBraintreeManager();\n const manager = new DonationFlowModalManager({\n braintreeManager: mockBraintreeManager,\n modalManager: mockModalManager,\n analytics,\n });\n manager.closeModal();\n expect(mockModalManager.closeCalled).to.be.true;\n });\n\n it('can calculate the proper default upsell amount', async () => {\n const defaultAmount = 8;\n let amount = DonationFlowModalManager.getDefaultUpsellAmount(1);\n expect(amount).to.equal(defaultAmount);\n amount = DonationFlowModalManager.getDefaultUpsellAmount(10);\n expect(amount).to.equal(defaultAmount);\n amount = DonationFlowModalManager.getDefaultUpsellAmount(10.01);\n expect(amount).to.equal(10);\n amount = DonationFlowModalManager.getDefaultUpsellAmount(25);\n expect(amount).to.equal(10);\n amount = DonationFlowModalManager.getDefaultUpsellAmount(25.01);\n expect(amount).to.equal(25);\n amount = DonationFlowModalManager.getDefaultUpsellAmount(100);\n expect(amount).to.equal(25);\n amount = DonationFlowModalManager.getDefaultUpsellAmount(100.01);\n expect(amount).to.equal(50);\n });\n\n it('can show the processing modal', async () => {\n const mockModalManager = (await fixture(html`\n <mock-modal-manager></mock-modal-manager>\n `)) as MockModalManager;\n const mockBraintreeManager = new MockBraintreeManager();\n const manager = new DonationFlowModalManager({\n braintreeManager: mockBraintreeManager,\n modalManager: mockModalManager,\n analytics,\n });\n manager.showProcessingModal();\n const modalOptions = mockModalManager.showModalOptions;\n expect(modalOptions?.config.headerColor).to.equal('#497fbf');\n expect(modalOptions?.config.showProcessingIndicator).to.be.true;\n expect(modalOptions?.config.processingImageMode).to.equal('processing');\n expect(modalOptions?.config.closeOnBackdropClick).to.be.false;\n expect(modalOptions?.config.showCloseButton).to.be.false;\n expect(modalOptions?.config.title?.strings[0]).to.contain('Processing...');\n });\n\n it('can show the error modal', async () => {\n const mockModalManager = (await fixture(html`\n <mock-modal-manager></mock-modal-manager>\n `)) as MockModalManager;\n const mockBraintreeManager = new MockBraintreeManager();\n const manager = new DonationFlowModalManager({\n braintreeManager: mockBraintreeManager,\n modalManager: mockModalManager,\n analytics,\n });\n manager.showErrorModal({ message: 'foo-error' });\n const modalOptions = mockModalManager.showModalOptions;\n expect(modalOptions?.config.headerColor).to.equal('#691916');\n expect(modalOptions?.config.showProcessingIndicator).to.be.false;\n expect(modalOptions?.config.closeOnBackdropClick).to.be.true;\n expect(modalOptions?.config.showCloseButton).to.be.true;\n expect(modalOptions?.config.headline?.strings[0]).to.contain(\n \"There's been a problem completing your donation.\",\n );\n expect(modalOptions?.config.message?.values[0]).to.equal('foo-error');\n });\n\n it('shows the thank you modal and calls `donationSuccessful` to take user to thank you page', async () => {\n const mockModalManager = (await fixture(html`\n <mock-modal-manager></mock-modal-manager>\n `)) as MockModalManager;\n const mockBraintreeManager = new MockBraintreeManager();\n const logEvent = sinon.fake();\n const logDonationFlowEvent = sinon.fake();\n const manager = new DonationFlowModalManager({\n braintreeManager: mockBraintreeManager,\n modalManager: mockModalManager,\n analytics: {\n logEvent,\n logDonationFlowEvent,\n },\n });\n manager.showThankYouModal({\n successResponse: mockSuccessResponse,\n });\n const modalOptions = mockModalManager.showModalOptions;\n expect(modalOptions?.config.headerColor).to.equal('#55A183');\n expect(modalOptions?.config.processingImageMode).to.equal('complete');\n expect(modalOptions?.config.showProcessingIndicator).to.be.true;\n expect(modalOptions?.config.closeOnBackdropClick).to.be.true;\n expect(modalOptions?.config.showCloseButton).to.be.true;\n expect(modalOptions?.config.title?.strings[0]).to.contain('Thank You!');\n const response = mockBraintreeManager.donationSuccessfulOptions?.successResponse;\n expect(response).to.deep.equal(mockSuccessResponse);\n });\n\n it('donation submitted analytics gets sent when drawing thank you modal', async () => {\n const mockModalManager = (await fixture(html`\n <mock-modal-manager></mock-modal-manager>\n `)) as MockModalManager;\n const mockBraintreeManager = new MockBraintreeManager();\n const logEvent = sinon.fake();\n const logDonationFlowEvent = sinon.fake();\n const manager = new DonationFlowModalManager({\n braintreeManager: mockBraintreeManager,\n modalManager: mockModalManager,\n analytics: {\n logEvent,\n logDonationFlowEvent,\n },\n });\n const successResponse = mockSuccessResponse;\n successResponse.paymentProvider = PaymentProvider.GooglePay;\n manager.showThankYouModal({\n successResponse: mockSuccessResponse,\n });\n\n // fires analytics\n expect(logDonationFlowEvent.callCount).to.equal(1);\n expect(logDonationFlowEvent.args[0][0]).to.equal(`Donated-GooglePay`);\n expect(logDonationFlowEvent.args[0][1]).to.equal(DonationType.OneTime);\n });\n\n it('can show the confirmation modal', async () => {\n const mockModalManager = (await fixture(html`\n <mock-modal-manager></mock-modal-manager>\n `)) as MockModalManager;\n const mockBraintreeManager = new MockBraintreeManager();\n const manager = new DonationFlowModalManager({\n braintreeManager: mockBraintreeManager,\n modalManager: mockModalManager,\n analytics,\n });\n manager.showConfirmationStepModal({\n donationType: DonationType.Upsell,\n amount: 8,\n currencyType: 'USD',\n cancelDonationCB: () => console.log('donation cancelled'),\n confirmDonationCB: () => console.log('donation confirmed'),\n });\n\n const modalOptions = mockModalManager.showModalOptions;\n expect(modalOptions?.config.headerColor).to.equal('#55A183');\n expect(modalOptions?.config.closeOnBackdropClick).to.be.false;\n expect(modalOptions?.config.showCloseButton).to.be.true;\n expect(modalOptions?.config?.title?.values).to.contain('Confirm monthly donation');\n });\n\n it('can start the donation submission flow', async () => {\n const mockModalManager = (await fixture(html`\n <mock-modal-manager></mock-modal-manager>\n `)) as MockModalManager;\n const mockBraintreeManager = new MockBraintreeManager();\n const manager = new DonationFlowModalManager({\n braintreeManager: mockBraintreeManager,\n modalManager: mockModalManager,\n analytics,\n });\n const result = await manager.startDonationSubmissionFlow({\n nonce: 'foo',\n paymentProvider: PaymentProvider.CreditCard,\n donationInfo: new DonationPaymentInfo({\n donationType: DonationType.OneTime,\n amount: 5,\n coverFees: false,\n }),\n billingInfo: mockBillingInfo,\n customerInfo: mockCustomerInfo,\n });\n\n expect(result).to.deep.equal({\n success: true,\n value: {\n amount: 5,\n billing: {\n countryCodeAlpha2: 'US',\n extendedAddress: 'Apt 123',\n locality: 'San Francisco',\n postalCode: '12345',\n region: 'CA',\n streetAddress: '123 Fake St',\n },\n customer: {\n email: 'foo@bar.com',\n firstName: 'Fooey',\n lastName: 'McBarrison',\n },\n customer_id: 'bar',\n donationType: 'one-time',\n paymentMethodNonce: 'foo',\n paymentProvider: 'Credit Card',\n transaction_id: 'foo',\n },\n });\n });\n});\n"]}
@@ -0,0 +1 @@
1
+ import '../../../src/form-elements/contact-form/contact-form';
@@ -0,0 +1,152 @@
1
+ import { __awaiter } from "tslib";
2
+ import { fixture, elementUpdated, expect } from '@open-wc/testing';
3
+ import { html } from 'lit';
4
+ import '../../../src/form-elements/contact-form/contact-form';
5
+ describe('ContactForm', () => {
6
+ it('validates required fields', () => __awaiter(void 0, void 0, void 0, function* () {
7
+ const el = (yield fixture(html `<contact-form></contact-form>`));
8
+ const firstNameInput = el.querySelector('#donation-contact-form-first-name');
9
+ const lastNameInput = el.querySelector('#donation-contact-form-last-name');
10
+ const emailInput = el.querySelector('#donation-contact-form-email');
11
+ firstNameInput.value = ' ';
12
+ lastNameInput.value = ' ';
13
+ emailInput.value = '';
14
+ expect(firstNameInput.checkValidity()).to.be.false;
15
+ expect(lastNameInput.checkValidity()).to.be.false;
16
+ expect(emailInput.checkValidity()).to.be.false;
17
+ firstNameInput.value = 'John';
18
+ lastNameInput.value = 'Doe';
19
+ emailInput.value = 'john.doe@example.com';
20
+ yield elementUpdated(el);
21
+ expect(firstNameInput.checkValidity()).to.be.true;
22
+ expect(lastNameInput.checkValidity()).to.be.true;
23
+ expect(emailInput.checkValidity()).to.be.true;
24
+ }));
25
+ it('requires minimum number of characters for first and last name', () => __awaiter(void 0, void 0, void 0, function* () {
26
+ const el = (yield fixture(html `<contact-form></contact-form>`));
27
+ const firstNameInput = el.querySelector('#donation-contact-form-first-name');
28
+ const lastNameInput = el.querySelector('#donation-contact-form-last-name');
29
+ firstNameInput.value = 'A';
30
+ lastNameInput.value = 'B';
31
+ yield elementUpdated(el);
32
+ expect(firstNameInput.checkValidity()).to.be.false;
33
+ expect(lastNameInput.checkValidity()).to.be.false;
34
+ }));
35
+ it('requires email by default', () => __awaiter(void 0, void 0, void 0, function* () {
36
+ const el = (yield fixture(html `<contact-form></contact-form>`));
37
+ const emailInput = el.querySelector('#donation-contact-form-email');
38
+ expect(emailInput.required).to.be.true;
39
+ }));
40
+ it('street address requires minimum number of characters', () => __awaiter(void 0, void 0, void 0, function* () {
41
+ const el = (yield fixture(html `<contact-form></contact-form>`));
42
+ const streetAddressInput = el.querySelector('#donation-contact-form-street-address');
43
+ streetAddressInput.value = '1 b';
44
+ yield elementUpdated(el);
45
+ expect(streetAddressInput.checkValidity()).to.be.false;
46
+ streetAddressInput.value = '1 st';
47
+ yield elementUpdated(el);
48
+ expect(streetAddressInput.checkValidity()).to.be.true;
49
+ }));
50
+ describe('region and postal code requirements', () => {
51
+ it('state and postal code required for US address', () => __awaiter(void 0, void 0, void 0, function* () {
52
+ const el = (yield fixture(html `<contact-form></contact-form>`));
53
+ el.selectedCountry = 'US';
54
+ yield elementUpdated(el);
55
+ const regionInput = el.querySelector('#donation-contact-form-region');
56
+ const postalCodeInput = el.querySelector('#donation-contact-form-postal-code');
57
+ expect(regionInput.required).to.be.true;
58
+ expect(postalCodeInput.required).to.be.true;
59
+ }));
60
+ it('state and postal code optional for non-US address', () => __awaiter(void 0, void 0, void 0, function* () {
61
+ const el = (yield fixture(html `<contact-form></contact-form>`));
62
+ el.selectedCountry = 'CA';
63
+ yield elementUpdated(el);
64
+ const regionInput = el.querySelector('#donation-contact-form-region');
65
+ const postalCodeInput = el.querySelector('#donation-contact-form-postal-code');
66
+ expect(regionInput.required).to.be.false;
67
+ expect(postalCodeInput.required).to.be.false;
68
+ }));
69
+ });
70
+ describe('postal code validation pattern', () => {
71
+ it('validates US postal codes correctly', () => __awaiter(void 0, void 0, void 0, function* () {
72
+ const el = (yield fixture(html `<contact-form></contact-form>`));
73
+ el.selectedCountry = 'US';
74
+ yield elementUpdated(el);
75
+ const postalCodeInput = el.querySelector('#donation-contact-form-postal-code');
76
+ const validPostalCodes = ['12345', '12345-6789'];
77
+ const invalidPostalCodes = ['1234', '123456', '1234A', 'ABCDE', '12345-678'];
78
+ for (const code of validPostalCodes) {
79
+ postalCodeInput.value = code;
80
+ yield elementUpdated(el);
81
+ expect(postalCodeInput.checkValidity(), `Expected ${code} to be valid`).to.be.true;
82
+ }
83
+ for (const code of invalidPostalCodes) {
84
+ postalCodeInput.value = code;
85
+ yield elementUpdated(el);
86
+ expect(postalCodeInput.checkValidity(), `Expected ${code} to be invalid`).to.be.false;
87
+ }
88
+ }));
89
+ });
90
+ describe('country selector', () => {
91
+ it('defaults selectedCountry to US', () => __awaiter(void 0, void 0, void 0, function* () {
92
+ const el = (yield fixture(html `<contact-form></contact-form>`));
93
+ expect(el.selectedCountry).to.equal('US');
94
+ }));
95
+ it('dropdown updates selectedCountry property', () => __awaiter(void 0, void 0, void 0, function* () {
96
+ const el = (yield fixture(html `<contact-form></contact-form>`));
97
+ const countrySelect = el.querySelector('#donation-contact-form-countryCodeAlpha2');
98
+ countrySelect.value = 'CA';
99
+ countrySelect.dispatchEvent(new Event('change'));
100
+ yield elementUpdated(el);
101
+ expect(el.selectedCountry).to.equal('CA');
102
+ }));
103
+ it('does not update selectedCountry property for invalid country code', () => __awaiter(void 0, void 0, void 0, function* () {
104
+ const el = (yield fixture(html `<contact-form></contact-form>`));
105
+ const countrySelect = el.querySelector('#donation-contact-form-countryCodeAlpha2');
106
+ const initialCountry = el.selectedCountry;
107
+ countrySelect.value = 'XX'; // Invalid country code
108
+ countrySelect.dispatchEvent(new Event('change'));
109
+ yield elementUpdated(el);
110
+ expect(el.selectedCountry).to.equal(initialCountry);
111
+ }));
112
+ });
113
+ describe('reportValidity()', () => {
114
+ it('returns false if required fields are empty and shows validation messages', () => __awaiter(void 0, void 0, void 0, function* () {
115
+ const el = (yield fixture(html `<contact-form></contact-form>`));
116
+ const firstNameInput = el.querySelector('#donation-contact-form-first-name');
117
+ const lastNameInput = el.querySelector('#donation-contact-form-last-name');
118
+ const emailInput = el.querySelector('#donation-contact-form-email');
119
+ firstNameInput.value = '';
120
+ lastNameInput.value = '';
121
+ emailInput.value = '';
122
+ const validityResult = el.reportValidity();
123
+ expect(validityResult).to.be.false;
124
+ expect(firstNameInput.validationMessage).to.not.equal('');
125
+ expect(lastNameInput.validationMessage).to.not.equal('');
126
+ expect(emailInput.validationMessage).to.not.equal('');
127
+ }));
128
+ it('returns true if all required fields are filled correctly', () => __awaiter(void 0, void 0, void 0, function* () {
129
+ const el = (yield fixture(html `<contact-form></contact-form>`));
130
+ const firstNameInput = el.querySelector('#donation-contact-form-first-name');
131
+ const lastNameInput = el.querySelector('#donation-contact-form-last-name');
132
+ const emailInput = el.querySelector('#donation-contact-form-email');
133
+ const streetAddressInput = el.querySelector('#donation-contact-form-street-address');
134
+ const cityInput = el.querySelector('#donation-contact-form-locality');
135
+ const regionInput = el.querySelector('#donation-contact-form-region');
136
+ const postalCodeInput = el.querySelector('#donation-contact-form-postal-code');
137
+ streetAddressInput.value = '123 Main St';
138
+ cityInput.value = 'Anytown';
139
+ regionInput.value = 'CA';
140
+ postalCodeInput.value = '12345';
141
+ firstNameInput.value = 'John';
142
+ lastNameInput.value = 'Doe';
143
+ emailInput.value = 'john.doe@example.com';
144
+ const validityResult = el.reportValidity();
145
+ expect(validityResult).to.be.true;
146
+ expect(firstNameInput.validationMessage).to.equal('');
147
+ expect(lastNameInput.validationMessage).to.equal('');
148
+ expect(emailInput.validationMessage).to.equal('');
149
+ }));
150
+ });
151
+ });
152
+ //# sourceMappingURL=contact-form.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contact-form.test.js","sourceRoot":"","sources":["../../../../test/tests/form-elements/contact-form.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { fixture, elementUpdated, expect } from '@open-wc/testing';\nimport { html } from 'lit';\nimport '../../../src/form-elements/contact-form/contact-form';\nimport type { ContactForm } from '../../../src/form-elements/contact-form/contact-form';\n\ndescribe('ContactForm', () => {\n it('validates required fields', async () => {\n const el = (await fixture(html`<contact-form></contact-form>`)) as ContactForm;\n const firstNameInput = el.querySelector(\n '#donation-contact-form-first-name',\n ) as HTMLInputElement;\n const lastNameInput = el.querySelector('#donation-contact-form-last-name') as HTMLInputElement;\n const emailInput = el.querySelector('#donation-contact-form-email') as HTMLInputElement;\n\n firstNameInput.value = ' ';\n lastNameInput.value = ' ';\n emailInput.value = '';\n\n expect(firstNameInput.checkValidity()).to.be.false;\n expect(lastNameInput.checkValidity()).to.be.false;\n expect(emailInput.checkValidity()).to.be.false;\n\n firstNameInput.value = 'John';\n lastNameInput.value = 'Doe';\n emailInput.value = 'john.doe@example.com';\n await elementUpdated(el);\n\n expect(firstNameInput.checkValidity()).to.be.true;\n expect(lastNameInput.checkValidity()).to.be.true;\n expect(emailInput.checkValidity()).to.be.true;\n });\n\n it('requires minimum number of characters for first and last name', async () => {\n const el = (await fixture(html`<contact-form></contact-form>`)) as ContactForm;\n const firstNameInput = el.querySelector(\n '#donation-contact-form-first-name',\n ) as HTMLInputElement;\n const lastNameInput = el.querySelector('#donation-contact-form-last-name') as HTMLInputElement;\n firstNameInput.value = 'A';\n lastNameInput.value = 'B';\n await elementUpdated(el);\n expect(firstNameInput.checkValidity()).to.be.false;\n expect(lastNameInput.checkValidity()).to.be.false;\n });\n\n it('requires email by default', async () => {\n const el = (await fixture(html`<contact-form></contact-form>`)) as ContactForm;\n const emailInput = el.querySelector('#donation-contact-form-email') as HTMLInputElement;\n expect(emailInput.required).to.be.true;\n });\n\n it('street address requires minimum number of characters', async () => {\n const el = (await fixture(html`<contact-form></contact-form>`)) as ContactForm;\n const streetAddressInput = el.querySelector(\n '#donation-contact-form-street-address',\n ) as HTMLInputElement;\n streetAddressInput.value = '1 b';\n await elementUpdated(el);\n expect(streetAddressInput.checkValidity()).to.be.false;\n streetAddressInput.value = '1 st';\n await elementUpdated(el);\n expect(streetAddressInput.checkValidity()).to.be.true;\n });\n\n describe('region and postal code requirements', () => {\n it('state and postal code required for US address', async () => {\n const el = (await fixture(html`<contact-form></contact-form>`)) as ContactForm;\n el.selectedCountry = 'US';\n await elementUpdated(el);\n const regionInput = el.querySelector('#donation-contact-form-region') as HTMLInputElement;\n const postalCodeInput = el.querySelector(\n '#donation-contact-form-postal-code',\n ) as HTMLInputElement;\n expect(regionInput.required).to.be.true;\n expect(postalCodeInput.required).to.be.true;\n });\n\n it('state and postal code optional for non-US address', async () => {\n const el = (await fixture(html`<contact-form></contact-form>`)) as ContactForm;\n el.selectedCountry = 'CA';\n await elementUpdated(el);\n const regionInput = el.querySelector('#donation-contact-form-region') as HTMLInputElement;\n const postalCodeInput = el.querySelector(\n '#donation-contact-form-postal-code',\n ) as HTMLInputElement;\n expect(regionInput.required).to.be.false;\n expect(postalCodeInput.required).to.be.false;\n });\n });\n\n describe('postal code validation pattern', () => {\n it('validates US postal codes correctly', async () => {\n const el = (await fixture(html`<contact-form></contact-form>`)) as ContactForm;\n el.selectedCountry = 'US';\n await elementUpdated(el);\n const postalCodeInput = el.querySelector(\n '#donation-contact-form-postal-code',\n ) as HTMLInputElement;\n\n const validPostalCodes = ['12345', '12345-6789'];\n const invalidPostalCodes = ['1234', '123456', '1234A', 'ABCDE', '12345-678'];\n\n for (const code of validPostalCodes) {\n postalCodeInput.value = code;\n await elementUpdated(el);\n expect(postalCodeInput.checkValidity(), `Expected ${code} to be valid`).to.be.true;\n }\n\n for (const code of invalidPostalCodes) {\n postalCodeInput.value = code;\n await elementUpdated(el);\n expect(postalCodeInput.checkValidity(), `Expected ${code} to be invalid`).to.be.false;\n }\n });\n });\n\n describe('country selector', () => {\n it('defaults selectedCountry to US', async () => {\n const el = (await fixture(html`<contact-form></contact-form>`)) as ContactForm;\n expect(el.selectedCountry).to.equal('US');\n });\n\n it('dropdown updates selectedCountry property', async () => {\n const el = (await fixture(html`<contact-form></contact-form>`)) as ContactForm;\n const countrySelect = el.querySelector(\n '#donation-contact-form-countryCodeAlpha2',\n ) as HTMLSelectElement;\n countrySelect.value = 'CA';\n countrySelect.dispatchEvent(new Event('change'));\n await elementUpdated(el);\n expect(el.selectedCountry).to.equal('CA');\n });\n\n it('does not update selectedCountry property for invalid country code', async () => {\n const el = (await fixture(html`<contact-form></contact-form>`)) as ContactForm;\n const countrySelect = el.querySelector(\n '#donation-contact-form-countryCodeAlpha2',\n ) as HTMLSelectElement;\n const initialCountry = el.selectedCountry;\n countrySelect.value = 'XX'; // Invalid country code\n countrySelect.dispatchEvent(new Event('change'));\n await elementUpdated(el);\n expect(el.selectedCountry).to.equal(initialCountry);\n });\n });\n\n describe('reportValidity()', () => {\n it('returns false if required fields are empty and shows validation messages', async () => {\n const el = (await fixture(html`<contact-form></contact-form>`)) as ContactForm;\n const firstNameInput = el.querySelector(\n '#donation-contact-form-first-name',\n ) as HTMLInputElement;\n const lastNameInput = el.querySelector(\n '#donation-contact-form-last-name',\n ) as HTMLInputElement;\n const emailInput = el.querySelector('#donation-contact-form-email') as HTMLInputElement;\n\n firstNameInput.value = '';\n lastNameInput.value = '';\n emailInput.value = '';\n\n const validityResult = el.reportValidity();\n\n expect(validityResult).to.be.false;\n expect(firstNameInput.validationMessage).to.not.equal('');\n expect(lastNameInput.validationMessage).to.not.equal('');\n expect(emailInput.validationMessage).to.not.equal('');\n });\n\n it('returns true if all required fields are filled correctly', async () => {\n const el = (await fixture(html`<contact-form></contact-form>`)) as ContactForm;\n const firstNameInput = el.querySelector(\n '#donation-contact-form-first-name',\n ) as HTMLInputElement;\n const lastNameInput = el.querySelector(\n '#donation-contact-form-last-name',\n ) as HTMLInputElement;\n const emailInput = el.querySelector('#donation-contact-form-email') as HTMLInputElement;\n const streetAddressInput = el.querySelector(\n '#donation-contact-form-street-address',\n ) as HTMLInputElement;\n const cityInput = el.querySelector('#donation-contact-form-locality') as HTMLInputElement;\n const regionInput = el.querySelector('#donation-contact-form-region') as HTMLInputElement;\n const postalCodeInput = el.querySelector(\n '#donation-contact-form-postal-code',\n ) as HTMLInputElement;\n\n streetAddressInput.value = '123 Main St';\n cityInput.value = 'Anytown';\n regionInput.value = 'CA';\n postalCodeInput.value = '12345';\n\n firstNameInput.value = 'John';\n lastNameInput.value = 'Doe';\n emailInput.value = 'john.doe@example.com';\n\n const validityResult = el.reportValidity();\n\n expect(validityResult).to.be.true;\n expect(firstNameInput.validationMessage).to.equal('');\n expect(lastNameInput.validationMessage).to.equal('');\n expect(emailInput.validationMessage).to.equal('');\n });\n });\n});\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@internetarchive/donation-form",
3
- "version": "1.0.3-webdev-8122.0",
3
+ "version": "1.0.3-webdev-8114.1",
4
4
  "description": "The Internet Archive Donation Form",
5
5
  "license": "AGPL-3.0-only",
6
6
  "main": "dist/index.js",
@@ -30,7 +30,7 @@
30
30
  "dependencies": {
31
31
  "@internetarchive/analytics-manager": "^0.1.4",
32
32
  "@internetarchive/donation-form-currency-validator": "^0.3.1",
33
- "@internetarchive/donation-form-data-models": "0.3.7-webdev-8122.0",
33
+ "@internetarchive/donation-form-data-models": "^0.3.6",
34
34
  "@internetarchive/donation-form-edit-donation": "^1.1.5",
35
35
  "@internetarchive/donation-form-section": "^0.3.6",
36
36
  "@internetarchive/icon-applepay": "^1.3.2",
@@ -51,7 +51,6 @@ export class ContactForm extends LitElement {
51
51
  @query('#donation-contact-form-error-message') errorMessage!: HTMLDivElement;
52
52
  @query('form') form!: HTMLFormElement;
53
53
 
54
- /** @keyof countries */
55
54
  @property({ type: String }) selectedCountry = 'US';
56
55
 
57
56
  @property({ type: String }) donorEmail = '';
@@ -83,7 +82,7 @@ export class ContactForm extends LitElement {
83
82
  });
84
83
 
85
84
  if (!isValid) {
86
- this.errorMessage.innerText = 'Please enter any missing contact information below';
85
+ this.errorMessage.innerText = 'Please enter any missing or invalid contact information below';
87
86
  } else {
88
87
  this.errorMessage.innerText = '';
89
88
  }
@@ -109,6 +108,7 @@ export class ContactForm extends LitElement {
109
108
  fieldType: 'email',
110
109
  name: 'email',
111
110
  autocomplete: 'email',
111
+ minlength: 5,
112
112
  maxlength: 255,
113
113
  icon: emailImg,
114
114
  })}
@@ -122,6 +122,7 @@ export class ContactForm extends LitElement {
122
122
  placeholder: 'First name',
123
123
  name: 'fname',
124
124
  required: true,
125
+ validationPattern: '.*\\S{2,}.*',
125
126
  maxlength: 255,
126
127
  autocomplete: 'given-name',
127
128
  icon: userIcon,
@@ -134,6 +135,7 @@ export class ContactForm extends LitElement {
134
135
  name: 'lname',
135
136
  autocomplete: 'family-name',
136
137
  required: true,
138
+ validationPattern: '.*\\S{2,}.*',
137
139
  maxlength: 255,
138
140
  })}
139
141
  </div>
@@ -147,6 +149,7 @@ export class ContactForm extends LitElement {
147
149
  autocomplete: 'address-line1',
148
150
  icon: localePinImg,
149
151
  name: 'street-address',
152
+ validationPattern: '.*?\\S.{2,}\\S.*?',
150
153
  })}
151
154
  </div>
152
155
  <div class="row">
@@ -165,6 +168,7 @@ export class ContactForm extends LitElement {
165
168
  autocomplete: 'address-level2',
166
169
  required: true,
167
170
  name: 'locality',
171
+ validationPattern: '.*\\S{2,}.*',
168
172
  })}
169
173
  </div>
170
174
  <div class="row">
@@ -172,18 +176,17 @@ export class ContactForm extends LitElement {
172
176
  id: 'donation-contact-form-region',
173
177
  placeholder: 'State / Province',
174
178
  autocomplete: 'address-level1',
175
- required: true,
179
+ required: this.regionAndPostalCodeRequired,
176
180
  name: 'region',
181
+ validationPattern: '.*\\S{2,}.*',
177
182
  })}
178
183
  ${this.generateInput({
179
184
  id: 'donation-contact-form-postal-code',
180
185
  placeholder: 'Zip / Postal',
181
186
  autocomplete: 'postal-code',
182
- required: true,
187
+ required: this.regionAndPostalCodeRequired,
183
188
  name: 'postal',
184
- maxlength: 9,
185
- // must start with a character, then may contain spaces
186
- validationPattern: '[a-zA-Z\\-\\d]+[a-zA-Z\\-\\d\\s]*',
189
+ validationPattern: '^\\d{5}(-\\d{4})?$',
187
190
  iconSpaceOption: SpacerOption.CompressSpace,
188
191
  })}
189
192
  </div>
@@ -194,28 +197,18 @@ export class ContactForm extends LitElement {
194
197
  `;
195
198
  }
196
199
 
200
+ private get regionAndPostalCodeRequired(): boolean {
201
+ return this.selectedCountry === 'US';
202
+ }
203
+
197
204
  private get countrySelectorTemplate(): TemplateResult {
198
205
  return html`
199
206
  <badged-input>
200
207
  <select
201
208
  id="donation-contact-form-countryCodeAlpha2"
202
209
  @change=${(e: Event) => {
203
- const currCountry = this.selectedCountry;
204
- this.selectedCountry = (e.target as HTMLInputElement)?.value
205
- ? ((e.target as HTMLInputElement)?.value as string)
206
- : currCountry;
207
- // update required visual cue on region/state/province & postal code fields
208
- if (this.selectedCountry === 'US') {
209
- this.postalBadgedInput?.setAttribute('required', '');
210
- this.postalCodeField?.setAttribute('required', '');
211
- this.regionBadgedInput?.setAttribute('required', '');
212
- this.regionField?.setAttribute('required', '');
213
- } else {
214
- this.postalBadgedInput?.removeAttribute('required');
215
- this.postalCodeField?.removeAttribute('required');
216
- this.regionBadgedInput?.removeAttribute('required');
217
- this.regionField?.removeAttribute('required');
218
- }
210
+ const newValue = (e.target as HTMLSelectElement).value;
211
+ if (countries[newValue]) this.selectedCountry = newValue;
219
212
  }}
220
213
  >
221
214
  ${Object.keys(countries).map(key => {
@@ -253,6 +246,7 @@ export class ContactForm extends LitElement {
253
246
  required?: boolean;
254
247
  fieldType?: 'text' | 'email';
255
248
  autocomplete?: AutoCompleteFieldOptions;
249
+ minlength?: number;
256
250
  maxlength?: number;
257
251
  name: string;
258
252
  icon?: TemplateResult;
@@ -279,6 +273,7 @@ export class ContactForm extends LitElement {
279
273
  aria-label=${options.placeholder}
280
274
  placeholder=${options.placeholder}
281
275
  maxlength=${ifDefined(options.maxlength)}
276
+ minlength=${ifDefined(options.minlength)}
282
277
  autocomplete=${options.autocomplete ?? 'on'}
283
278
  pattern=${ifDefined(options.validationPattern)}
284
279
  @focus=${this.inputFocused}
@@ -297,8 +292,6 @@ export class ContactForm extends LitElement {
297
292
 
298
293
  get billingInfo(): BillingInfo {
299
294
  const billingInfo = new BillingInfo({
300
- firstName: this.firstNameField.value,
301
- lastName: this.lastNameField.value,
302
295
  streetAddress: this.streetAddressField.value,
303
296
  extendedAddress: this.extendedAddressField.value,
304
297
  locality: this.localityField.value,
@@ -86,8 +86,6 @@ export class GooglePayFlowHandler implements GooglePayFlowHandlerInterface {
86
86
  });
87
87
 
88
88
  const billing = new BillingInfo({
89
- firstName,
90
- lastName,
91
89
  streetAddress: billingInfo?.address1,
92
90
  extendedAddress: billingInfo?.address2,
93
91
  locality: billingInfo?.locality,
@@ -159,8 +159,6 @@ export class PayPalFlowHandler
159
159
  const shippingAddress = details.shippingAddress;
160
160
 
161
161
  const billingInfo = new BillingInfo({
162
- firstName: details?.firstName,
163
- lastName: details?.lastName,
164
162
  streetAddress: shippingAddress?.line1,
165
163
  extendedAddress: shippingAddress?.line2,
166
164
  locality: shippingAddress?.city,