const makeServiceWorkerEnv = require('service-worker-mock'); describe("plugin: dnslink-ipfs", () => { beforeEach(() => { Object.assign(global, makeServiceWorkerEnv()); jest.resetModules(); init = { name: 'dnslink-ipfs', gunPubkey: 'stub' } global.LibResilientPluginConstructors = new Map() LR = { log: jest.fn((component, ...items)=>{ console.debug(component + ' :: ', ...items) }) } global.Ipfs = { ipfsFixtureAddress: 'QmiPFSiPFSiPFSiPFSiPFSiPFSiPFSiPFSiPFSiPFSiPFS', create: ()=>{ return Promise.resolve({ cat: (path)=>{ return { sourceUsed: false, next: ()=>{ if (path.endsWith('nonexistent.path')) { throw new Error('Error: file does not exist') } var prevSourceUsed = self.sourceUsed self.sourceUsed = true var val = undefined if (!prevSourceUsed) { var val = Uint8Array.from( Array .from(JSON.stringify({ test: "success", path: path })) .map( letter => letter.charCodeAt(0) ) ) } return Promise.resolve({ done: prevSourceUsed, value: val }) } } }, name: { resolve: (path)=>{ var result = path.replace( '/ipns/' + self.location.origin.replace('https://', ''), '/ipfs/' + Ipfs.ipfsFixtureAddress ) return { next: ()=> { return Promise.resolve({ done: false, value: result }) } } } } }) } } self.Ipfs = global.Ipfs }) test("it should register in LibResilientPlugins", () => { require("../../../plugins/dnslink-ipfs/index.js"); expect(LibResilientPluginConstructors.get('dnslink-ipfs')(LR, init).name).toEqual('dnslink-ipfs'); }); test("IPFS setup should be initiated", async ()=>{ self.importScripts = jest.fn() require("../../../plugins/dnslink-ipfs/index.js"); try { await LibResilientPluginConstructors.get('dnslink-ipfs')(LR, init).fetch('/test.json') } catch {} expect(self.importScripts).toHaveBeenNthCalledWith(1, './lib/ipfs.js') }) test("fetching should error out for unpublished content", async ()=>{ require("../../../plugins/dnslink-ipfs/index.js"); expect.assertions(1) try { await LibResilientPluginConstructors.get('dnslink-ipfs')(LR, init).fetch(self.location.origin + '/nonexistent.path') } catch(e) { expect(e).toEqual(new Error('Error: file does not exist')) } }) // TODO: probably not necessary in the long run? test("fetching a path ending in / should instead fetch /index.html", async ()=>{ require("../../../plugins/dnslink-ipfs/index.js"); try { var response = await LibResilientPluginConstructors.get('dnslink-ipfs')(LR, init).fetch(self.location.origin + '/test/') } catch(e) { } var blob = await response.blob() expect(JSON.parse(new TextDecoder().decode(blob.parts[0]))).toEqual({test: "success", path: "/ipfs/" + global.Ipfs.ipfsFixtureAddress + '/test/index.html'}) }) test("content types should be guessed correctly when fetching", async ()=>{ require("../../../plugins/dnslink-ipfs/index.js"); var dnslinkIpfsPlugin = LibResilientPluginConstructors.get('dnslink-ipfs')(LR, init) try { await dnslinkIpfsPlugin.fetch(self.location.origin + '/test/') } catch(e) {} expect(LR.log).toHaveBeenCalledWith('dnslink-ipfs', " +-- guessed contentType : text/html") LR.log.mockClear() try { await dnslinkIpfsPlugin.fetch(self.location.origin + '/test.htm') } catch(e) {} expect(LR.log).toHaveBeenCalledWith('dnslink-ipfs', " +-- guessed contentType : text/html") LR.log.mockClear() try { await dnslinkIpfsPlugin.fetch(self.location.origin + '/test.css') } catch(e) {} expect(LR.log).toHaveBeenCalledWith('dnslink-ipfs', " +-- guessed contentType : text/css") LR.log.mockClear() try { await dnslinkIpfsPlugin.fetch(self.location.origin + '/test.js') } catch(e) {} expect(LR.log).toHaveBeenCalledWith('dnslink-ipfs', " +-- guessed contentType : text/javascript") LR.log.mockClear() try { await dnslinkIpfsPlugin.fetch(self.location.origin + '/test.json') } catch(e) {} expect(LR.log).toHaveBeenCalledWith('dnslink-ipfs', " +-- guessed contentType : application/json") LR.log.mockClear() try { await dnslinkIpfsPlugin.fetch(self.location.origin + '/test.svg') } catch(e) {} expect(LR.log).toHaveBeenCalledWith('dnslink-ipfs', " +-- guessed contentType : image/svg+xml") LR.log.mockClear() try { await dnslinkIpfsPlugin.fetch(self.location.origin + '/test.ico') } catch(e) {} expect(LR.log).toHaveBeenCalledWith('dnslink-ipfs', " +-- guessed contentType : image/x-icon") }) test("fetching should work", async ()=>{ require("../../../plugins/dnslink-ipfs/index.js"); let response = await LibResilientPluginConstructors.get('dnslink-ipfs')(LR, init).fetch(self.location.origin + '/test.json') expect(response.body.type).toEqual('application/json') var blob = await response.blob() expect(JSON.parse(new TextDecoder().decode(blob.parts[0]))).toEqual({test: "success", path: "/ipfs/" + global.Ipfs.ipfsFixtureAddress + '/test.json'}) }) test("publish() should throw an error", async ()=>{ require("../../../plugins/dnslink-ipfs/index.js"); expect.assertions(1) try { LibResilientPluginConstructors.get('dnslink-ipfs')(LR, init).publish() } catch(e) { expect(e).toEqual(new Error("Not implemented yet.")) } }) test("IPFS load error should be handled", async ()=>{ global.Ipfs.create = ()=>{ throw new Error('Testing IPFS loading failure') } require("../../../plugins/dnslink-ipfs/index.js"); expect.assertions(1) try { await LibResilientPluginConstructors.get('dnslink-ipfs')(LR, init).fetch('/test.json') } catch(e) { expect(e).toEqual(new Error("Error: Testing IPFS loading failure")) } }) test("importScripts being undefined should be handled", async ()=>{ self.importScripts = undefined require("../../../plugins/dnslink-ipfs/index.js"); try { await LibResilientPluginConstructors.get('dnslink-ipfs')(LR, init).fetch('/test.json') } catch(e) { } expect(LR.log).toHaveBeenCalledWith("dnslink-ipfs", "Importing IPFS-related libraries...") expect(LR.log).toHaveBeenCalledWith("dnslink-ipfs", "assuming these scripts are already included:") expect(LR.log).toHaveBeenCalledWith("dnslink-ipfs", "+--", "./lib/ipfs.js") }) });