diff --git a/src/elements/public/Transaction/Transaction.test.ts b/src/elements/public/Transaction/Transaction.test.ts index 9cd8cb5c..b3170bc7 100644 --- a/src/elements/public/Transaction/Transaction.test.ts +++ b/src/elements/public/Transaction/Transaction.test.ts @@ -67,10 +67,22 @@ describe('Transaction', () => { expect(customElements.get('foxy-internal-async-list-control')).to.exist; }); + it('imports and defines foxy-internal-summary-control', () => { + expect(customElements.get('foxy-internal-summary-control')).to.exist; + }); + + it('imports and defines foxy-internal-switch-control', () => { + expect(customElements.get('foxy-internal-switch-control')).to.exist; + }); + it('imports and defines foxy-internal-form', () => { expect(customElements.get('foxy-internal-form')).to.exist; }); + it('imports and defines foxy-internal-transaction-post-action-control', () => { + expect(customElements.get('foxy-internal-transaction-post-action-control')).to.exist; + }); + it('imports and defines foxy-internal-transaction-customer-control', () => { expect(customElements.get('foxy-internal-transaction-customer-control')).to.exist; }); @@ -139,6 +151,46 @@ describe('Transaction', () => { }); }); + it('always keeps datafeed controls readonly', () => { + const element = new Transaction(); + expect(element.readonlySelector.matches('datafeed', true)).to.be.true; + }); + + it("hides XML datafeed controls when store doesn't have XML datafeed enabled", async () => { + const router = createRouter(); + const element = await fixture(html` + !evt.defaultPrevented && router.handleEvent(evt)} + > + + `); + + await waitUntil( + () => { + if (!element.in({ idle: 'snapshot' })) return false; + const nucleons = element.renderRoot.querySelectorAll>('foxy-nucleon'); + return [...nucleons].every(nucleon => nucleon.in({ idle: 'snapshot' })); + }, + '', + { timeout: 5000 } + ); + + expect(element.hiddenSelector.matches('datafeed', true)).to.be.true; + expect(element.hiddenSelector.matches('actions:resend-datafeed', true)).to.be.true; + + const store = await getTestData>('https://demo.api/hapi/stores/0'); + store.use_webhook = true; + Transaction.Rumour('').share({ + source: 'https://demo.api/hapi/stores/0', + data: store, + }); + + await element.requestUpdate(); + expect(element.hiddenSelector.matches('datafeed', true)).to.be.false; + expect(element.hiddenSelector.matches('actions:resend-datafeed', true)).to.be.false; + }); + it('renders a form header', () => { const form = new Transaction(); const renderHeaderMethod = stub(form, 'renderHeader'); @@ -560,6 +612,24 @@ describe('Transaction', () => { expect(control).to.have.property('localName', 'foxy-internal-transaction-actions-control'); }); + it('renders a post action control for refeeding XML datafeed', async () => { + const router = createRouter(); + const element = await fixture(html` + !evt.defaultPrevented && router.handleEvent(evt)} + > + + `); + + await waitUntil(() => element.in({ idle: 'snapshot' })); + const control = element.renderRoot.querySelector('[infer="actions resend-datafeed"]'); + + expect(control).to.exist; + expect(control).to.have.property('localName', 'foxy-internal-transaction-post-action-control'); + expect(control).to.have.attribute('href', element.data!._links['fx:process_webhook'].href); + }); + it('renders customer info as control', async () => { const router = createRouter(); const element = await fixture(html` @@ -831,4 +901,25 @@ describe('Transaction', () => { expect(refeedRequest?.url).to.equal('https://demo.api/virtual/empty?status=200'); expect(await refeedRequest?.json()).to.deep.equal({ refeed_hooks: [0], event: 'refeed' }); }); + + it('renders XML datafeed status as control', async () => { + const router = createRouter(); + const element = await fixture(html` + !evt.defaultPrevented && router.handleEvent(evt)} + > + + `); + + await waitUntil(() => element.in({ idle: 'snapshot' })); + + const summary = element.renderRoot.querySelector('[infer="datafeed"]'); + expect(summary).to.exist; + expect(summary).to.have.property('localName', 'foxy-internal-summary-control'); + + const status = summary?.querySelector('[infer="data-is-fed"'); + expect(status).to.exist; + expect(status).to.have.property('localName', 'foxy-internal-switch-control'); + }); }); diff --git a/src/elements/public/Transaction/Transaction.ts b/src/elements/public/Transaction/Transaction.ts index 3fc133ef..16e7ffc9 100644 --- a/src/elements/public/Transaction/Transaction.ts +++ b/src/elements/public/Transaction/Transaction.ts @@ -76,7 +76,13 @@ export class Transaction extends Base { ]; get readonlySelector(): BooleanSelector { - const alwaysMatch = ['billing-addresses', 'webhooks:dialog:url', super.readonlySelector]; + const alwaysMatch = [ + 'billing-addresses', + 'datafeed', + 'webhooks:dialog:url', + super.readonlySelector, + ]; + const isEditable = Boolean(this.data?._links['fx:void'] ?? this.data?._links['fx:refund']); if (!isEditable) alwaysMatch.push('items', 'attributes', 'custom-fields'); return new BooleanSelector(alwaysMatch.join(' ').trim()); @@ -109,6 +115,10 @@ export class Transaction extends Base { alwaysMatch.unshift('not=customer,subscription,custom-fields,attributes'); } + if (!this.__storeLoader?.data?.use_webhook) { + alwaysMatch.unshift('datafeed', 'actions:resend-datafeed'); + } + return new BooleanSelector(alwaysMatch.join(' ').trim()); } @@ -187,6 +197,12 @@ export class Transaction extends Base { return html` + + + `; } @@ -324,6 +340,10 @@ export class Transaction extends Base { > + + + +