Skip to content

Commit 9668ecc

Browse files
committed
feat(foxy-native-integration-form): improve category to tax code mapping ui for taxes
1 parent 91b36b0 commit 9668ecc

File tree

9 files changed

+520
-109
lines changed

9 files changed

+520
-109
lines changed

src/elements/public/NativeIntegrationForm/NativeIntegrationForm.stories.ts

+11-8
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,15 @@ const summary: Summary = {
4343
'avalara-group-one:avalara-id',
4444
'avalara-group-one:avalara-key',
4545
'avalara-group-one:avalara-company-code',
46-
'avalara-group-two:avalara-category-to-product-tax-code-mappings',
47-
'avalara-group-three:avalara-use-ava-tax',
48-
'avalara-group-three:avalara-enable-colorado-delivery-fee',
49-
'avalara-group-three:avalara-create-invoice',
50-
'avalara-group-three:avalara-use-address-validation',
51-
'avalara-group-three:avalara-address-validation-countries',
46+
'avalara-group-two:avalara-use-ava-tax',
47+
'avalara-group-two:avalara-enable-colorado-delivery-fee',
48+
'avalara-group-two:avalara-create-invoice',
49+
'avalara-group-two:avalara-use-address-validation',
50+
'avalara-group-two:avalara-address-validation-countries',
51+
'avalara-category-to-product-tax-code-mappings',
5252
'taxjar-group-one:taxjar-api-token',
5353
'taxjar-group-one:taxjar-create-invoice',
54-
'taxjar-group-two:taxjar-category-to-product-tax-code-mappings',
54+
'taxjar-category-to-product-tax-code-mappings',
5555
'onesource-group-one:onesource-service-url',
5656
'onesource-group-one:onesource-external-company-id',
5757
'onesource-group-one:onesource-from-city',
@@ -88,7 +88,10 @@ const summary: Summary = {
8888

8989
export default getMeta(summary);
9090

91-
const ext = `store="https://demo.api/hapi/stores/0"`;
91+
const ext = `
92+
item-category-base="https://demo.api/hapi/item_categories/"
93+
store="https://demo.api/hapi/stores/0"
94+
`;
9295

9396
export const Playground = getStory({ ...summary, ext, code: true });
9497
export const Legacy = getStory({ ...summary, ext });

src/elements/public/NativeIntegrationForm/NativeIntegrationForm.test.ts

+90-39
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
import type { InternalNativeIntegrationFormCodeMapControl } from './internal/InternalNativeIntegrationFormCodeMapControl/InternalNativeIntegrationFormCodeMapControl';
2+
import type { InternalPasswordControl } from '../../internal/InternalPasswordControl/InternalPasswordControl';
3+
import type { InternalSwitchControl } from '../../internal/InternalSwitchControl/InternalSwitchControl';
4+
import type { InternalTextControl } from '../../internal/InternalTextControl/InternalTextControl';
5+
import type { NucleonElement } from '../NucleonElement/NucleonElement';
16
import type { Data } from './types';
27

38
import './index';
@@ -6,9 +11,6 @@ import { expect, fixture, html, waitUntil } from '@open-wc/testing';
611
import { NativeIntegrationForm as Form } from './NativeIntegrationForm';
712
import { InternalEditableListControl } from '../../internal/InternalEditableListControl/InternalEditableListControl';
813
import { InternalSelectControl } from '../../internal/InternalSelectControl/InternalSelectControl';
9-
import { InternalPasswordControl } from '../../internal/InternalPasswordControl/InternalPasswordControl';
10-
import { InternalSwitchControl } from '../../internal/InternalSwitchControl/InternalSwitchControl';
11-
import { InternalTextControl } from '../../internal/InternalTextControl/InternalTextControl';
1214
import { createRouter } from '../../../server';
1315
import { getTestData } from '../../../testgen/getTestData';
1416
import { FetchEvent } from '../NucleonElement/FetchEvent';
@@ -17,6 +19,17 @@ import { stub } from 'sinon';
1719

1820
import * as defaults from './defaults';
1921

22+
async function waitForIdle(element: Form) {
23+
await waitUntil(
24+
() => {
25+
const loaders = element.renderRoot.querySelectorAll<NucleonElement<any>>('foxy-nucleon');
26+
return [...loaders].every(loader => loader.in('idle'));
27+
},
28+
'',
29+
{ timeout: 5000 }
30+
);
31+
}
32+
2033
describe('NativeIntegrationForm', () => {
2134
it('imports and defines foxy-internal-editable-list-control element', () => {
2235
expect(customElements.get('foxy-internal-editable-list-control')).to.exist;
@@ -46,6 +59,10 @@ describe('NativeIntegrationForm', () => {
4659
expect(customElements.get('foxy-internal-form')).to.exist;
4760
});
4861

62+
it('imports and defines foxy-internal-native-integration-form-code-map-control element', () => {
63+
expect(customElements.get('foxy-internal-native-integration-form-code-map-control')).to.exist;
64+
});
65+
4966
it('defines itself as foxy-native-integration-form element', () => {
5067
expect(customElements.get('foxy-native-integration-form')).to.equal(Form);
5168
});
@@ -59,6 +76,14 @@ describe('NativeIntegrationForm', () => {
5976
expect(new Form()).to.have.property('ns', 'native-integration-form');
6077
});
6178

79+
it('has a reactive property itemCategoryBase', () => {
80+
const element = new Form();
81+
expect(element).to.have.property('itemCategoryBase').that.equals(null);
82+
expect(Form.properties).to.have.deep.property('itemCategoryBase', {
83+
attribute: 'item-category-base',
84+
});
85+
});
86+
6287
it('produces avalara-service-url:v8n_required error if service url for avalara is missing', () => {
6388
const element = new Form();
6489
element.edit({ provider: 'avalara' });
@@ -101,15 +126,6 @@ describe('NativeIntegrationForm', () => {
101126
expect(element.errors).to.not.include('avalara-company-code:v8n_required');
102127
});
103128

104-
it('produces avalara-category-to-product-tax-code-mappings:v8n_required error if there are no mappings for avalara', () => {
105-
const element = new Form();
106-
const error = 'avalara-category-to-product-tax-code-mappings:v8n_required';
107-
element.edit({ provider: 'avalara' });
108-
expect(element.errors).to.include(error);
109-
element.edit({ config: JSON.stringify({ category_to_product_tax_code_mappings: { a: 'b' } }) });
110-
expect(element.errors).to.not.include(error);
111-
});
112-
113129
it('produces taxjar-api-token:v8n_required error if api token for taxjar is missing', () => {
114130
const element = new Form();
115131
element.edit({ provider: 'taxjar' });
@@ -493,32 +509,49 @@ describe('NativeIntegrationForm', () => {
493509
expect(control).to.have.attribute('layout', 'summary-item');
494510
});
495511

496-
it('renders an editable list control for avalara tax code mappings in avalara group two', async () => {
512+
it('renders an internal control for avalara tax code mappings', async () => {
497513
const data = await getTestData<Data>('./hapi/native_integrations/0');
514+
const router = createRouter();
515+
498516
data.provider = 'avalara';
499517
data.config = JSON.stringify({
500518
...JSON.parse(defaults.avalara),
501519
category_to_product_tax_code_mappings: { foo: 'bar', bar: 'qux' },
502520
});
503521

504522
const element = await fixture<Form>(html`
505-
<foxy-native-integration-form .data=${data}></foxy-native-integration-form>
523+
<foxy-native-integration-form
524+
item-category-base="https://demo.api/hapi/item_categories/"
525+
store="https://demo.api/hapi/stores/0"
526+
.data=${data}
527+
@fetch=${(evt: FetchEvent) => router.handleEvent(evt)}
528+
>
529+
</foxy-native-integration-form>
506530
`);
507531

532+
await waitForIdle(element);
508533
const control = element.renderRoot.querySelector(
509-
'foxy-internal-summary-control[infer="avalara-group-two"] foxy-internal-editable-list-control[infer="avalara-category-to-product-tax-code-mappings"]'
510-
) as InternalEditableListControl;
534+
'foxy-internal-native-integration-form-code-map-control[infer="avalara-category-to-product-tax-code-mappings"]'
535+
) as InternalNativeIntegrationFormCodeMapControl;
511536

512537
expect(control).to.exist;
513-
expect(control).to.have.attribute('layout', 'summary-item');
514-
expect(control.getValue()).to.deep.equal([{ value: 'foo:bar' }, { value: 'bar:qux' }]);
515538

516-
control.setValue([{ value: 'a:b' }]);
517-
const config = JSON.parse(element.form.config as string);
518-
expect(config).to.have.deep.property('category_to_product_tax_code_mappings', { a: 'b' });
539+
expect(control).to.have.attribute(
540+
'item-category-base',
541+
'https://demo.api/hapi/item_categories/'
542+
);
543+
544+
expect(control).to.have.attribute(
545+
'item-categories',
546+
'https://demo.api/hapi/item_categories?store_id=0'
547+
);
548+
549+
expect(control).to.have.attribute('json-template', defaults.avalara);
550+
expect(control).to.have.attribute('json-path', 'category_to_product_tax_code_mappings');
551+
expect(control).to.have.attribute('property', 'config');
519552
});
520553

521-
it('renders a switch control for avalara use_ava_tax in avalara group three', async () => {
554+
it('renders a switch control for avalara use_ava_tax in avalara group two', async () => {
522555
const data = await getTestData<Data>('./hapi/native_integrations/0');
523556
data.provider = 'avalara';
524557
data.config = JSON.stringify({ ...JSON.parse(defaults.avalara), use_ava_tax: true });
@@ -528,7 +561,7 @@ describe('NativeIntegrationForm', () => {
528561
`);
529562

530563
const control = element.renderRoot.querySelector(
531-
'foxy-internal-summary-control[infer="avalara-group-three"] foxy-internal-switch-control[infer="avalara-use-ava-tax"]'
564+
'foxy-internal-summary-control[infer="avalara-group-two"] foxy-internal-switch-control[infer="avalara-use-ava-tax"]'
532565
);
533566

534567
expect(control).to.exist;
@@ -537,7 +570,7 @@ describe('NativeIntegrationForm', () => {
537570
expect(control).to.have.attribute('property', 'config');
538571
});
539572

540-
it('renders a switch control for avalara use_address_validation in avalara group three', async () => {
573+
it('renders a switch control for avalara use_address_validation in avalara group two', async () => {
541574
const data = await getTestData<Data>('./hapi/native_integrations/0');
542575
data.provider = 'avalara';
543576
data.config = JSON.stringify({ ...JSON.parse(defaults.avalara), use_address_validation: true });
@@ -547,7 +580,7 @@ describe('NativeIntegrationForm', () => {
547580
`);
548581

549582
const control = element.renderRoot.querySelector(
550-
'foxy-internal-summary-control[infer="avalara-group-three"] foxy-internal-switch-control[infer="avalara-use-address-validation"]'
583+
'foxy-internal-summary-control[infer="avalara-group-two"] foxy-internal-switch-control[infer="avalara-use-address-validation"]'
551584
);
552585

553586
expect(control).to.exist;
@@ -569,7 +602,7 @@ describe('NativeIntegrationForm', () => {
569602
`);
570603

571604
const control = element.renderRoot.querySelector(
572-
'foxy-internal-summary-control[infer="avalara-group-three"] foxy-internal-editable-list-control[infer="avalara-address-validation-countries"]'
605+
'foxy-internal-summary-control[infer="avalara-group-two"] foxy-internal-editable-list-control[infer="avalara-address-validation-countries"]'
573606
) as InternalEditableListControl;
574607

575608
expect(control).to.exist;
@@ -580,7 +613,7 @@ describe('NativeIntegrationForm', () => {
580613
expect(control).to.have.deep.property('options', [{ value: 'US' }, { value: 'CA' }]);
581614
});
582615

583-
it('renders a switch control for avalara create_invoice in avalara group three', async () => {
616+
it('renders a switch control for avalara create_invoice in avalara group two', async () => {
584617
const data = await getTestData<Data>('./hapi/native_integrations/0');
585618
data.provider = 'avalara';
586619
data.config = JSON.stringify({ ...JSON.parse(defaults.avalara), create_invoice: true });
@@ -590,7 +623,7 @@ describe('NativeIntegrationForm', () => {
590623
`);
591624

592625
const control = element.renderRoot.querySelector(
593-
'foxy-internal-summary-control[infer="avalara-group-three"] foxy-internal-switch-control[infer="avalara-create-invoice"]'
626+
'foxy-internal-summary-control[infer="avalara-group-two"] foxy-internal-switch-control[infer="avalara-create-invoice"]'
594627
);
595628

596629
expect(control).to.exist;
@@ -599,7 +632,7 @@ describe('NativeIntegrationForm', () => {
599632
expect(control).to.have.attribute('property', 'config');
600633
});
601634

602-
it('renders a switch control for avalara enable_colorado_delivery_fee in avalara group three', async () => {
635+
it('renders a switch control for avalara enable_colorado_delivery_fee in avalara group two', async () => {
603636
const data = await getTestData<Data>('./hapi/native_integrations/0');
604637
data.provider = 'avalara';
605638
data.config = JSON.stringify({
@@ -612,7 +645,7 @@ describe('NativeIntegrationForm', () => {
612645
`);
613646

614647
const control = element.renderRoot.querySelector(
615-
'foxy-internal-summary-control[infer="avalara-group-three"] foxy-internal-switch-control[infer="avalara-enable-colorado-delivery-fee"]'
648+
'foxy-internal-summary-control[infer="avalara-group-two"] foxy-internal-switch-control[infer="avalara-enable-colorado-delivery-fee"]'
616649
);
617650

618651
expect(control).to.exist;
@@ -660,28 +693,46 @@ describe('NativeIntegrationForm', () => {
660693
expect(control).to.have.attribute('property', 'config');
661694
});
662695

663-
it('renders an editable list control for taxjar product code mappings in taxjar group two', async () => {
696+
it('renders an internal control for taxjar tax code mappings', async () => {
664697
const data = await getTestData<Data>('./hapi/native_integrations/0');
698+
const router = createRouter();
699+
665700
data.provider = 'taxjar';
666701
data.config = JSON.stringify({
667702
...JSON.parse(defaults.taxjar),
668703
category_to_product_tax_code_mappings: { foo: 'bar', bar: 'qux' },
669704
});
670705

671706
const element = await fixture<Form>(html`
672-
<foxy-native-integration-form .data=${data}></foxy-native-integration-form>
707+
<foxy-native-integration-form
708+
item-category-base="https://demo.api/hapi/item_categories/"
709+
store="https://demo.api/hapi/stores/0"
710+
.data=${data}
711+
@fetch=${(evt: FetchEvent) => router.handleEvent(evt)}
712+
>
713+
</foxy-native-integration-form>
673714
`);
674715

716+
await waitForIdle(element);
675717
const control = element.renderRoot.querySelector(
676-
'[infer="taxjar-group-two"] foxy-internal-editable-list-control[infer="taxjar-category-to-product-tax-code-mappings"]'
677-
) as InternalEditableListControl;
718+
'foxy-internal-native-integration-form-code-map-control[infer="taxjar-category-to-product-tax-code-mappings"]'
719+
) as InternalNativeIntegrationFormCodeMapControl;
678720

679-
expect(control).to.be.instanceOf(InternalEditableListControl);
680-
expect(control.getValue()).to.deep.equal([{ value: 'foo:bar' }, { value: 'bar:qux' }]);
721+
expect(control).to.exist;
681722

682-
control.setValue([{ value: 'a:b' }]);
683-
const config = JSON.parse(element.form.config as string);
684-
expect(config).to.have.deep.property('category_to_product_tax_code_mappings', { a: 'b' });
723+
expect(control).to.have.attribute(
724+
'item-category-base',
725+
'https://demo.api/hapi/item_categories/'
726+
);
727+
728+
expect(control).to.have.attribute(
729+
'item-categories',
730+
'https://demo.api/hapi/item_categories?store_id=0'
731+
);
732+
733+
expect(control).to.have.attribute('json-template', defaults.taxjar);
734+
expect(control).to.have.attribute('json-path', 'category_to_product_tax_code_mappings');
735+
expect(control).to.have.attribute('property', 'config');
685736
});
686737

687738
it('renders a text control for onesource service url in onesource group one', async () => {

0 commit comments

Comments
 (0)