Skip to content

Commit

Permalink
feat(foxy-webhook-form): filter logs and statuses when resource uri i…
Browse files Browse the repository at this point in the history
…s set
  • Loading branch information
pheekus committed Aug 22, 2024
1 parent c4638ff commit 0f1d405
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 6 deletions.
53 changes: 51 additions & 2 deletions src/elements/public/WebhookForm/WebhookForm.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ describe('WebhookForm', () => {
expect(new WebhookForm()).to.have.property('ns', 'webhook-form');
});

it('has a reactive property "resourceUri" that defaults to null', () => {
expect(new WebhookForm()).to.have.property('resourceUri', null);
expect(WebhookForm).to.have.deep.nested.property('properties.resourceUri', {
attribute: 'resource-uri',
});
});

it('produces an v8n error if webhook name is missing', () => {
const form = new WebhookForm();
expect(WebhookForm.v8n.map(fn => fn({}, form))).to.include('name:v8n_required');
Expand Down Expand Up @@ -162,13 +169,34 @@ describe('WebhookForm', () => {

element.data = webhook;
await element.requestUpdate();
const control = element.renderRoot.querySelector('[infer="statuses"]');

expect(control).to.exist;
expect(control).to.be.instanceOf(InternalAsyncListControl);
expect(control).to.have.property('item', 'foxy-webhook-status-card');
expect(control).to.have.property(
'first',
'https://demo.api/hapi/webhook_statuses?webhook_id=0&order=date_created+desc'
);
});

it('includes only resource-specific statuses when resource uri is set', async () => {
const webhook = await getTestData<Data>('./hapi/webhooks/0');
const element = await fixture<WebhookForm>(html`
<foxy-webhook-form resource-uri="https://demo.api/hapi/transactions/0"></foxy-webhook-form>
`);

element.data = webhook;
await element.requestUpdate();
const control = element.renderRoot.querySelector('[infer="statuses"]');

expect(control).to.exist;
expect(control).to.be.instanceOf(InternalAsyncListControl);
expect(control).to.have.property('first', webhook._links['fx:statuses'].href);
expect(control).to.have.property('item', 'foxy-webhook-status-card');
expect(control).to.have.property(
'first',
'https://demo.api/hapi/webhook_statuses?webhook_id=0&resource_id=0&order=date_created+desc'
);
});

it('renders webhook logs when an existing webhook is loaded', async () => {
Expand All @@ -177,13 +205,34 @@ describe('WebhookForm', () => {

element.data = webhook;
await element.requestUpdate();
const control = element.renderRoot.querySelector('[infer="logs"]');

expect(control).to.exist;
expect(control).to.be.instanceOf(InternalAsyncListControl);
expect(control).to.have.property('item', 'foxy-webhook-log-card');
expect(control).to.have.property(
'first',
'https://demo.api/hapi/webhook_logs?webhook_id=0&order=date_created+desc'
);
});

it('includes only resource-specific logs when resource uri is set', async () => {
const webhook = await getTestData<Data>('./hapi/webhooks/0');
const element = await fixture<WebhookForm>(html`
<foxy-webhook-form resource-uri="https://demo.api/hapi/transactions/0"></foxy-webhook-form>
`);

element.data = webhook;
await element.requestUpdate();
const control = element.renderRoot.querySelector('[infer="logs"]');

expect(control).to.exist;
expect(control).to.be.instanceOf(InternalAsyncListControl);
expect(control).to.have.property('first', webhook._links['fx:logs'].href);
expect(control).to.have.property('item', 'foxy-webhook-log-card');
expect(control).to.have.property(
'first',
'https://demo.api/hapi/webhook_logs?webhook_id=0&resource_id=0&order=date_created+desc'
);
});

it('hides event resource selector when loaded', async () => {
Expand Down
46 changes: 42 additions & 4 deletions src/elements/public/WebhookForm/WebhookForm.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import type { PropertyDeclarations } from 'lit-element';
import type { TemplateResult } from 'lit-html';
import type { NucleonV8N } from '../NucleonElement/types';
import type { Data } from './types';

import { BooleanSelector, getResourceId } from '@foxy.io/sdk/core';
import { TranslatableMixin } from '../../../mixins/translatable';
import { BooleanSelector } from '@foxy.io/sdk/core';
import { InternalForm } from '../../internal/InternalForm/InternalForm';
import { ifDefined } from 'lit-html/directives/if-defined';
import { html } from 'lit-html';

/**
Expand All @@ -14,6 +16,13 @@ import { html } from 'lit-html';
* @since 1.17.0
*/
export class WebhookForm extends TranslatableMixin(InternalForm, 'webhook-form')<Data> {
static get properties(): PropertyDeclarations {
return {
...super.properties,
resourceUri: { attribute: 'resource-uri' },
};
}

static get v8n(): NucleonV8N<Data> {
return [
({ name: v }) => !!v || 'name:v8n_required',
Expand All @@ -25,6 +34,12 @@ export class WebhookForm extends TranslatableMixin(InternalForm, 'webhook-form')
];
}

/**
* Optional URI of a transaction, customer or subscription. When provided,
* the form will display logs and statuses for that particular resource only.
*/
resourceUri: string | null = null;

private __encryptionKeyGeneratorOptions = { separator: '', length: 512 };

private __eventResources = [
Expand All @@ -51,6 +66,29 @@ export class WebhookForm extends TranslatableMixin(InternalForm, 'webhook-form')
}

renderBody(): TemplateResult {
const resourceId = this.resourceUri ? getResourceId(this.resourceUri) : null;

let statusesLink: string | undefined;
let logsLink: string | undefined;

try {
const url = new URL(this.data?._links['fx:statuses'].href ?? '');
if (resourceId !== null) url.searchParams.set('resource_id', String(resourceId));
url.searchParams.set('order', 'date_created desc');
statusesLink = url.toString();
} catch {
statusesLink = undefined;
}

try {
const url = new URL(this.data?._links['fx:logs'].href ?? '');
if (resourceId !== null) url.searchParams.set('resource_id', String(resourceId));
url.searchParams.set('order', 'date_created desc');
logsLink = url.toString();
} catch {
logsLink = undefined;
}

return html`
${this.renderHeader()}
Expand All @@ -72,17 +110,17 @@ export class WebhookForm extends TranslatableMixin(InternalForm, 'webhook-form')
${this.data
? html`
<foxy-internal-async-list-control
first=${this.data._links['fx:statuses'].href}
first=${ifDefined(statusesLink)}
infer="statuses"
limit="10"
item="foxy-webhook-status-card"
>
</foxy-internal-async-list-control>
<foxy-internal-async-list-control
first=${this.data._links['fx:logs'].href}
first=${ifDefined(logsLink)}
infer="logs"
limit="5"
limit="10"
item="foxy-webhook-log-card"
>
</foxy-internal-async-list-control>
Expand Down

0 comments on commit 0f1d405

Please sign in to comment.