Skip to content

Commit

Permalink
feat: add glob to webhook definition (#345)
Browse files Browse the repository at this point in the history
* feat: add glob to webhook definition

* clarify typings and usage
  • Loading branch information
zzmp authored Jan 24, 2024
1 parent bb1fd11 commit 3f023e7
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 37 deletions.
10 changes: 6 additions & 4 deletions lib/providers/json-webhook-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,18 @@ export class JsonWebhookProvider implements WebhookProvider {
}

export function findEndpointsMatchingFilter(filter: OrderFilter, definition: WebhookDefinition): Webhook[] {
let endpoints: Webhook[] = []
const endpoints: Webhook[] = []

const catchallEndpoints = definition['*'] ?? []
endpoints.push(...catchallEndpoints)

const filterKeys = Object.keys(filter) as FILTER_FIELD[]
const filterMapping = definition.filter

for (const filterKey of filterKeys) {
const filterValue = filter[filterKey]
if (filterValue && Object.keys(filterMapping[filterKey]).includes(filterValue)) {
const registeredEndpoints = filterMapping[filterKey][filterValue]
endpoints = endpoints.concat(registeredEndpoints)
const filterEndpoints = filterMapping[filterKey][filterValue]
endpoints.push(...filterEndpoints)
}
}

Expand Down
4 changes: 3 additions & 1 deletion lib/providers/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ export enum FILTER_FIELD {
}

export type WebhookDefinition = {
/** Webhooks that are notified when the filter condition is matched. */
filter: WebhookFilterMapping
registeredWebhook: { [key: string]: string }
/** Webhooks that are notified on every order update. */
['*']?: Webhook[]
}

export type Webhook = {
Expand Down
90 changes: 58 additions & 32 deletions test/providers/s3-webhook-provider.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { S3Client } from '@aws-sdk/client-s3';
import { WebhookDefinition } from '../../lib/providers/types'
import { S3Client } from '@aws-sdk/client-s3'
import { S3WebhookConfigurationProvider } from '../../lib/providers/s3-webhook-provider'
import { WebhookDefinition } from '../../lib/providers/types'

describe('S3WebhookProvider test', () => {
const bucket = 'test-bucket';
const key = 'test-key';
const bucket = 'test-bucket'
const key = 'test-key'

function applyMock(endpoints: WebhookDefinition) {
jest.spyOn(S3Client.prototype, 'send').mockImplementationOnce(() =>
Expand All @@ -13,10 +13,9 @@ describe('S3WebhookProvider test', () => {
transformToString: () => Promise.resolve(JSON.stringify(endpoints)),
},
})
);
)
}


const mockEndpoints = {
filter: {
filler: {
Expand All @@ -25,7 +24,8 @@ describe('S3WebhookProvider test', () => {
orderStatus: { open: [{ url: 'webhook.com/2' }, { url: 'webhook.com/1' }] },
offerer: { '0x2': [{ url: 'webhook.com/4' }] },
},
registeredWebhook: {}
['*']: [{ url: 'webhook.com/0' }],
registeredWebhook: {},
}

const mockEndpoints2 = {
Expand All @@ -36,62 +36,88 @@ describe('S3WebhookProvider test', () => {
orderStatus: { open: [{ url: 'webhook2.com/2' }, { url: 'webhook2.com/1' }] },
offerer: { '0x2': [{ url: 'webhook2.com/4' }] },
},
registeredWebhook: {}
['*']: [{ url: 'webhook.com/0' }],
registeredWebhook: {},
}

it('Fetches endpoints', async () => {
applyMock(mockEndpoints);
const provider = new S3WebhookConfigurationProvider(bucket, key);
applyMock(mockEndpoints)
const provider = new S3WebhookConfigurationProvider(bucket, key)
const endpoints = await provider.getEndpoints({
filler: '0x1',
orderStatus: 'open',
offerer: '0x2',
} as any)
expect(endpoints).toEqual([{ url: 'webhook.com/1' }, { url: 'webhook.com/2' }, { url: 'webhook.com/4' }])
});
})
expect(endpoints).toEqual([
{ url: 'webhook.com/0' },
{ url: 'webhook.com/1' },
{ url: 'webhook.com/2' },
{ url: 'webhook.com/4' },
])
})

it('Caches fetched endpoints', async () => {
applyMock(mockEndpoints);
const provider = new S3WebhookConfigurationProvider(bucket, key);
let endpoints = await provider.getEndpoints({
applyMock(mockEndpoints)
const provider = new S3WebhookConfigurationProvider(bucket, key)
const endpoints = await provider.getEndpoints({
filler: '0x1',
orderStatus: 'open',
offerer: '0x2',
} as any)
expect(endpoints).toEqual([{ url: 'webhook.com/1' }, { url: 'webhook.com/2' }, { url: 'webhook.com/4' }])
});
})
expect(endpoints).toEqual([
{ url: 'webhook.com/0' },
{ url: 'webhook.com/1' },
{ url: 'webhook.com/2' },
{ url: 'webhook.com/4' },
])
})

it('Refetches after cache expires', async () => {
applyMock(mockEndpoints);
const provider = new S3WebhookConfigurationProvider(bucket, key);
applyMock(mockEndpoints)
const provider = new S3WebhookConfigurationProvider(bucket, key)
let endpoints = await provider.getEndpoints({
filler: '0x1',
orderStatus: 'open',
offerer: '0x2',
} as any)
expect(endpoints).toEqual([{ url: 'webhook.com/1' }, { url: 'webhook.com/2' }, { url: 'webhook.com/4' }])
})
expect(endpoints).toEqual([
{ url: 'webhook.com/0' },
{ url: 'webhook.com/1' },
{ url: 'webhook.com/2' },
{ url: 'webhook.com/4' },
])

// update mock endpoints and skip a small bit of time forward
// should still use the old ones
applyMock(mockEndpoints2);
jest.useFakeTimers().setSystemTime(Date.now() + 100);
applyMock(mockEndpoints2)
jest.useFakeTimers().setSystemTime(Date.now() + 100)
endpoints = await provider.getEndpoints({
filler: '0x1',
orderStatus: 'open',
offerer: '0x2',
} as any)
})
// should still equal old ones
expect(endpoints).toEqual([{ url: 'webhook.com/1' }, { url: 'webhook.com/2' }, { url: 'webhook.com/4' }])
expect(endpoints).toEqual([
{ url: 'webhook.com/0' },
{ url: 'webhook.com/1' },
{ url: 'webhook.com/2' },
{ url: 'webhook.com/4' },
])

// skip farther forward
applyMock(mockEndpoints2);
jest.useFakeTimers().setSystemTime(Date.now() + 1000000);
applyMock(mockEndpoints2)
jest.useFakeTimers().setSystemTime(Date.now() + 1000000)
endpoints = await provider.getEndpoints({
filler: '0x1',
orderStatus: 'open',
offerer: '0x2',
} as any)
})
// should still equal old ones
expect(endpoints).toEqual([{ url: 'webhook2.com/1' }, { url: 'webhook2.com/2' }, { url: 'webhook2.com/4' }])
});
expect(endpoints).toEqual([
{ url: 'webhook.com/0' },
{ url: 'webhook2.com/1' },
{ url: 'webhook2.com/2' },
{ url: 'webhook2.com/4' },
])
})
})

0 comments on commit 3f023e7

Please sign in to comment.