From 6e610636594157ac5d01473eee1e2c2a2c8605cd Mon Sep 17 00:00:00 2001 From: achingbrain Date: Sat, 15 Apr 2023 16:06:20 +0200 Subject: [PATCH] chore: fix linting and add tests --- README.md | 2 +- package.json | 1 + src/index.ts | 14 +++++------ test/index.spec.ts | 63 ++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 67 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 39a1417..9ce2d40 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ import { ipniContentRouting } from '@libp2p/ipni-content-routing' const node = await createLibp2p({ peerRouting: [ - ipniContentRouting(new URL('https://cid.contact')) + ipniContentRouting('https://cid.contact') ] //.. other config }) diff --git a/package.json b/package.json index 865f293..ff8b4cf 100644 --- a/package.json +++ b/package.json @@ -141,6 +141,7 @@ "@libp2p/interfaces": "^3.3.1", "@libp2p/logger": "^2.0.7", "@libp2p/peer-id": "^2.0.3", + "@multiformats/multiaddr": "^12.1.2", "any-signal": "^4.1.1", "browser-readablestream-to-it": "^2.0.2", "iterable-ndjson": "^1.1.0", diff --git a/src/index.ts b/src/index.ts index df635f0..415dc3c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -29,6 +29,7 @@ export interface IpniResponseItem { export interface IpniContentRoutingInit { /** * A concurrency limit to avoid request flood in web browser (default: 4) + * * @see https://github.com/libp2p/js-libp2p-delegated-content-routing/issues/12 */ concurrentRequests?: number @@ -50,21 +51,21 @@ const defaultValues = { class IpniContentRouting implements ContentRouting, Startable { private started: boolean private readonly httpQueue: PQueue - private shutDownController: AbortController - private clientUrl: URL - private timeout: number + private readonly shutDownController: AbortController + private readonly clientUrl: URL + private readonly timeout: number /** * Create a new DelegatedContentRouting instance */ - constructor (url: URL, init: IpniContentRoutingInit = {}) { + constructor (url: string | URL, init: IpniContentRoutingInit = {}) { log('enabled IPNI routing via', url) this.started = false this.shutDownController = new AbortController() this.httpQueue = new PQueue({ concurrency: init.concurrentRequests ?? defaultValues.concurrentRequests }) - this.clientUrl = url + this.clientUrl = url instanceof URL ? url : new URL(url) this.timeout = init.timeout ?? defaultValues.timeout } @@ -114,7 +115,6 @@ class IpniContentRouting implements ContentRouting, Startable { } } catch (err) { log.error('findProviders errored:', err) - throw err } finally { signal.clear() onFinish.resolve() @@ -153,6 +153,6 @@ class IpniContentRouting implements ContentRouting, Startable { } } -export function ipniContentRouting (url: URL, init: IpniContentRoutingInit = {}): () => ContentRouting { +export function ipniContentRouting (url: string | URL, init: IpniContentRoutingInit = {}): () => ContentRouting { return () => new IpniContentRouting(url, init) } diff --git a/test/index.spec.ts b/test/index.spec.ts index 284f408..df88494 100644 --- a/test/index.spec.ts +++ b/test/index.spec.ts @@ -6,12 +6,14 @@ import { ipniContentRouting } from '../src/index.js' import { CID } from 'multiformats/cid' import all from 'it-all' +if (process.env.ECHO_SERVER == null) { + throw new Error('Echo server not configured correctly') +} + +const serverUrl = process.env.ECHO_SERVER + describe('IPNIContentRouting', function () { it('should find providers', async () => { - if (process.env.ECHO_SERVER == null) { - throw new Error('Echo server not configured correctly') - } - const providers = [{ Metadata: 'gBI=', ContextID: '', @@ -36,7 +38,7 @@ describe('IPNIContentRouting', function () { body: providers.map(prov => JSON.stringify(prov)).join('\n') }) - const routing = ipniContentRouting(new URL(process.env.ECHO_SERVER))() + const routing = ipniContentRouting(serverUrl)() const provs = await all(routing.findProviders(cid)) expect(provs.map(prov => ({ @@ -47,4 +49,55 @@ describe('IPNIContentRouting', function () { addrs: prov.Provider.Addrs }))) }) + + it('should handle non-json input', async () => { + const cid = CID.parse('QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn') + + // load providers for the router to fetch + await fetch(`${process.env.ECHO_SERVER}/add-providers/${cid.toString()}`, { + method: 'POST', + body: 'not json' + }) + + const routing = ipniContentRouting(serverUrl)() + + const provs = await all(routing.findProviders(cid)) + expect(provs).to.be.empty() + }) + + it('should handle bad input providers', async () => { + const providers = [{ + Metadata: 'gBI=', + Provider: { + Bad: 'field' + } + }, { + Metadata: 'gBI=', + ContextID: '', + Another: { + Bad: 'field' + } + }] + + const cid = CID.parse('QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn') + + // load providers for the router to fetch + await fetch(`${process.env.ECHO_SERVER}/add-providers/${cid.toString()}`, { + method: 'POST', + body: providers.map(prov => JSON.stringify(prov)).join('\n') + }) + + const routing = ipniContentRouting(serverUrl)() + + const provs = await all(routing.findProviders(cid)) + expect(provs).to.be.empty() + }) + + it('should handle empty input', async () => { + const cid = CID.parse('QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn') + const routing = ipniContentRouting(serverUrl)() + + const provs = await all(routing.findProviders(cid)) + expect(provs).to.be.empty() + }) })