diff --git a/scheduler-utils/package-lock.json b/scheduler-utils/package-lock.json index a02006687..92a7df0b0 100644 --- a/scheduler-utils/package-lock.json +++ b/scheduler-utils/package-lock.json @@ -9,7 +9,8 @@ "version": "0.0.17", "dependencies": { "lru-cache": "^10.2.0", - "ramda": "^0.29.1" + "ramda": "^0.29.1", + "zod": "^3.22.4" }, "devDependencies": { "esbuild": "^0.20.1", @@ -454,6 +455,14 @@ "engines": { "node": ">=14.17" } + }, + "node_modules/zod": { + "version": "3.22.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", + "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } }, "dependencies": { @@ -664,6 +673,11 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", "dev": true + }, + "zod": { + "version": "3.22.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", + "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==" } } } diff --git a/scheduler-utils/package.json b/scheduler-utils/package.json index f150fa857..bb6421741 100644 --- a/scheduler-utils/package.json +++ b/scheduler-utils/package.json @@ -32,7 +32,8 @@ }, "dependencies": { "lru-cache": "^10.2.0", - "ramda": "^0.29.1" + "ramda": "^0.29.1", + "zod": "^3.22.4" }, "devDependencies": { "esbuild": "^0.20.1", diff --git a/scheduler-utils/src/client/gateway.js b/scheduler-utils/src/client/gateway.js index bcfea14a0..cc5c211e0 100644 --- a/scheduler-utils/src/client/gateway.js +++ b/scheduler-utils/src/client/gateway.js @@ -102,6 +102,6 @@ export function loadSchedulerWith ({ fetch, GRAPHQL_URL }) { .then(([url, ttl]) => { if (!url) throw new InvalidSchedulerLocationError('No "Url" tag found on Scheduler-Location') if (!ttl) throw new InvalidSchedulerLocationError('No "Time-To-Live" tag found on Scheduler-Location') - return { url, ttl, owner: walletAddress } + return { url, ttl, address: walletAddress } }) } diff --git a/scheduler-utils/src/client/gateway.test.js b/scheduler-utils/src/client/gateway.test.js index 6e738a29c..0a439c143 100644 --- a/scheduler-utils/src/client/gateway.test.js +++ b/scheduler-utils/src/client/gateway.test.js @@ -1,6 +1,7 @@ import { describe, test } from 'node:test' import * as assert from 'node:assert' +import { loadProcessSchedulerSchema, loadSchedulerSchema } from '../dal.js' import { InvalidSchedulerLocationError, SchedulerTagNotFoundError } from '../err.js' import { loadProcessSchedulerWith, loadSchedulerWith } from './gateway.js' @@ -61,16 +62,18 @@ describe('gateway', () => { } } - const loadProcessScheduler = loadProcessSchedulerWith({ - GRAPHQL_URL, - fetch: mockFetch - }) + const loadProcessScheduler = loadProcessSchedulerSchema.implement( + loadProcessSchedulerWith({ + GRAPHQL_URL, + fetch: mockFetch + }) + ) await loadProcessScheduler(PROCESS) .then((res) => { assert.equal(res.url, 'https://foo.bar') assert.equal(res.ttl, `${TWO_DAYS}`) - assert.equal(res.owner, SCHEDULER) + assert.equal(res.address, SCHEDULER) }) }) @@ -94,10 +97,12 @@ describe('gateway', () => { } } - const loadProcessScheduler = loadProcessSchedulerWith({ - GRAPHQL_URL, - fetch: mockFetch - }) + const loadProcessScheduler = loadProcessSchedulerSchema.implement( + loadProcessSchedulerWith({ + GRAPHQL_URL, + fetch: mockFetch + }) + ) await loadProcessScheduler(PROCESS) .catch((err) => assert.ok(err instanceof SchedulerTagNotFoundError)) @@ -129,16 +134,18 @@ describe('gateway', () => { } } - const loadScheduler = loadSchedulerWith({ - GRAPHQL_URL, - fetch: mockFetch - }) + const loadScheduler = loadSchedulerSchema.implement( + loadSchedulerWith({ + GRAPHQL_URL, + fetch: mockFetch + }) + ) await loadScheduler(SCHEDULER) .then((res) => { assert.equal(res.url, 'https://foo.bar') assert.equal(res.ttl, `${TWO_DAYS}`) - assert.equal(res.owner, SCHEDULER) + assert.equal(res.address, SCHEDULER) }) }) @@ -166,10 +173,12 @@ describe('gateway', () => { } } - const loadScheduler = loadSchedulerWith({ - GRAPHQL_URL, - fetch: mockFetch - }) + const loadScheduler = loadSchedulerSchema.implement( + loadSchedulerWith({ + GRAPHQL_URL, + fetch: mockFetch + }) + ) await loadScheduler(SCHEDULER) .catch((err) => { @@ -202,10 +211,12 @@ describe('gateway', () => { } } - const loadScheduler = loadSchedulerWith({ - GRAPHQL_URL, - fetch: mockFetch - }) + const loadScheduler = loadSchedulerSchema.implement( + loadSchedulerWith({ + GRAPHQL_URL, + fetch: mockFetch + }) + ) await loadScheduler(SCHEDULER) .catch((err) => { diff --git a/scheduler-utils/src/client/in-memory.js b/scheduler-utils/src/client/in-memory.js index 1bd91dd2c..d077fc537 100644 --- a/scheduler-utils/src/client/in-memory.js +++ b/scheduler-utils/src/client/in-memory.js @@ -57,6 +57,6 @@ export function getByOwnerWith ({ cache }) { export function setByOwnerWith ({ cache }) { return async (owner, url, ttl) => { if (!cache.max) return - return cache.set(owner, { url, address: owner }, { ttl }) + return cache.set(owner, { url, address: owner, ttl }, { ttl }) } } diff --git a/scheduler-utils/src/client/in-memory.test.js b/scheduler-utils/src/client/in-memory.test.js index c0df219ab..8b1135af4 100644 --- a/scheduler-utils/src/client/in-memory.test.js +++ b/scheduler-utils/src/client/in-memory.test.js @@ -1,6 +1,7 @@ -import { describe, test, beforeEach } from 'node:test' +import { describe, test } from 'node:test' import * as assert from 'node:assert' +import { getByOwnerSchema, getByProcessSchema, setByOwnerSchema, setByProcessSchema } from '../dal.js' import { createLruCache, getByProcessWith, getByOwnerWith, setByProcessWith, setByOwnerWith } from './in-memory.js' const PROCESS = 'zc24Wpv_i6NNCEdxeKt7dcNrqL5w0hrShtSCcFGGL24' @@ -10,22 +11,18 @@ const TEN_MS = 10 const SIZE = 10 describe('in-memory', () => { - const cache = createLruCache({ size: SIZE }) - - beforeEach(() => { - cache.clear() - }) - describe('getByProcessWith', () => { - test('returns the url if in cache', async () => { - const getByProcess = getByProcessWith({ cache }) + test('returns the cached entry', async () => { + const cache = createLruCache({ size: SIZE }) + const getByProcess = getByProcessSchema.implement(getByProcessWith({ cache })) assert.equal(await getByProcess(PROCESS), undefined) cache.set(PROCESS, { url: DOMAIN, address: SCHEDULER }) assert.deepStrictEqual(await getByProcess(PROCESS), { url: DOMAIN, address: SCHEDULER }) }) test('returns undefined if cache size is set to 0', async () => { - const getByProcess = getByProcessWith({ cache: createLruCache({ size: 0 }) }) + const cache = createLruCache({ size: 0 }) + const getByProcess = getByProcessSchema.implement(getByProcessWith({ cache })) assert.equal(await getByProcess(PROCESS), undefined) cache.set(PROCESS, { url: DOMAIN, address: SCHEDULER }) assert.deepStrictEqual(await getByProcess(PROCESS), undefined) @@ -33,44 +30,52 @@ describe('in-memory', () => { }) describe('getByOwnerWith', () => { - test('returns the url if in cache', async () => { - const getByOwner = getByOwnerWith({ cache }) + test('returns the cached entry', async () => { + const cache = createLruCache({ size: SIZE }) + const getByOwner = getByOwnerSchema.implement( + getByOwnerWith({ cache }) + ) assert.equal(await getByOwner(SCHEDULER), undefined) - cache.set(SCHEDULER, { url: DOMAIN, address: SCHEDULER }) - assert.deepStrictEqual(await getByOwner(SCHEDULER), { url: DOMAIN, address: SCHEDULER }) + cache.set(SCHEDULER, { url: DOMAIN, address: SCHEDULER, ttl: 10 }) + assert.deepStrictEqual(await getByOwner(SCHEDULER), { url: DOMAIN, address: SCHEDULER, ttl: 10 }) }) test('returns undefined if cache size is set to 0', async () => { - const getByOwner = getByOwnerWith({ cache: createLruCache({ size: 0 }) }) + const cache = createLruCache({ size: 0 }) + const getByOwner = getByOwnerSchema.implement(getByOwnerWith({ cache })) assert.equal(await getByOwner(SCHEDULER), undefined) - cache.set(SCHEDULER, { url: DOMAIN, address: SCHEDULER }) + cache.set(SCHEDULER, { url: DOMAIN, address: SCHEDULER, ttl: 10 }) assert.deepStrictEqual(await getByOwner(SCHEDULER), undefined) }) }) describe('setByProcessWith', () => { test('sets the value in cache', async () => { - const setByProcess = setByProcessWith({ cache }) - await setByProcess(PROCESS, DOMAIN, TEN_MS) - assert.ok(cache.has(PROCESS)) + const cache = createLruCache({ size: SIZE }) + const setByProcess = setByProcessSchema.implement(setByProcessWith({ cache })) + await setByProcess(PROCESS, { url: DOMAIN, address: SCHEDULER }, TEN_MS) + assert.deepStrictEqual(cache.get(PROCESS), { url: DOMAIN, address: SCHEDULER }) }) test('does nothing if cache size is set to 0', async () => { - const setByProcess = setByProcessWith({ cache: createLruCache({ size: 0 }) }) - await setByProcess(PROCESS, DOMAIN, TEN_MS) + const cache = createLruCache({ size: 0 }) + const setByProcess = setByProcessSchema.implement(setByProcessWith({ cache })) + await setByProcess(PROCESS, { url: DOMAIN, address: SCHEDULER }, TEN_MS) assert.ok(!cache.has(PROCESS)) }) }) describe('setByOwnerWith', () => { test('sets the value in cache', async () => { - const setByOwner = setByOwnerWith({ cache }) + const cache = createLruCache({ size: SIZE }) + const setByOwner = setByOwnerSchema.implement(setByOwnerWith({ cache })) await setByOwner(SCHEDULER, DOMAIN, TEN_MS) - assert.ok(cache.has(SCHEDULER)) + assert.deepStrictEqual(cache.get(SCHEDULER), { url: DOMAIN, address: SCHEDULER, ttl: TEN_MS }) }) test('does nothing if cache size is set to 0', async () => { - const setByOwner = setByOwnerWith({ cache: createLruCache({ size: 0 }) }) + const cache = createLruCache({ size: 0 }) + const setByOwner = setByOwnerSchema.implement(setByOwnerWith({ cache })) await setByOwner(SCHEDULER, DOMAIN, TEN_MS) assert.ok(!cache.has(SCHEDULER)) }) diff --git a/scheduler-utils/src/client/scheduler.test.js b/scheduler-utils/src/client/scheduler.test.js index 51fb16dce..684a3b5a1 100644 --- a/scheduler-utils/src/client/scheduler.test.js +++ b/scheduler-utils/src/client/scheduler.test.js @@ -1,6 +1,7 @@ import { test } from 'node:test' import assert from 'node:assert' import { checkForRedirectWith } from './scheduler.js' +import { checkForRedirectSchema } from '../dal.js' const mockFetch = (url, options) => { if (options.method === 'GET' && !url.includes('no-redirect')) { @@ -22,13 +23,17 @@ const mockFetch = (url, options) => { } test('checkForRedirectWith should return new location on redirect', async (_t) => { - const checkForRedirect = checkForRedirectWith({ fetch: mockFetch }) + const checkForRedirect = checkForRedirectSchema.implement( + checkForRedirectWith({ fetch: mockFetch }) + ) const result = await checkForRedirect('http://example.com/redirect', 'test-process') assert.strictEqual(result, 'http://newlocation.com', 'The function should return the new location URL on redirect') }) test('checkForRedirectWith should return original URL if no redirect', async (_t) => { - const checkForRedirect = checkForRedirectWith({ fetch: mockFetch }) + const checkForRedirect = checkForRedirectSchema.implement( + checkForRedirectWith({ fetch: mockFetch }) + ) const result = await checkForRedirect('http://example.com/no-redirect', 'test-process') assert.strictEqual(result, 'http://example.com/no-redirect', 'The function should return the original URL if there is no redirect') }) diff --git a/scheduler-utils/src/dal.js b/scheduler-utils/src/dal.js new file mode 100644 index 000000000..5fb76327b --- /dev/null +++ b/scheduler-utils/src/dal.js @@ -0,0 +1,30 @@ +import { z } from 'zod' + +const processCacheEntry = z.object({ url: z.string(), address: z.string() }) +const scheduler = z.object({ url: z.string(), address: z.string(), ttl: z.coerce.number() }) + +export const checkForRedirectSchema = z.function() + .args(z.string(), z.string()) + .returns(z.promise(z.string())) + +export const getByProcessSchema = z.function() + .args(z.string()) + .returns(z.promise(processCacheEntry.nullish())) + +export const setByProcessSchema = z.function() + .args(z.string(), processCacheEntry, z.number()) + .returns(z.promise(z.any())) + +export const getByOwnerSchema = z.function() + .args(z.string()) + .returns(z.promise(scheduler.nullish())) + +export const setByOwnerSchema = z.function() + .args(z.string(), z.string(), z.number()) + .returns(z.promise(z.any())) + +export const loadSchedulerSchema = z.function() + .args(z.string()) + .returns(z.promise(scheduler)) + +export const loadProcessSchedulerSchema = loadSchedulerSchema diff --git a/scheduler-utils/src/locate.js b/scheduler-utils/src/locate.js index 4f1598900..011f0737d 100644 --- a/scheduler-utils/src/locate.js +++ b/scheduler-utils/src/locate.js @@ -1,4 +1,14 @@ +import { checkForRedirectSchema, getByOwnerSchema, getByProcessSchema, loadProcessSchedulerSchema, loadSchedulerSchema, setByOwnerSchema, setByProcessSchema } from './dal.js' + export function locateWith ({ loadProcessScheduler, loadScheduler, cache, followRedirects, checkForRedirect }) { + loadProcessScheduler = loadProcessSchedulerSchema.implement(loadProcessScheduler) + loadScheduler = loadSchedulerSchema.implement(loadScheduler) + checkForRedirect = checkForRedirectSchema.implement(checkForRedirect) + const getByProcess = getByProcessSchema.implement(cache.getByProcess) + const getByOwner = getByOwnerSchema.implement(cache.getByOwner) + const setByProcess = setByProcessSchema.implement(cache.setByProcess) + const setByOwner = setByOwnerSchema.implement(cache.setByOwner) + /** * Locate the scheduler for the given process. * @@ -11,7 +21,7 @@ export function locateWith ({ loadProcessScheduler, loadScheduler, cache, follow * @returns {Promise<{ url: string, address: string }>} - an object whose url field is the Scheduler Location */ return (process, schedulerHint) => - cache.getByProcess(process) + getByProcess(process) .then(async (cached) => { if (cached) return cached @@ -23,11 +33,11 @@ export function locateWith ({ loadProcessScheduler, loadScheduler, cache, follow * query the Scheduler-Location record directly */ if (schedulerHint) { - const byOwner = await cache.getByOwner(schedulerHint) - if (byOwner) return (byOwner) + const byOwner = await getByOwner(schedulerHint) + if (byOwner) return byOwner return loadScheduler(schedulerHint).then((scheduler) => { - cache.setByOwner(scheduler.owner, scheduler.url, scheduler.ttl) + setByOwner(scheduler.address, scheduler.url, scheduler.ttl) return scheduler }) } @@ -43,8 +53,8 @@ export function locateWith ({ loadProcessScheduler, loadScheduler, cache, follow */ if (followRedirects) finalUrl = await checkForRedirect(scheduler.url, process) - const byProcess = { url: finalUrl, address: scheduler.owner } - await cache.setByProcess(process, byProcess, scheduler.ttl) + const byProcess = { url: finalUrl, address: scheduler.address } + await setByProcess(process, byProcess, scheduler.ttl) return byProcess }) }) diff --git a/scheduler-utils/src/locate.test.js b/scheduler-utils/src/locate.test.js index 6557b49ff..6a32bd013 100644 --- a/scheduler-utils/src/locate.test.js +++ b/scheduler-utils/src/locate.test.js @@ -14,7 +14,7 @@ describe('locateWith', () => { const locate = locateWith({ loadProcessScheduler: async (process) => { assert.equal(process, PROCESS) - return { url: DOMAIN, ttl: TEN_MS, owner: SCHEDULER } + return { url: DOMAIN, ttl: TEN_MS, address: SCHEDULER } }, loadScheduler: async () => assert.fail('should not load the scheduler if no hint'), cache: { @@ -28,12 +28,14 @@ describe('locateWith', () => { assert.equal(address, SCHEDULER) assert.equal(ttl, TEN_MS) }, + getByOwner: async () => assert.fail('should not get by owner, if no scheduler hint'), setByOwner: async (owner, url, ttl) => { assert.equal(owner, SCHEDULER) assert.equal(url, DOMAIN) assert.equal(ttl, TEN_MS) } }, + checkForRedirect: async () => assert.fail('should not check for redirect if followRedirects is false'), followRedirects: false }) @@ -55,7 +57,9 @@ describe('locateWith', () => { getByOwner: async () => assert.fail('should not check cache by owner if cached by process'), setByProcess: async () => assert.fail('should not set cache by process if cached by process'), setByOwner: async () => assert.fail('should not set cache by owner if cached by process') - } + }, + checkForRedirect: async () => assert.fail('should not check for redirect if followRedirects is false'), + followRedirects: false }) await locate(PROCESS) @@ -66,7 +70,7 @@ describe('locateWith', () => { const locate = locateWith({ loadProcessScheduler: async (process) => { assert.equal(process, PROCESS) - return { url: DOMAIN, ttl: TEN_MS, owner: SCHEDULER } + return { url: DOMAIN, ttl: TEN_MS, address: SCHEDULER } }, loadScheduler: async () => assert.fail('should not load the scheduler if no hint'), cache: { @@ -80,6 +84,7 @@ describe('locateWith', () => { assert.equal(address, SCHEDULER) assert.equal(ttl, TEN_MS) }, + getByOwner: async () => assert.fail('should not get by owner, if no scheduler hint'), setByOwner: async (owner, url, ttl) => { assert.equal(owner, SCHEDULER) /** @@ -106,7 +111,7 @@ describe('locateWith', () => { loadProcessScheduler: async () => assert.fail('should not load process if given a scheduler hint'), loadScheduler: async (owner) => { assert.equal(owner, SCHEDULER) - return { url: DOMAIN, ttl: TEN_MS, owner: SCHEDULER } + return { url: DOMAIN, ttl: TEN_MS, address: SCHEDULER } }, cache: { getByProcess: async (process) => { @@ -155,7 +160,7 @@ describe('locateWith', () => { }, getByOwner: async (owner) => { assert.equal(owner, SCHEDULER) - return { url: DOMAIN, ttl: TEN_MS, owner: SCHEDULER } + return { url: DOMAIN, ttl: TEN_MS, address: SCHEDULER } }, setByProcess: async (process, { url, address }, ttl) => { assert.equal(process, PROCESS) diff --git a/scheduler-utils/src/raw.js b/scheduler-utils/src/raw.js index 81e5e1ae3..702079863 100644 --- a/scheduler-utils/src/raw.js +++ b/scheduler-utils/src/raw.js @@ -1,6 +1,10 @@ +import { getByOwnerSchema, loadSchedulerSchema, setByOwnerSchema } from './dal.js' import { InvalidSchedulerLocationError } from './err.js' export function rawWith ({ loadScheduler, cache }) { + loadScheduler = loadSchedulerSchema.implement(loadScheduler) + const getByOwner = getByOwnerSchema.implement(cache.getByOwner) + const setByOwner = setByOwnerSchema.implement(cache.setByOwner) /** * Return the `Scheduler-Location` record for the address * or undefined, if it cannot be found @@ -9,12 +13,12 @@ export function rawWith ({ loadScheduler, cache }) { * @returns {Promise<{ url: string } | undefined >} whether the wallet address is Scheduler */ return (address) => - cache.getByOwner(address) + getByOwner(address) .then((cached) => { if (cached) return { url: cached.url } return loadScheduler(address) .then((scheduler) => - cache.setByOwner(address, scheduler.url, scheduler.ttl) + setByOwner(address, scheduler.url, scheduler.ttl) .then(() => ({ url: scheduler.url })) ) .catch((err) => { diff --git a/scheduler-utils/src/raw.test.js b/scheduler-utils/src/raw.test.js index 16f501e24..bea50a640 100644 --- a/scheduler-utils/src/raw.test.js +++ b/scheduler-utils/src/raw.test.js @@ -14,7 +14,7 @@ describe('rawWith', () => { const raw = rawWith({ loadScheduler: async (walletAddress) => { assert.equal(walletAddress, SCHEDULER) - return { url: DOMAIN, ttl: TEN_MS, owner: SCHEDULER } + return { url: DOMAIN, ttl: TEN_MS, address: SCHEDULER } }, cache: { getByOwner: async (scheduler) => { @@ -43,7 +43,8 @@ describe('rawWith', () => { getByOwner: async (scheduler) => { assert.equal(scheduler, SCHEDULER) return undefined - } + }, + setByOwner: async () => assert.fail('should not call if not scheduler is found') } }) @@ -60,8 +61,9 @@ describe('rawWith', () => { cache: { getByOwner: async (walletAddress) => { assert.equal(walletAddress, SCHEDULER) - return { url: DOMAIN, address: SCHEDULER } - } + return { url: DOMAIN, address: SCHEDULER, ttl: 10 } + }, + setByOwner: async () => assert.fail('should not call if not scheduler is in cache') } }) diff --git a/scheduler-utils/src/validate.js b/scheduler-utils/src/validate.js index 575d378f9..7d8ac3baf 100644 --- a/scheduler-utils/src/validate.js +++ b/scheduler-utils/src/validate.js @@ -1,6 +1,10 @@ +import { getByOwnerSchema, loadSchedulerSchema, setByOwnerSchema } from './dal.js' import { InvalidSchedulerLocationError } from './err.js' export function validateWith ({ loadScheduler, cache }) { + loadScheduler = loadSchedulerSchema.implement(loadScheduler) + const getByOwner = getByOwnerSchema.implement(cache.getByOwner) + const setByOwner = setByOwnerSchema.implement(cache.setByOwner) /** * Validate whether the given wallet address is an ao Scheduler * @@ -8,11 +12,11 @@ export function validateWith ({ loadScheduler, cache }) { * @returns {Promise} whether the wallet address is Scheduler */ return (address) => - cache.getByOwner(address) + getByOwner(address) .then((cached) => { if (cached) return true return loadScheduler(address) - .then((scheduler) => cache.setByOwner(address, scheduler.url, scheduler.ttl)) + .then((scheduler) => setByOwner(address, scheduler.url, scheduler.ttl)) .then(() => true) .catch((err) => { if (err instanceof InvalidSchedulerLocationError) return false diff --git a/scheduler-utils/src/validate.test.js b/scheduler-utils/src/validate.test.js index 8fa82452e..0c11f67a6 100644 --- a/scheduler-utils/src/validate.test.js +++ b/scheduler-utils/src/validate.test.js @@ -14,7 +14,7 @@ describe('validateWith', () => { const validate = validateWith({ loadScheduler: async (walletAddress) => { assert.equal(walletAddress, SCHEDULER) - return { url: DOMAIN, ttl: TEN_MS, owner: SCHEDULER } + return { url: DOMAIN, ttl: TEN_MS, address: SCHEDULER } }, cache: { getByOwner: async (scheduler) => { @@ -65,8 +65,9 @@ describe('validateWith', () => { cache: { getByOwner: async (walletAddress) => { assert.equal(walletAddress, SCHEDULER) - return { url: DOMAIN, address: SCHEDULER } - } + return { url: DOMAIN, address: SCHEDULER, ttl: 10 } + }, + setByOwner: async () => assert.fail('should not call if not scheduler is in cache') } })