diff --git a/package.json b/package.json index 18da62f4f..043222207 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "test:e2e": "mocha --timeout 300000 \"test/e2e/**/*.test.js\"", "test:functional": "c8 mocha --timeout 5000 --file \"test/setup/mocha-setup.js\" \"test/functional/**/*.test.js\" \"test/functional/**/*.test.ts\"", "lint": "run-s lint:*", - "test:functional_MV3": "mocha --timeout 5000 --file \"test/setup/mocha-setup.mv3.js\" \"test/functional/**/*.test.mv3.js\"", + "test:functional_MV3": "cross-env TEST_MV3=true c8 mocha --timeout 5000 --file \"test/setup/mocha-setup.js\" \"test/functional/**/*.test.js\" \"test/functional/**/*.test.ts\"", "lint:standard": "ts-standard -v \"*.js\" \"add-on/src/**/*.js\" \"add-on/src/**/*.ts\" \"test/**/*.js\" \"scripts/**/*.js\"", "lint:web-ext": "shx cat add-on/manifest.common.json add-on/manifest.chromium.json add-on/manifest.firefox-beta.json | json --deep-merge > add-on/manifest.json && web-ext lint --firefox-preview", "fix:lint": "run-s fix:lint:*", diff --git a/test/functional/lib/ipfs-companion.test.js b/test/functional/lib/ipfs-companion.test.js index e23c95161..935336a56 100644 --- a/test/functional/lib/ipfs-companion.test.js +++ b/test/functional/lib/ipfs-companion.test.js @@ -1,7 +1,6 @@ -import { describe, it, before, after } from 'mocha' import { expect } from 'chai' +import { after, before, describe, it } from 'mocha' import browser from 'sinon-chrome' -import AbortController from 'abort-controller' import { URL } from 'url' import { optionDefaults } from '../../../add-on/src/lib/options.js' @@ -10,17 +9,6 @@ import { optionDefaults } from '../../../add-on/src/lib/options.js' const init = async () => (await import('../../../add-on/src/lib/ipfs-companion.js')).default() describe('lib/ipfs-companion.js', function () { - before(function () { - browser.runtime.id = 'testid' - global.browser = browser - global.AbortController = AbortController - global.chrome = browser - global.navigator = { - clipboard: { - writeText: () => {} - } - } - }) describe('init', function () { before(function () { global.localStorage = global.localStorage || {} @@ -47,12 +35,6 @@ describe('lib/ipfs-companion.js', function () { }) describe.skip('onStorageChange()', function () { - before(function () { - global.window = {} - global.browser = browser - global.URL = URL - }) - it('should update ipfs API instance on IPFS API URL change', async function () { browser.storage.local.get.resolves(optionDefaults) browser.storage.local.set.resolves() diff --git a/test/functional/lib/ipfs-import.test.js b/test/functional/lib/ipfs-import.test.js index 7bdc0ff66..4967ed087 100644 --- a/test/functional/lib/ipfs-import.test.js +++ b/test/functional/lib/ipfs-import.test.js @@ -1,24 +1,9 @@ 'use strict' -import { describe, it, before, after } from 'mocha' import { expect } from 'chai' -import { useFakeTimers } from 'sinon' -import browser from 'sinon-chrome' +import { describe, it } from 'mocha' import { formatImportDirectory } from '../../../add-on/src/lib/ipfs-import.js' describe('ipfs-import.js', function () { - before(function () { - browser.runtime.id = 'testid' - global.document = {} - global.browser = browser - // ipfs-import depends on webextension/polyfill which can't be imported - // in a non-browser environment unless global.browser is stubbed - - // need to force Date to return a particular date - global.clock = useFakeTimers({ - now: new Date(2017, 10, 5, 12, 1, 1) - }) - }) - describe('formatImportDirectory', function () { it('should change nothing if path is properly formatted and date wildcards are not provided', function () { const path = '/ipfs-companion-imports/my-directory/' @@ -54,11 +39,4 @@ describe('ipfs-import.js', function () { // // describe('importFiles', function () { // }) - - after(function () { - global.browser.flush() - global.clock.restore() - delete global.document - delete global.browser - }) }) diff --git a/test/functional/lib/ipfs-request-dnslink.test.js b/test/functional/lib/ipfs-request-dnslink.test.js index 5ba8427f7..f61e8b0c6 100644 --- a/test/functional/lib/ipfs-request-dnslink.test.js +++ b/test/functional/lib/ipfs-request-dnslink.test.js @@ -1,15 +1,15 @@ 'use strict' -import { describe, it, before, beforeEach, after } from 'mocha' -import sinon from 'sinon' import { expect } from 'chai' -import { URL } from 'url' +import { after, before, beforeEach, describe, it } from 'mocha' +import sinon from 'sinon' import browser from 'sinon-chrome' -import { initState } from '../../../add-on/src/lib/state.js' -import createRuntimeChecks from '../../../add-on/src/lib/runtime-checks.js' -import { createRequestModifier } from '../../../add-on/src/lib/ipfs-request.js' import createDnslinkResolver from '../../../add-on/src/lib/dnslink.js' import { createIpfsPathValidator } from '../../../add-on/src/lib/ipfs-path.js' +import { createRequestModifier } from '../../../add-on/src/lib/ipfs-request.js' import { optionDefaults } from '../../../add-on/src/lib/options.js' +import createRuntimeChecks from '../../../add-on/src/lib/runtime-checks.js' +import { initState } from '../../../add-on/src/lib/state.js' +import isMv3TestingEnabled from '../../helpers/is-mv3-testing-enabled.js' const url2request = (string) => { return { url: string, type: 'main_frame' } @@ -23,6 +23,9 @@ describe('modifyRequest processing of DNSLinks', function () { let state, dnslinkResolver, ipfsPathValidator, modifyRequest, runtime before(function () { + if (isMv3TestingEnabled) { + return this.skip() + } global.URL = URL global.browser = browser browser.runtime.id = 'testid' diff --git a/test/functional/lib/ipfs-request-gateway-recover.test.js b/test/functional/lib/ipfs-request-gateway-recover.test.js index 1f2287d98..becbcdd29 100644 --- a/test/functional/lib/ipfs-request-gateway-recover.test.js +++ b/test/functional/lib/ipfs-request-gateway-recover.test.js @@ -1,15 +1,15 @@ 'use strict' -import { describe, it, before, beforeEach, after, afterEach } from 'mocha' -import sinon from 'sinon' import { assert } from 'chai' -import { URL } from 'url' +import { after, afterEach, before, beforeEach, describe, it } from 'mocha' +import sinon from 'sinon' import browser from 'sinon-chrome' -import { initState } from '../../../add-on/src/lib/state.js' -import createRuntimeChecks from '../../../add-on/src/lib/runtime-checks.js' -import { createRequestModifier } from '../../../add-on/src/lib/ipfs-request.js' +import { URL } from 'url' import createDnslinkResolver from '../../../add-on/src/lib/dnslink.js' import { createIpfsPathValidator } from '../../../add-on/src/lib/ipfs-path.js' +import { createRequestModifier } from '../../../add-on/src/lib/ipfs-request.js' import { optionDefaults } from '../../../add-on/src/lib/options.js' +import createRuntimeChecks from '../../../add-on/src/lib/runtime-checks.js' +import { initState } from '../../../add-on/src/lib/state.js' browser.runtime.id = 'testid' diff --git a/test/functional/lib/ipfs-request-gateway-redirect.test.js b/test/functional/lib/ipfs-request-gateway-redirect.test.js index 592a13d79..cf4838e50 100644 --- a/test/functional/lib/ipfs-request-gateway-redirect.test.js +++ b/test/functional/lib/ipfs-request-gateway-redirect.test.js @@ -1,15 +1,17 @@ 'use strict' -import { describe, it, before, beforeEach, after } from 'mocha' -import sinon from 'sinon' import { expect } from 'chai' -import { URL } from 'url' +import { afterEach, before, beforeEach, describe, it } from 'mocha' +import sinon from 'sinon' import browser from 'sinon-chrome' -import { initState } from '../../../add-on/src/lib/state.js' -import createRuntimeChecks from '../../../add-on/src/lib/runtime-checks.js' -import { createRequestModifier, redirectOptOutHint } from '../../../add-on/src/lib/ipfs-request.js' +import { URL } from 'url' import createDnslinkResolver from '../../../add-on/src/lib/dnslink.js' import { createIpfsPathValidator } from '../../../add-on/src/lib/ipfs-path.js' +import { createRequestModifier, redirectOptOutHint } from '../../../add-on/src/lib/ipfs-request.js' import { optionDefaults } from '../../../add-on/src/lib/options.js' +import { cleanupRules, generateAddRule } from '../../../add-on/src/lib/redirect-handler/blockOrObserve.js' +import createRuntimeChecks from '../../../add-on/src/lib/runtime-checks.js' +import { initState } from '../../../add-on/src/lib/state.js' +import isMv3TestingEnabled, { manifestVersion } from '../../helpers/is-mv3-testing-enabled.js' const url2request = (string) => { return { url: string, type: 'main_frame' } @@ -19,16 +21,24 @@ const fakeRequestId = () => { return Math.floor(Math.random() * 100000).toString() } -const expectNoRedirect = async (modifyRequest, request) => { - expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) - expect(await modifyRequest.onHeadersReceived(request)).to.equal(undefined) +const expectNoRedirect = async (modifyRequest, request, browser) => { + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) + await modifyRequest.onHeadersReceived(request) + sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) + } else { + expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + expect(await modifyRequest.onHeadersReceived(request)).to.equal(undefined) + } } const nodeTypes = ['external'] +const regexRuleEnding = '((?:[^\\.]|$).*)$' +const sinonSandbox = sinon.createSandbox() -describe('modifyRequest.onBeforeRequest:', function () { +describe(`[${manifestVersion}] modifyRequest.onBeforeRequest:`, function () { let state, dnslinkResolver, ipfsPathValidator, modifyRequest, runtime - before(function () { global.URL = URL global.browser = browser @@ -51,13 +61,20 @@ describe('modifyRequest.onBeforeRequest:', function () { pubSubdomainGwURL: new URL('https://dweb.link') }) const getState = () => state - const getIpfs = () => {} + const getIpfs = () => { } dnslinkResolver = createDnslinkResolver(getState) runtime = Object.assign({}, await createRuntimeChecks(browser)) // make it mutable for tests ipfsPathValidator = createIpfsPathValidator(getState, getIpfs, dnslinkResolver) modifyRequest = createRequestModifier(getState, dnslinkResolver, ipfsPathValidator, runtime) }) + afterEach(async function () { + sinonSandbox.reset() + if (isMv3TestingEnabled) { + await cleanupRules(true) + } + }) + describe('request for a path matching /ipfs/{CIDv0}', function () { describe('with external node', function () { beforeEach(function () { @@ -65,7 +82,22 @@ describe('modifyRequest.onBeforeRequest:', function () { }) it('should be served from custom gateway if redirect is enabled', async function () { const request = url2request('https://google.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('http://localhost:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + + if (isMv3TestingEnabled) { + const request = url2request('https://google.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + await modifyRequest.onBeforeRequest(request) + const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args + expect(args).to.deep.equal({ + addRules: [generateAddRule( + args.addRules[0].id, + `${'^https?\\:\\/\\/google\\.com'}${regexRuleEnding}`, + 'http://localhost:8080\\1' + )], + removeRuleIds: [] + }) + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('http://localhost:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + } }) }) describe('with every node type', function () { @@ -77,19 +109,32 @@ describe('modifyRequest.onBeforeRequest:', function () { it(`should be left untouched if redirect is disabled (${nodeType} node)`, async function () { state.redirect = false const request = url2request('https://google.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') - await expectNoRedirect(modifyRequest, request) + if (isMv3TestingEnabled) { + await expectNoRedirect(modifyRequest, request, browser) + } else { + await expectNoRedirect(modifyRequest, request) + } }) it(`should be left untouched if redirect is enabled but global active flag is OFF (${nodeType} node)`, async function () { state.active = false state.redirect = true const request = url2request('https://google.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') - await expectNoRedirect(modifyRequest, request) + if (isMv3TestingEnabled) { + await expectNoRedirect(modifyRequest, request, browser) + } else { + await expectNoRedirect(modifyRequest, request) + } }) it(`should be left untouched if URL includes opt-out hint (${nodeType} node)`, async function () { // A safe way for preloading data at arbitrary gateways - it should arrive at original destination const request = url2request('https://google.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?x-ipfs-companion-no-redirect#hashTest') - await expectNoRedirect(modifyRequest, request) - expect(redirectOptOutHint).to.equal('x-ipfs-companion-no-redirect') + + if (isMv3TestingEnabled) { + await expectNoRedirect(modifyRequest, request, browser) + } else { + await expectNoRedirect(modifyRequest, request) + expect(redirectOptOutHint).to.equal('x-ipfs-companion-no-redirect') + } }) it(`should be left untouched if request is for subresource on a page loaded from URL that includes opt-out hint (${nodeType} node)`, async function () { // ensure opt-out works for subresources (Firefox only for now) @@ -98,16 +143,31 @@ describe('modifyRequest.onBeforeRequest:', function () { url: 'https://google.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest', originUrl: 'https://example.com/?x-ipfs-companion-no-redirect#hashTest' } - await expectNoRedirect(modifyRequest, subRequest) + + if (isMv3TestingEnabled) { + await expectNoRedirect(modifyRequest, subRequest, browser) + } else { + await expectNoRedirect(modifyRequest, subRequest) + } }) it(`should be left untouched if CID is invalid (${nodeType} node)`, async function () { const request = url2request('https://google.com/ipfs/notacid?argTest#hashTest') - await expectNoRedirect(modifyRequest, request) + + if (isMv3TestingEnabled) { + await expectNoRedirect(modifyRequest, request, browser) + } else { + await expectNoRedirect(modifyRequest, request) + } }) it(`should be left untouched if its is a HEAD preload with explicit opt-out in URL hash (${nodeType} node)`, async function () { // HTTP HEAD is a popular way for preloading data at arbitrary gateways, so we have a dedicated test to make sure it works as expected const headRequest = { url: 'https://google.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#x-ipfs-companion-no-redirect', method: 'HEAD' } - await expectNoRedirect(modifyRequest, headRequest) + + if (isMv3TestingEnabled) { + await expectNoRedirect(modifyRequest, headRequest, browser) + } else { + await expectNoRedirect(modifyRequest, headRequest) + } }) }) }) @@ -121,22 +181,51 @@ describe('modifyRequest.onBeforeRequest:', function () { it('should be served from custom gateway if fetched from the same origin and redirect is enabled in Firefox', async function () { runtime.isFirefox = true const xhrRequest = { url: 'https://google.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest', type: 'xmlhttprequest', originUrl: 'https://google.com/' } - expect((await modifyRequest.onBeforeRequest(xhrRequest)).redirectUrl).to.equal('http://127.0.0.1:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + + if (isMv3TestingEnabled) { + // return this.skip() + } else { + expect((await modifyRequest.onBeforeRequest(xhrRequest)).redirectUrl).to.equal('http://127.0.0.1:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + } }) it('should be served from custom gateway if fetched from the same origin and redirect is enabled in Chromium', async function () { runtime.isFirefox = false const xhrRequest = { url: 'https://google.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest', type: 'xmlhttprequest', initiator: 'https://google.com/' } - expect((await modifyRequest.onBeforeRequest(xhrRequest)).redirectUrl).to.equal('http://127.0.0.1:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(xhrRequest) + const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args + expect(args).to.deep.equal({ + addRules: [generateAddRule( + args.addRules[0].id, + `${'^https?\\:\\/\\/google\\.com'}${regexRuleEnding}`, + 'http://127.0.0.1:8080\\1' + )], + removeRuleIds: [] + }) + } else { + expect((await modifyRequest.onBeforeRequest(xhrRequest)).redirectUrl).to.equal('http://127.0.0.1:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + } }) it('should be served from custom gateway if XHR is cross-origin and redirect is enabled in Chromium', async function () { runtime.isFirefox = false const xhrRequest = { url: 'https://google.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest', type: 'xmlhttprequest', initiator: 'https://www.nasa.gov/foo.html', requestId: fakeRequestId() } - expect((await modifyRequest.onBeforeRequest(xhrRequest)).redirectUrl).to.equal('http://127.0.0.1:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + + if (isMv3TestingEnabled) { + // return this.skip() + } else { + expect((await modifyRequest.onBeforeRequest(xhrRequest)).redirectUrl).to.equal('http://127.0.0.1:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + } }) it('should be served from custom gateway if XHR is cross-origin and redirect is enabled in Firefox', async function () { runtime.isFirefox = true const xhrRequest = { url: 'https://google.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest', type: 'xmlhttprequest', originUrl: 'https://www.nasa.gov/foo.html', requestId: fakeRequestId() } - expect((await modifyRequest.onBeforeRequest(xhrRequest)).redirectUrl).to.equal('http://127.0.0.1:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + + if (isMv3TestingEnabled) { + // return this.skip() + } else { + expect((await modifyRequest.onBeforeRequest(xhrRequest)).redirectUrl).to.equal('http://127.0.0.1:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + } }) }) describe('with external node when runtime.requiresXHRCORSfix', function () { @@ -147,26 +236,45 @@ describe('modifyRequest.onBeforeRequest:', function () { it('should be served from custom gateway if fetched from the same origin and redirect is enabled in Firefox', async function () { runtime.isFirefox = true const xhrRequest = { url: 'https://google.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest', type: 'xmlhttprequest', originUrl: 'https://google.com/' } - expect((await modifyRequest.onBeforeRequest(xhrRequest)).redirectUrl).to.equal('http://127.0.0.1:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + if (isMv3TestingEnabled) { + // return this.skip() + } else { + expect((await modifyRequest.onBeforeRequest(xhrRequest)).redirectUrl).to.equal('http://127.0.0.1:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + } }) it('should be served from custom gateway if fetched from the same origin and redirect is enabled in non-Firefox', async function () { runtime.isFirefox = false const xhrRequest = { url: 'https://google.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest', type: 'xmlhttprequest', initiator: 'https://google.com/' } - expect((await modifyRequest.onBeforeRequest(xhrRequest)).redirectUrl).to.equal('http://127.0.0.1:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + + if (isMv3TestingEnabled) { + // return this.skip() + } else { + expect((await modifyRequest.onBeforeRequest(xhrRequest)).redirectUrl).to.equal('http://127.0.0.1:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + } }) it('should be served from custom gateway if XHR is cross-origin and redirect is enabled in non-Firefox', async function () { runtime.isFirefox = false const xhrRequest = { url: 'https://google.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest', type: 'xmlhttprequest', initiator: 'https://www.nasa.gov/foo.html', requestId: fakeRequestId() } - expect((await modifyRequest.onBeforeRequest(xhrRequest)).redirectUrl).to.equal('http://127.0.0.1:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + + if (isMv3TestingEnabled) { + // return this.skip() + } else { + expect((await modifyRequest.onBeforeRequest(xhrRequest)).redirectUrl).to.equal('http://127.0.0.1:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + } }) it('should be served from custom gateway via late redirect in onHeadersReceived if XHR is cross-origin and redirect is enabled in Firefox', async function () { // Context for CORS XHR problems in Firefox: https://github.com/ipfs-shipyard/ipfs-companion/issues/436 runtime.isFirefox = true const xhrRequest = { url: 'https://google.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest', type: 'xmlhttprequest', originUrl: 'https://www.nasa.gov/foo.html', requestId: fakeRequestId() } + + if (isMv3TestingEnabled) { + // return this.skip() + } else { // onBeforeRequest should not change anything, as it will trigger false-positive CORS error - expect(await modifyRequest.onBeforeRequest(xhrRequest)).to.equal(undefined) - // onHeadersReceived is after CORS validation happens, so its ok to cancel and redirect late - expect((await modifyRequest.onHeadersReceived(xhrRequest)).redirectUrl).to.equal('http://127.0.0.1:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + expect(await modifyRequest.onBeforeRequest(xhrRequest)).to.equal(undefined) + // onHeadersReceived is after CORS validation happens, so its ok to cancel and redirect late + expect((await modifyRequest.onHeadersReceived(xhrRequest)).redirectUrl).to.equal('http://127.0.0.1:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + } }) }) }) @@ -183,12 +291,31 @@ describe('modifyRequest.onBeforeRequest:', function () { dnslinkResolver.readDnslinkFromTxtRecord = sinon.stub().withArgs(fqdn).resolves('/ipfs/Qmazvovg6Sic3m9igZMKoAPjkiVZsvbWWc8ZvgjjK1qMss') // pretend API is online and we can do dns lookups with it state.peerCount = 1 - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('http://localhost:8080/ipns/en.wikipedia-on-ipfs.org/index.html?argTest#hashTest') + + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args + expect(args).to.deep.equal({ + addRules: [generateAddRule( + args.addRules[0].id, + `${'^https?\\:\\/\\/google\\.com'}${regexRuleEnding}`, + 'http://localhost:8080\\1' + )], + removeRuleIds: [] + }) + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('http://localhost:8080/ipns/en.wikipedia-on-ipfs.org/index.html?argTest#hashTest') + } }) it('should be served from custom gateway if {path} starts with a valid PeerID', async function () { const request = url2request('https://google.com/ipns/QmSWnBwMKZ28tcgMFdihD8XS7p6QzdRSGf71cCybaETSsU/index.html?argTest#hashTest') dnslinkResolver.readDnslinkFromTxtRecord = sinon.stub().resolves(false) - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('http://localhost:8080/ipns/QmSWnBwMKZ28tcgMFdihD8XS7p6QzdRSGf71cCybaETSsU/index.html?argTest#hashTest') + + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('http://localhost:8080/ipns/QmSWnBwMKZ28tcgMFdihD8XS7p6QzdRSGf71cCybaETSsU/index.html?argTest#hashTest') + } }) }) @@ -201,12 +328,22 @@ describe('modifyRequest.onBeforeRequest:', function () { it(`should be left untouched if redirect is disabled' (${nodeType} node)`, async function () { state.redirect = false const request = url2request('https://google.com/ipns/ipfs.io?argTest#hashTest') - await expectNoRedirect(modifyRequest, request) + + if (isMv3TestingEnabled) { + await expectNoRedirect(modifyRequest, request, browser) + } else { + await expectNoRedirect(modifyRequest, request) + } }) it(`should be left untouched if FQDN is not a real domain nor a valid CID (${nodeType} node)`, async function () { const request = url2request('https://google.com/ipns/notafqdnorcid?argTest#hashTest') dnslinkResolver.readDnslinkFromTxtRecord = sinon.stub().resolves(false) - await expectNoRedirect(modifyRequest, request) + + if (isMv3TestingEnabled) { + await expectNoRedirect(modifyRequest, request, browser) + } else { + await expectNoRedirect(modifyRequest, request) + } }) }) }) @@ -225,40 +362,96 @@ describe('modifyRequest.onBeforeRequest:', function () { state.ipfsNodeType = 'external' // dweb.link is the default subdomain gw }) + it('should be redirected to localhost gateway (*.ipfs on default gw)', async function () { state.redirect = true const request = url2request(`https://${cid}.ipfs.dweb.link/`) - // X-Ipfs-Path to ensure value from URL takes a priority - request.responseHeaders = [{ name: 'X-Ipfs-Path', value: fakeXIpfsPathHdrVal }] - - /// We expect redirect to path-based gateway because go-ipfs >=0.5 will + // We expect redirect to path-based gateway because go-ipfs >=0.5 will // return redirect to a subdomain, and we don't want to break users // running older versions of go-ipfs by loading subdomain first and // failing. - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl) - .to.equal(`http://localhost:8080/ipfs/${cid}/`) + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args + expect(args).to.deep.equal({ + addRules: [generateAddRule( + args.addRules[0].id, + `^https?\\:\\/\\/${cid}\\.ipfs\\.dweb\\.link${regexRuleEnding}`, + `http://localhost:8080/ipfs/${cid}\\1` + )], + removeRuleIds: [] + }) + } else { + // X-Ipfs-Path to ensure value from URL takes a priority + request.responseHeaders = [{ name: 'X-Ipfs-Path', value: fakeXIpfsPathHdrVal }] + + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl) + .to.equal(`http://localhost:8080/ipfs/${cid}/`) + } }) it('should be redirected to localhost gateway (*.ipfs on 3rd party gw)', async function () { state.redirect = true const request = url2request(`https://${cid}.ipfs.cf-ipfs.com/`) - request.responseHeaders = [{ name: 'X-Ipfs-Path', value: fakeXIpfsPathHdrVal }] - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl) - .to.equal(`http://localhost:8080/ipfs/${cid}/`) + + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args + expect(args).to.deep.equal({ + addRules: [generateAddRule( + args.addRules[0].id, + `^https?\\:\\/\\/${cid}\\.ipfs\\.cf\\-ipfs\\.com${regexRuleEnding}`, + `http://localhost:8080/ipfs/${cid}\\1` + )], + removeRuleIds: [] + }) + } else { + request.responseHeaders = [{ name: 'X-Ipfs-Path', value: fakeXIpfsPathHdrVal }] + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl) + .to.equal(`http://localhost:8080/ipfs/${cid}/`) + } }) it('should be redirected to localhost gateway and keep URL encoding of original path', async function () { state.redirect = true const request = url2request('https://bafybeigfejjsuq5im5c3w3t3krsiytszhfdc4v5myltcg4myv2n2w6jumy.ipfs.dweb.link/%3Ffilename=test.jpg?arg=val') - request.responseHeaders = [{ name: 'X-Ipfs-Path', value: fakeXIpfsPathHdrVal }] - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl) - .to.equal('http://localhost:8080/ipfs/bafybeigfejjsuq5im5c3w3t3krsiytszhfdc4v5myltcg4myv2n2w6jumy/%3Ffilename=test.jpg?arg=val') + + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args + expect(args).to.deep.equal({ + addRules: [generateAddRule( + args.addRules[0].id, + `^https?\\:\\/\\/bafybeigfejjsuq5im5c3w3t3krsiytszhfdc4v5myltcg4myv2n2w6jumy\\.ipfs\\.dweb\\.link${regexRuleEnding}`, + 'http://localhost:8080/ipfs/bafybeigfejjsuq5im5c3w3t3krsiytszhfdc4v5myltcg4myv2n2w6jumy\\1' + )], + removeRuleIds: [] + }) + } else { + request.responseHeaders = [{ name: 'X-Ipfs-Path', value: fakeXIpfsPathHdrVal }] + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl) + .to.equal('http://localhost:8080/ipfs/bafybeigfejjsuq5im5c3w3t3krsiytszhfdc4v5myltcg4myv2n2w6jumy/%3Ffilename=test.jpg?arg=val') + } }) it('should be redirected to localhost gateway (*.ipns on default gw)', async function () { state.redirect = true const request = url2request(`https://${peerid}.ipns.dweb.link/`) - request.responseHeaders = [{ name: 'X-Ipfs-Path', value: '/ipns/QmPhnvn747LqwPYMJmQVorMaGbMSgA7mRRoyyZYz3DoZRQ' }] - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl) - .to.equal(`http://localhost:8080/ipns/${peerid}/`) + + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args + expect(args).to.deep.equal({ + addRules: [generateAddRule( + args.addRules[0].id, + `^https?\\:\\/\\/${peerid}\\.ipns\\.dweb\\.link${regexRuleEnding}`, + `http://localhost:8080/ipns/${peerid}\\1` + )], + removeRuleIds: [] + }) + } else { + request.responseHeaders = [{ name: 'X-Ipfs-Path', value: '/ipns/QmPhnvn747LqwPYMJmQVorMaGbMSgA7mRRoyyZYz3DoZRQ' }] + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl) + .to.equal(`http://localhost:8080/ipns/${peerid}/`) + } }) }) }) @@ -275,43 +468,75 @@ describe('modifyRequest.onBeforeRequest:', function () { // or could produce false-positives such as redirection from localhost:5001/ipfs/path to localhost:8080/ipfs/path it('should fix localhost Kubo RPC hostname to IP', async function () { const request = url2request('http://localhost:5001/ipfs/QmPhnvn747LqwPYMJmQVorMaGbMSgA7mRRoyyZYz3DoZRQ/') - // expectNoRedirect(modifyRequest, request) - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl) - .to.equal('http://127.0.0.1:5001/ipfs/QmPhnvn747LqwPYMJmQVorMaGbMSgA7mRRoyyZYz3DoZRQ/') + + if (isMv3TestingEnabled) { + // return this.skip() + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl) + .to.equal('http://127.0.0.1:5001/ipfs/QmPhnvn747LqwPYMJmQVorMaGbMSgA7mRRoyyZYz3DoZRQ/') + } }) it('should be left untouched if localhost Gateway is used', async function () { const request = url2request('http://localhost:8080/ipfs/QmPhnvn747LqwPYMJmQVorMaGbMSgA7mRRoyyZYz3DoZRQ/') - await expectNoRedirect(modifyRequest, request) + + if (isMv3TestingEnabled) { + // return this.skip() + } else { + await expectNoRedirect(modifyRequest, request) + } }) it('should fix 127.0.0.1 Gateway to localhost', async function () { const request = url2request('http://127.0.0.1:8080/ipfs/QmPhnvn747LqwPYMJmQVorMaGbMSgA7mRRoyyZYz3DoZRQ/') - // expectNoRedirect(modifyRequest, request) - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl) - .to.equal('http://localhost:8080/ipfs/QmPhnvn747LqwPYMJmQVorMaGbMSgA7mRRoyyZYz3DoZRQ/') + + if (isMv3TestingEnabled) { + // return this.skip() + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl) + .to.equal('http://localhost:8080/ipfs/QmPhnvn747LqwPYMJmQVorMaGbMSgA7mRRoyyZYz3DoZRQ/') + } }) it('should fix 0.0.0.0 to localhost IP API', async function () { // https://github.com/ipfs-shipyard/ipfs-companion/issues/867 const request = url2request('http://0.0.0.0:5001/ipfs/QmPhnvn747LqwPYMJmQVorMaGbMSgA7mRRoyyZYz3DoZRQ/') - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl) - .to.equal('http://127.0.0.1:5001/ipfs/QmPhnvn747LqwPYMJmQVorMaGbMSgA7mRRoyyZYz3DoZRQ/') + + if (isMv3TestingEnabled) { + // return this.skip() + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl) + .to.equal('http://127.0.0.1:5001/ipfs/QmPhnvn747LqwPYMJmQVorMaGbMSgA7mRRoyyZYz3DoZRQ/') + } }) it('should be left untouched if /webui on localhost Kubo RPC port', async function () { // https://github.com/ipfs/ipfs-companion/issues/291 const request = url2request('http://localhost:5001/webui') - // expectNoRedirect(modifyRequest, request) - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl) - .to.equal('http://127.0.0.1:5001/webui') + + if (isMv3TestingEnabled) { + // return this.skip() + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl) + .to.equal('http://127.0.0.1:5001/webui') + } }) it('should be left untouched if localhost Kubo RPC IP is used, even when x-ipfs-path is present', async function () { // https://github.com/ipfs-shipyard/ipfs-companion/issues/604 const request = url2request('http://127.0.0.1:5001/ipfs/QmPhnvn747LqwPYMJmQVorMaGbMSgA7mRRoyyZYz3DoZRQ/') request.responseHeaders = [{ name: 'X-Ipfs-Path', value: '/ipfs/QmPhnvn747LqwPYMJmQVorMaGbMSgA7mRRoyyZYz3DDIFF' }] - await expectNoRedirect(modifyRequest, request) + + if (isMv3TestingEnabled) { + // return this.skip() + } else { + await expectNoRedirect(modifyRequest, request) + } }) it('should be left untouched if [::1] is used', async function () { // https://github.com/ipfs/ipfs-companion/issues/291 const request = url2request('http://[::1]:5001/ipfs/QmPhnvn747LqwPYMJmQVorMaGbMSgA7mRRoyyZYz3DoZRQ/') - await expectNoRedirect(modifyRequest, request) + + if (isMv3TestingEnabled) { + // return this.skip() + } else { + await expectNoRedirect(modifyRequest, request) + } }) it('should be redirected to localhost (subdomain in go-ipfs >0.5) if type=main_frame and 127.0.0.1 (path gw) is used un URL', async function () { state.redirect = true @@ -320,8 +545,13 @@ describe('modifyRequest.onBeforeRequest:', function () { const cid = 'QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR' const request = url2request(`http://127.0.0.1:8080/ipfs/${cid}?arg=val#hash`) request.type = 'main_frame' // explicit - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl) - .to.equal(`http://localhost:8080/ipfs/${cid}?arg=val#hash`) + + if (isMv3TestingEnabled) { + // return this.skip() + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl) + .to.equal(`http://localhost:8080/ipfs/${cid}?arg=val#hash`) + } }) }) }) @@ -336,19 +566,28 @@ describe('modifyRequest.onBeforeRequest:', function () { state.gwURLString = 'http://foo:80/' state.gwURL = new URL(state.gwURLString) const request = url2request('https://bar.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('http://foo/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + + if (isMv3TestingEnabled) { + // return this.skip() + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('http://foo/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + } }) it('should work for HTTPS GW without explicit port in URL', async function () { state.gwURLString = 'https://foo:443/' state.gwURL = new URL(state.gwURLString) const request = url2request('https://bar.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://foo/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + + if (isMv3TestingEnabled) { + // return this.skip() + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://foo/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + } }) }) describe('Recovers Page if node is unreachable', function () { beforeEach(function () { - global.browser = browser state.ipfsNodeType = 'external' state.redirect = true state.peerCount = -1 // this simulates Kubo RPC being offline @@ -357,37 +596,68 @@ describe('modifyRequest.onBeforeRequest:', function () { state.pubGwURLString = 'https://ipfs.io' state.pubGwURL = new URL('https://ipfs.io') }) + it('should present recovery page if node is offline and redirect is enabled', async function () { expect(state.nodeActive).to.be.equal(false) state.redirect = true const request = url2request('https://localhost:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR/foo/bar') - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('chrome-extension://testid/dist/recovery/recovery.html#https%3A%2F%2Fipfs.io%2Fipfs%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%2Ffoo%2Fbar') + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args + + expect(args.addRules[0]).to.deep.equal(generateAddRule( + args.addRules[0].id, + `^https?\\:\\/\\/localhost\\:8080\\/ipfs\\/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR\\/foo\\/${regexRuleEnding}`, + 'chrome-extension://testid/dist/recovery/recovery.html#https%3A%2F%2Fipfs.io%2Fipfs%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%2Ffoo%2F\\1' + )) + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('chrome-extension://testid/dist/recovery/recovery.html#https%3A%2F%2Fipfs.io%2Fipfs%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%2Ffoo%2Fbar') + } }) + it('should present recovery page if node is offline and redirect is disabled', async function () { expect(state.nodeActive).to.be.equal(false) state.redirect = false const request = url2request('https://localhost:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR/foo/bar') - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('chrome-extension://testid/dist/recovery/recovery.html#https%3A%2F%2Fipfs.io%2Fipfs%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%2Ffoo%2Fbar') + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args + console.log('args: ', args) + + expect(args.addRules[0]).to.deep.equal(generateAddRule( + args.addRules[0].id, + `^https?\\:\\/\\/localhost\\:8080\\/ipfs\\/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR\\/foo\\/${regexRuleEnding}`, + 'chrome-extension://testid/dist/recovery/recovery.html#https%3A%2F%2Fipfs.io%2Fipfs%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%2Ffoo%2F\\1' + )) + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('chrome-extension://testid/dist/recovery/recovery.html#https%3A%2F%2Fipfs.io%2Fipfs%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%2Ffoo%2Fbar') + } }) + it('should not show recovery page if node is offline, redirect is enabled, but non-gateway URL failed to load from the same port', async function () { // this covers https://github.com/ipfs/ipfs-companion/issues/1162 and https://twitter.com/unicomp21/status/1626244123102679041 state.redirect = true expect(state.nodeActive).to.be.equal(false) const request = url2request('https://localhost:8080/') - expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + await expectNoRedirect(modifyRequest, request, browser) + } else { + expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + } }) + it('should not show recovery page if extension is disabled', async function () { // allows user to quickly avoid anything similar to https://github.com/ipfs/ipfs-companion/issues/1162 state.active = false expect(state.nodeActive).to.be.equal(false) const request = url2request('https://localhost:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR/foo/bar') - expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + await expectNoRedirect(modifyRequest, request, browser) + } else { + expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + } }) }) - - after(function () { - delete global.URL - delete global.browser - browser.flush() - }) }) diff --git a/test/functional/lib/ipfs-request-gateway-redirect.test.mv3.js b/test/functional/lib/ipfs-request-gateway-redirect.test.mv3.js deleted file mode 100644 index 007d98557..000000000 --- a/test/functional/lib/ipfs-request-gateway-redirect.test.mv3.js +++ /dev/null @@ -1,364 +0,0 @@ -'use strict' -import { expect } from 'chai' -import { after, afterEach, before, beforeEach, describe, it } from 'mocha' -import sinon from 'sinon' -import browser from 'sinon-chrome' -import { URL } from 'url' -import createDnslinkResolver from '../../../add-on/src/lib/dnslink.js' -import { createIpfsPathValidator } from '../../../add-on/src/lib/ipfs-path.js' -import { createRequestModifier } from '../../../add-on/src/lib/ipfs-request.js' -import { optionDefaults } from '../../../add-on/src/lib/options.js' -import { cleanupRules, generateAddRule } from '../../../add-on/src/lib/redirect-handler/blockOrObserve.js' -import createRuntimeChecks from '../../../add-on/src/lib/runtime-checks.js' -import { initState } from '../../../add-on/src/lib/state.js' - -const url2request = (string) => { - return { url: string, type: 'main_frame' } -} - -const expectNoRedirect = async (modifyRequest, request, browser) => { - await modifyRequest.onBeforeRequest(request) - sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) - await modifyRequest.onHeadersReceived(request) - sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) -} - -const regexRuleEnding = '((?:[^\\.]|$).*)$' -const nodeTypes = ['external'] -const sinonSandbox = sinon.createSandbox() - -describe('[MV3] modifyRequest.onBeforeRequest:', function () { - let state, dnslinkResolver, ipfsPathValidator, modifyRequest, runtime - - before(async function () { - global.URL = URL - browser.runtime.getURL.returns('chrome-extension://testid/') - }) - - afterEach(async function () { - await cleanupRules(true) - }) - - beforeEach(async function () { - state = Object.assign(initState(optionDefaults), { - ipfsNodeType: 'external', - peerCount: 1, - redirect: true, - dnslinkPolicy: false, // dnslink test suite is in ipfs-request-dnslink.test.js - catchUnhandledProtocols: true, - gwURLString: 'http://localhost:8080', - gwURL: new URL('http://localhost:8080'), - pubGwURLString: 'https://ipfs.io', - pubGwURL: new URL('https://ipfs.io'), - pubSubdomainGwURLString: 'https://dweb.link', - pubSubdomainGwURL: new URL('https://dweb.link') - }) - const getState = () => state - const getIpfs = () => { } - dnslinkResolver = createDnslinkResolver(getState) - runtime = Object.assign({}, await createRuntimeChecks(browser)) // make it mutable for tests - ipfsPathValidator = createIpfsPathValidator(getState, getIpfs, dnslinkResolver) - modifyRequest = createRequestModifier(getState, dnslinkResolver, ipfsPathValidator, runtime) - }) - - afterEach(async function () { - sinonSandbox.reset() - }) - - describe('request for a path matching /ipfs/{CIDv0}', function () { - describe('with external node', function () { - beforeEach(function () { - state.ipfsNodeType = 'external' - }) - it('should be served from custom gateway if redirect is enabled', async function () { - const request = url2request('https://google.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') - // MV2 - // expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('http://localhost:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') - await modifyRequest.onBeforeRequest(request) - const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args - expect(args).to.deep.equal({ - addRules: [generateAddRule( - args.addRules[0].id, - `${'^https?\\:\\/\\/google\\.com'}${regexRuleEnding}`, - 'http://localhost:8080\\1' - )], - removeRuleIds: [] - }) - }) - }) - describe('with every node type', function () { - // tests in which results should be the same for all node types - nodeTypes.forEach(function (nodeType) { - beforeEach(function () { - state.ipfsNodeType = nodeType - }) - it(`should be left untouched if redirect is disabled (${nodeType} node)`, async function () { - state.redirect = false - const request = url2request('https://google.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') - await expectNoRedirect(modifyRequest, request, browser) - }) - it(`should be left untouched if redirect is enabled but global active flag is OFF (${nodeType} node)`, async function () { - state.active = false - state.redirect = true - const request = url2request('https://google.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') - await expectNoRedirect(modifyRequest, request, browser) - }) - it(`should be left untouched if URL includes opt-out hint (${nodeType} node)`, async function () { - // A safe way for preloading data at arbitrary gateways - it should arrive at original destination - const request = url2request('https://google.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?x-ipfs-companion-no-redirect#hashTest') - await expectNoRedirect(modifyRequest, request, browser) - }) - it(`should be left untouched if request is for subresource on a page loaded from URL that includes opt-out hint (${nodeType} node)`, async function () { - // ensure opt-out works for subresources (Firefox only for now) - const subRequest = { - type: 'script', - url: 'https://google.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest', - originUrl: 'https://example.com/?x-ipfs-companion-no-redirect#hashTest' - } - await expectNoRedirect(modifyRequest, subRequest, browser) - }) - it(`should be left untouched if CID is invalid (${nodeType} node)`, async function () { - const request = url2request('https://google.com/ipfs/notacid?argTest#hashTest') - await expectNoRedirect(modifyRequest, request, browser) - }) - it(`should be left untouched if its is a HEAD preload with explicit opt-out in URL hash (${nodeType} node)`, async function () { - // HTTP HEAD is a popular way for preloading data at arbitrary gateways, so we have a dedicated test to make sure it works as expected - const headRequest = { url: 'https://google.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#x-ipfs-companion-no-redirect', method: 'HEAD' } - await expectNoRedirect(modifyRequest, headRequest, browser) - }) - }) - }) - }) - - describe('XHR request for a path matching /ipfs/{CIDv0} coming from 3rd party Origin', function () { - describe('with external node', function () { - beforeEach(function () { - state.ipfsNodeType = 'external' - }) - it('should be served from custom gateway if fetched from the same origin and redirect is enabled in Chromium', async function () { - const xhrRequest = { url: 'https://google.com/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest', type: 'xmlhttprequest', initiator: 'https://google.com/' } - // MV2 - // expect((await modifyRequest.onBeforeRequest(xhrRequest)).redirectUrl).to.equal('http://127.0.0.1:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') - await modifyRequest.onBeforeRequest(xhrRequest) - const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args - expect(args).to.deep.equal({ - addRules: [generateAddRule( - args.addRules[0].id, - `${'^https?\\:\\/\\/google\\.com'}${regexRuleEnding}`, - 'http://127.0.0.1:8080\\1' - )], - removeRuleIds: [] - }) - }) - }) - }) - - describe('request for a path matching /ipns/{path}', function () { - describe('with external node', function () { - beforeEach(function () { - state.ipfsNodeType = 'external' - }) - - it('should be served from custom gateway if {path} points to a FQDN with existing dnslink', async function () { - const request = url2request('https://google.com/ipns/en.wikipedia-on-ipfs.org/index.html?argTest#hashTest') - // stub the existence of valid dnslink - const fqdn = 'en.wikipedia-on-ipfs.org' - dnslinkResolver.readDnslinkFromTxtRecord = sinon.stub().withArgs(fqdn).resolves('/ipfs/Qmazvovg6Sic3m9igZMKoAPjkiVZsvbWWc8ZvgjjK1qMss') - // pretend API is online and we can do dns lookups with it - state.peerCount = 1 - // MV2 - // expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('http://localhost:8080/ipns/en.wikipedia-on-ipfs.org/index.html?argTest#hashTest') - await modifyRequest.onBeforeRequest(request) - const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args - expect(args).to.deep.equal({ - addRules: [generateAddRule( - args.addRules[0].id, - `${'^https?\\:\\/\\/google\\.com'}${regexRuleEnding}`, - 'http://localhost:8080\\1' - )], - removeRuleIds: [] - }) - }) - it('should be served from custom gateway if {path} starts with a valid PeerID', async function () { - const request = url2request('https://google.com/ipns/QmSWnBwMKZ28tcgMFdihD8XS7p6QzdRSGf71cCybaETSsU/index.html?argTest#hashTest') - dnslinkResolver.readDnslinkFromTxtRecord = sinon.stub().resolves(false) - // MV2 - // expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('http://localhost:8080/ipns/QmSWnBwMKZ28tcgMFdihD8XS7p6QzdRSGf71cCybaETSsU/index.html?argTest#hashTest') - await modifyRequest.onBeforeRequest(request) - console.log(browser.declarativeNetRequest.updateDynamicRules.calls) - }) - }) - - describe('with every node type', function () { - // tests in which results should be the same for all node types - nodeTypes.forEach(function (nodeType) { - beforeEach(function () { - state.ipfsNodeType = nodeType - }) - it(`should be left untouched if redirect is disabled' (${nodeType} node)`, async function () { - state.redirect = false - const request = url2request('https://google.com/ipns/ipfs.io?argTest#hashTest') - await expectNoRedirect(modifyRequest, request, browser) - }) - it(`should be left untouched if FQDN is not a real domain nor a valid CID (${nodeType} node)`, async function () { - const request = url2request('https://google.com/ipns/notafqdnorcid?argTest#hashTest') - dnslinkResolver.readDnslinkFromTxtRecord = sinon.stub().resolves(false) - await expectNoRedirect(modifyRequest, request, browser) - }) - }) - }) - }) - - describe('request to a subdomain gateway', function () { - const cid = 'bafybeigxjv2o4jse2lajbd5c7xxl5rluhyqg5yupln42252e5tcao7hbge' - const peerid = 'bafzbeigxjv2o4jse2lajbd5c7xxl5rluhyqg5yupln42252e5tcao7hbge' - - describe('with external node', function () { - beforeEach(function () { - state.ipfsNodeType = 'external' - // dweb.link is the default subdomain gw - }) - it('should be redirected to localhost gateway (*.ipfs on default gw)', async function () { - state.redirect = true - const request = url2request(`https://${cid}.ipfs.dweb.link/`) - - /// We expect redirect to path-based gateway because go-ipfs >=0.5 will - // return redirect to a subdomain, and we don't want to break users - // running older versions of go-ipfs by loading subdomain first and - // failing. - // expect((await modifyRequest.onBeforeRequest(request)).redirectUrl) - // .to.equal(`http://localhost:8080/ipfs/${cid}/`) - await modifyRequest.onBeforeRequest(request) - const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args - expect(args).to.deep.equal({ - addRules: [generateAddRule( - args.addRules[0].id, - `^https?\\:\\/\\/${cid}\\.ipfs\\.dweb\\.link${regexRuleEnding}`, - `http://localhost:8080/ipfs/${cid}\\1` - )], - removeRuleIds: [] - }) - }) - it('should be redirected to localhost gateway (*.ipfs on 3rd party gw)', async function () { - state.redirect = true - const request = url2request(`https://${cid}.ipfs.cf-ipfs.com/`) - // MV2 - // expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal(`http://localhost:8080/ipfs/${cid}/`) - await modifyRequest.onBeforeRequest(request) - const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args - expect(args).to.deep.equal({ - addRules: [generateAddRule( - args.addRules[0].id, - `^https?\\:\\/\\/${cid}\\.ipfs\\.cf\\-ipfs\\.com${regexRuleEnding}`, - `http://localhost:8080/ipfs/${cid}\\1` - )], - removeRuleIds: [] - }) - }) - it('should be redirected to localhost gateway and keep URL encoding of original path', async function () { - state.redirect = true - const request = url2request('https://bafybeigfejjsuq5im5c3w3t3krsiytszhfdc4v5myltcg4myv2n2w6jumy.ipfs.dweb.link/%3Ffilename=test.jpg?arg=val') - // MV2 - // expect((await modifyRequest.onBeforeRequest(request)).redirectUrl) - // .to.equal('http://localhost:8080/ipfs/bafybeigfejjsuq5im5c3w3t3krsiytszhfdc4v5myltcg4myv2n2w6jumy/%3Ffilename=test.jpg?arg=val') - await modifyRequest.onBeforeRequest(request) - const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args - expect(args).to.deep.equal({ - addRules: [generateAddRule( - args.addRules[0].id, - `^https?\\:\\/\\/bafybeigfejjsuq5im5c3w3t3krsiytszhfdc4v5myltcg4myv2n2w6jumy\\.ipfs\\.dweb\\.link${regexRuleEnding}`, - 'http://localhost:8080/ipfs/bafybeigfejjsuq5im5c3w3t3krsiytszhfdc4v5myltcg4myv2n2w6jumy\\1' - )], - removeRuleIds: [] - }) - }) - it('should be redirected to localhost gateway (*.ipns on default gw)', async function () { - state.redirect = true - const request = url2request(`https://${peerid}.ipns.dweb.link/`) - // MV2 - // expect((await modifyRequest.onBeforeRequest(request)).redirectUrl) - // .to.equal(`http://localhost:8080/ipns/${peerid}/`) - await modifyRequest.onBeforeRequest(request) - const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args - expect(args).to.deep.equal({ - addRules: [generateAddRule( - args.addRules[0].id, - `^https?\\:\\/\\/${peerid}\\.ipns\\.dweb\\.link${regexRuleEnding}`, - `http://localhost:8080/ipns/${peerid}\\1` - )], - removeRuleIds: [] - }) - }) - }) - }) - - describe('Recovers Page if node is unreachable', function () { - beforeEach(function () { - global.browser = browser - state.ipfsNodeType = 'external' - state.redirect = true - state.peerCount = -1 // this simulates Kubo RPC being offline - state.gwURLString = 'http://localhost:8080' - state.gwURL = new URL('http://localhost:8080') - state.pubGwURLString = 'https://ipfs.io' - state.pubGwURL = new URL('https://ipfs.io') - }) - it('should present recovery page if node is offline and redirect is enabled', async function () { - expect(state.nodeActive).to.be.equal(false) - state.redirect = true - const request = url2request('https://localhost:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR/foo/bar') - // mv2 - // expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('chrome-extension://testid/dist/recovery/recovery.html#https%3A%2F%2Fipfs.io%2Fipfs%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%2Ffoo%2Fbar') - await modifyRequest.onBeforeRequest(request) - const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args - - expect(args.addRules[0]).to.deep.equal(generateAddRule( - args.addRules[0].id, - `^https?\\:\\/\\/localhost\\:8080\\/ipfs\\/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR\\/foo\\/${regexRuleEnding}`, - 'chrome-extension://testid/dist/recovery/recovery.html#https%3A%2F%2Fipfs.io%2Fipfs%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%2Ffoo%2F\\1' - )) - }) - it('should present recovery page if node is offline and redirect is disabled', async function () { - expect(state.nodeActive).to.be.equal(false) - state.redirect = false - const request = url2request('https://localhost:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR/foo/bar') - // mv2 - // expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('chrome-extension://testid/dist/recovery/recovery.html#https%3A%2F%2Fipfs.io%2Fipfs%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%2Ffoo%2Fbar') - await modifyRequest.onBeforeRequest(request) - const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args - - expect(args.addRules[0]).to.deep.equal(generateAddRule( - args.addRules[0].id, - `^https?\\:\\/\\/localhost\\:8080\\/ipfs\\/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR\\/foo\\/${regexRuleEnding}`, - 'chrome-extension://testid/dist/recovery/recovery.html#https%3A%2F%2Fipfs.io%2Fipfs%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%2Ffoo%2F\\1' - )) - }) - it('should not show recovery page if node is offline, redirect is enabled, but non-gateway URL failed to load from the same port', async function () { - // this covers https://github.com/ipfs/ipfs-companion/issues/1162 and https://twitter.com/unicomp21/status/1626244123102679041 - state.redirect = true - expect(state.nodeActive).to.be.equal(false) - const request = url2request('https://localhost:8080/') - // mv2 - // expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) - await modifyRequest.onBeforeRequest(request) - await expectNoRedirect(modifyRequest, request, browser) - }) - it('should not show recovery page if extension is disabled', async function () { - // allows user to quickly avoid anything similar to https://github.com/ipfs/ipfs-companion/issues/1162 - state.active = false - expect(state.nodeActive).to.be.equal(false) - const request = url2request('https://localhost:8080/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR/foo/bar') - // mv2 - // expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) - await modifyRequest.onBeforeRequest(request) - await expectNoRedirect(modifyRequest, request, browser) - }) - }) - - after(function () { - delete global.URL - delete global.browser - sinonSandbox.restore() - browser.flush() - }) -}) diff --git a/test/functional/lib/ipfs-request-protocol-handlers.test.js b/test/functional/lib/ipfs-request-protocol-handlers.test.js index faf5ee4f5..1883839b8 100644 --- a/test/functional/lib/ipfs-request-protocol-handlers.test.js +++ b/test/functional/lib/ipfs-request-protocol-handlers.test.js @@ -1,20 +1,24 @@ 'use strict' -import { describe, it, before, beforeEach, after } from 'mocha' import { expect } from 'chai' -import { URL } from 'url' +import { after, before, beforeEach, describe, it } from 'mocha' +import Sinon from 'sinon' import browser from 'sinon-chrome' -import { initState } from '../../../add-on/src/lib/state.js' -import createRuntimeChecks from '../../../add-on/src/lib/runtime-checks.js' -import { createRequestModifier } from '../../../add-on/src/lib/ipfs-request.js' +import { URL } from 'url' import createDnslinkResolver from '../../../add-on/src/lib/dnslink.js' import { createIpfsPathValidator } from '../../../add-on/src/lib/ipfs-path.js' +import { createRequestModifier } from '../../../add-on/src/lib/ipfs-request.js' import { optionDefaults } from '../../../add-on/src/lib/options.js' +import { generateAddRule } from '../../../add-on/src/lib/redirect-handler/blockOrObserve.js' +import createRuntimeChecks from '../../../add-on/src/lib/runtime-checks.js' +import { initState } from '../../../add-on/src/lib/state.js' +import isMv3TestingEnabled from '../../helpers/is-mv3-testing-enabled.js' const url2request = (string) => { return { url: string, type: 'main_frame' } } const nodeTypes = ['external'] +const groupAtEndRegex = '((?:[^\\.]|$).*)$' describe('modifyRequest.onBeforeRequest:', function () { let state, dnslinkResolver, ipfsPathValidator, modifyRequest, runtime @@ -61,173 +65,558 @@ describe('modifyRequest.onBeforeRequest:', function () { // without web+ prefix (Firefox > 59: https://github.com/ipfs-shipyard/ipfs-companion/issues/164#issuecomment-356301174) it('should not be normalized if ipfs:/{CID}', async function () { const request = url2request('https://dweb.link/ipfs/?uri=ipfs%3A%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest') - expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) + } else { + expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + } }) it('should be normalized if ipfs://{CID}', async function () { const request = url2request('https://dweb.link/ipfs/?uri=ipfs%3A%2F%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest') - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args + expect(args).to.deep.equal({ + addRules: [ + generateAddRule( + args.addRules[0].id, + `^https?\\:\\/\\/dweb\\.link\\/ipfs\\/\\?uri\\=ipfs%3A%2F%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23${groupAtEndRegex}`, + 'https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#\\1') + ], + removeRuleIds: [] + }) + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + } }) it('should not be normalized if ipns:/{fqdn}', async function () { const request = url2request('https://dweb.link/ipfs/?uri=ipns%3A%2Fipfs.io%3FargTest%23hashTest') - expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) + } else { + expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + } }) it('should be normalized if ipns://{fqdn}', async function () { const request = url2request('https://dweb.link/ipfs/?uri=ipns%3A%2F%2Fipfs.io%3FargTest%23hashTest') - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipns/ipfs.io?argTest#hashTest') + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args + expect(args).to.deep.equal({ + addRules: [ + generateAddRule( + args.addRules[0].id, + `^https?\\:\\/\\/dweb\\.link\\/ipfs\\/\\?uri\\=ipns%3A%2F%2Fipfs\\.io%3FargTest%23${groupAtEndRegex}`, + 'https://ipfs.io/ipns/ipfs.io?argTest#\\1') + ], + removeRuleIds: [] + }) + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipns/ipfs.io?argTest#hashTest') + } }) it('should be normalized if ipfs://{fqdn}', async function () { const request = url2request('https://dweb.link/ipfs/?uri=ipfs%3A%2F%2Fipfs.io%3FargTest%23hashTest') - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipns/ipfs.io?argTest#hashTest') + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args + expect(args).to.deep.equal({ + addRules: [ + generateAddRule( + args.addRules[0].id, + `^https?\\:\\/\\/dweb\\.link\\/ipfs\\/\\?uri\\=ipfs%3A%2F%2Fipfs\\.io%3FargTest%23${groupAtEndRegex}`, + 'https://ipfs.io/ipns/ipfs.io?argTest#\\1') + ], + removeRuleIds: [] + }) + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipns/ipfs.io?argTest#hashTest') + } }) it('should be normalized if dweb:/ipfs/{CID}', async function () { const request = url2request('https://dweb.link/ipfs/?uri=dweb%3A%2Fipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest') - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args + expect(args).to.deep.equal({ + addRules: [ + generateAddRule( + args.addRules[0].id, + `^https?\\:\\/\\/dweb\\.link\\/ipfs\\/\\?uri\\=dweb%3A%2Fipfs\\/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23${groupAtEndRegex}`, + 'https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#\\1') + ], + removeRuleIds: [] + }) + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + } }) it('should not be normalized if dweb://ipfs/{CID}', async function () { const request = url2request('https://dweb.link/ipfs/?uri=dweb%3A%2F%2Fipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest') - expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) + } else { + expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + } }) it('should be normalized if dweb:/ipns/{foo}', async function () { const request = url2request('https://dweb.link/ipfs/?uri=dweb%3A%2Fipns/ipfs.io%3FargTest%23hashTest') - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).equal('https://ipfs.io/ipns/ipfs.io?argTest#hashTest') + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args + expect(args).to.deep.equal({ + addRules: [ + generateAddRule( + args.addRules[0].id, + `^https?\\:\\/\\/dweb\\.link\\/ipfs\\/\\?uri\\=dweb%3A%2Fipns\\/ipfs\\.io%3FargTest%23${groupAtEndRegex}`, + 'https://ipfs.io/ipns/ipfs.io?argTest#\\1') + ], + removeRuleIds: [] + }) + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).equal('https://ipfs.io/ipns/ipfs.io?argTest#hashTest') + } }) it('should not be normalized if dweb://ipns/{foo}', async function () { const request = url2request('https://dweb.link/ipfs/?uri=dweb%3A%2F%2Fipns/ipfs.io%3FargTest%23hashTest') - expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) + } else { + expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + } }) // web+ prefixed versions (Firefox < 59 and Chrome) it('should not be normalized if web+ipfs:/{CID}', async function () { const request = url2request('https://dweb.link/ipfs/?uri=web%2Bipfs%3A%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest') - expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) + } else { + expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + } }) it('should be normalized if web+ipfs://{CID}', async function () { const request = url2request('https://dweb.link/ipfs/?uri=web%2Bipfs%3A%2F%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest') - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args + expect(args).to.deep.equal({ + addRules: [ + generateAddRule( + args.addRules[0].id, + `^https?\\:\\/\\/dweb\\.link\\/ipfs\\/\\?uri\\=web%2Bipfs%3A%2F%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23${groupAtEndRegex}`, + 'https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#\\1') + ], + removeRuleIds: [] + }) + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + } }) it('should not be normalized if web+ipns:/{foo}', async function () { const request = url2request('https://dweb.link/ipfs/?uri=web%2Bipns%3A%2Fipfs.io%3FargTest%23hashTest') - expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) + } else { + expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + } }) it('should be normalized if web+ipns://{foo}', async function () { const request = url2request('https://dweb.link/ipfs/?uri=web%2Bipns%3A%2F%2Fipfs.io%3FargTest%23hashTest') - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipns/ipfs.io?argTest#hashTest') + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args + expect(args).to.deep.equal({ + addRules: [ + generateAddRule( + args.addRules[0].id, + `^https?\\:\\/\\/dweb\\.link\\/ipfs\\/\\?uri\\=web%2Bipns%3A%2F%2Fipfs\\.io%3FargTest%23${groupAtEndRegex}`, + 'https://ipfs.io/ipns/ipfs.io?argTest#\\1') + ], + removeRuleIds: [] + }) + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipns/ipfs.io?argTest#hashTest') + } }) it('should be normalized if web+dweb:/ipfs/{CID}', async function () { const request = url2request('https://dweb.link/ipfs/?uri=web%2Bdweb%3A%2Fipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest') - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args + expect(args).to.deep.equal({ + addRules: [ + generateAddRule( + args.addRules[0].id, + `^https?\\:\\/\\/dweb\\.link\\/ipfs\\/\\?uri\\=web%2Bdweb%3A%2Fipfs\\/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23${groupAtEndRegex}`, + 'https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#\\1') + ], + removeRuleIds: [] + }) + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + } }) it('should not be normalized if web+dweb://ipfs/{CID}', async function () { const request = url2request('https://dweb.link/ipfs/?uri=web%2Bdweb%3A%2F%2Fipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest') - expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) + } else { + expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + } }) it('should be normalized if web+dweb:/ipns/{foo}', async function () { const request = url2request('https://dweb.link/ipfs/?uri=web%2Bdweb%3A%2Fipns/ipfs.io%3FargTest%23hashTest') - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).equal('https://ipfs.io/ipns/ipfs.io?argTest#hashTest') + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args + expect(args).to.deep.equal({ + addRules: [ + generateAddRule( + args.addRules[0].id, + `^https?\\:\\/\\/dweb\\.link\\/ipfs\\/\\?uri\\=web%2Bdweb%3A%2Fipns\\/ipfs\\.io%3FargTest%23${groupAtEndRegex}`, + 'https://ipfs.io/ipns/ipfs.io?argTest#\\1') + ], + removeRuleIds: [] + }) + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).equal('https://ipfs.io/ipns/ipfs.io?argTest#hashTest') + } }) it('should not be normalized if web+dweb://ipns/{foo}', async function () { const request = url2request('https://dweb.link/ipfs/?uri=web%2Bdweb%3A%2F%2Fipns/ipfs.io%3FargTest%23hashTest') - expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) + } else { + expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + } }) it('should not be normalized if web+{foo}:/bar', async function () { const request = url2request('https://dweb.link/ipfs/?uri=web%2Bfoo%3A%2Fbar%3FargTest%23hashTest') - expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) + } else { + expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + } }) it('should not be normalized if web+{foo}://bar', async function () { const request = url2request('https://dweb.link/ipfs/?uri=web%2Bfoo%3A%2F%2Fbar%3FargTest%23hashTest') - expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) + } else { + expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + } }) }) describe('catching unhandled custom protocol request', function () { it('should not be normalized if ipfs:/{CID}', async function () { const request = url2request('https://duckduckgo.com/?q=ipfs%3A%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest&foo=bar') - expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) + } else { + expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + } }) it('should be normalized if ipfs://{CID}', async function () { const request = url2request('https://duckduckgo.com/?q=ipfs%3A%2F%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest&foo=bar') - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args + expect(args).to.deep.equal({ + addRules: [ + generateAddRule( + args.addRules[0].id, + `^https?\\:\\/\\/duckduckgo\\.com\\/\\?q\\=ipfs%3A%2F%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest\\&foo\\=bar${groupAtEndRegex}`, + 'https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest\\1') + ], + removeRuleIds: [] + }) + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + } }) it('should not be normalized if ipns:/{foo}', async function () { const request = url2request('https://duckduckgo.com/?q=ipns%3A%2Fipns.io%2Findex.html%3Farg%3Dfoo%26bar%3Dbuzz%23hashTest') - expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) + } else { + expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + } }) it('should be normalized if ipns://{foo}', async function () { const request = url2request('https://duckduckgo.com/?q=ipns%3A%2F%2Fipns.io%2Findex.html%3Farg%3Dfoo%26bar%3Dbuzz%23hashTest') - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipns/ipns.io/index.html?arg=foo&bar=buzz#hashTest') + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args + expect(args).to.deep.equal({ + addRules: [ + generateAddRule( + args.addRules[0].id, + `^https?\\:\\/\\/duckduckgo\\.com\\/\\?q\\=ipns%3A%2F%2Fipns\\.io%2Findex\\.html%3Farg%3Dfoo%26bar%3Dbuzz%23${groupAtEndRegex}`, + 'https://ipfs.io/ipns/ipns.io/index.html?arg=foo&bar=buzz#\\1') + ], + removeRuleIds: [] + }) + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipns/ipns.io/index.html?arg=foo&bar=buzz#hashTest') + } }) it('should be normalized if ipfs://{fqdn}', async function () { const request = url2request('https://duckduckgo.com/?q=ipfs%3A%2F%2Fipns.io%2Findex.html%3Farg%3Dfoo%26bar%3Dbuzz%23hashTest') - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipns/ipns.io/index.html?arg=foo&bar=buzz#hashTest') + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args + expect(args).to.deep.equal({ + addRules: [ + generateAddRule( + args.addRules[0].id, + `^https?\\:\\/\\/duckduckgo\\.com\\/\\?q\\=ipfs%3A%2F%2Fipns\\.io%2Findex\\.html%3Farg%3Dfoo%26bar%3Dbuzz%23${groupAtEndRegex}`, + 'https://ipfs.io/ipns/ipns.io/index.html?arg=foo&bar=buzz#\\1' + ) + ], + removeRuleIds: [] + }) + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipns/ipns.io/index.html?arg=foo&bar=buzz#hashTest') + } }) it('should be normalized if dweb:/ipfs/{CID}', async function () { const request = url2request('https://duckduckgo.com/?q=dweb%3A%2Fipfs%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3Farg%3Dfoo%26bar%3Dbuzz%23hash&ia=software') - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?arg=foo&bar=buzz#hash') + + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args + expect(args).to.deep.equal({ + addRules: [ + generateAddRule( + args.addRules[0].id, + `^https?\\:\\/\\/duckduckgo\\.com\\/\\?q\\=dweb%3A%2Fipfs%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3Farg%3Dfoo%26bar%3Dbuzz%23hash\\&ia\\=software${groupAtEndRegex}`, + 'https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?arg=foo&bar=buzz#hash\\1' + ) + ], + removeRuleIds: [] + }) + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?arg=foo&bar=buzz#hash') + } }) it('should not be normalized if dweb://ipfs/{CID}', async function () { const request = url2request('https://duckduckgo.com/?q=dweb%3A%2F%2Fipfs%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3Farg%3Dfoo%26bar%3Dbuzz%23hash&ia=software') - expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) + } else { + expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + } }) it('should be normalized if dweb:/ipns/{foo}', async function () { const request = url2request('https://duckduckgo.com/?q=dweb%3A%2Fipns%2Fipfs.io%2Findex.html%3Farg%3Dfoo%26bar%3Dbuzz%23hash&ia=web') - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipns/ipfs.io/index.html?arg=foo&bar=buzz#hash') + + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args + expect(args).to.deep.equal({ + addRules: [ + generateAddRule( + args.addRules[0].id, + `^https?\\:\\/\\/duckduckgo\\.com\\/\\?q\\=dweb%3A%2Fipns%2Fipfs\\.io%2Findex\\.html%3Farg%3Dfoo%26bar%3Dbuzz%23hash\\&ia\\=web${groupAtEndRegex}`, + 'https://ipfs.io/ipns/ipfs.io/index.html?arg=foo&bar=buzz#hash\\1' + ) + ], + removeRuleIds: [] + }) + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipns/ipfs.io/index.html?arg=foo&bar=buzz#hash') + } }) it('should not be normalized if dweb://ipns/{foo}', async function () { const request = url2request('https://duckduckgo.com/?q=dweb%3A%2F%2Fipns%2Fipfs.io%2Findex.html%3Farg%3Dfoo%26bar%3Dbuzz%23hash&ia=web') - expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) + } else { + expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + } }) it('should not be normalized if web+ipfs:/{CID}', async function () { const request = url2request('https://duckduckgo.com/?q=web%2Bipfs%3A%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest&foo=bar') - expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) + } else { + expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + } }) it('should be normalized if web+ipfs://{CID}', async function () { const request = url2request('https://duckduckgo.com/?q=web%2Bipfs%3A%2F%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest&foo=bar') - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args + expect(args).to.deep.equal({ + addRules: [ + generateAddRule( + args.addRules[0].id, + `^https?\\:\\/\\/duckduckgo\\.com\\/\\?q\\=web%2Bipfs%3A%2F%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest\\&foo\\=bar${groupAtEndRegex}`, + 'https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest\\1' + ) + ], + removeRuleIds: [] + }) + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') + } }) it('should not be normalized if web+ipns:/{foo}', async function () { const request = url2request('https://duckduckgo.com/?q=web%2Bipns%3A%2Fipns.io%2Findex.html%3Farg%3Dfoo%26bar%3Dbuzz%23hashTest') - expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) + } else { + expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + } }) it('should be normalized if web+ipns://{foo}', async function () { const request = url2request('https://duckduckgo.com/?q=web%2Bipns%3A%2F%2Fipns.io%2Findex.html%3Farg%3Dfoo%26bar%3Dbuzz%23hashTest') - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipns/ipns.io/index.html?arg=foo&bar=buzz#hashTest') + + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args + expect(args).to.deep.equal({ + addRules: [ + generateAddRule( + args.addRules[0].id, + `^https?\\:\\/\\/duckduckgo\\.com\\/\\?q\\=web%2Bipns%3A%2F%2Fipns\\.io%2Findex\\.html%3Farg%3Dfoo%26bar%3Dbuzz%23${groupAtEndRegex}`, + 'https://ipfs.io/ipns/ipns.io/index.html?arg=foo&bar=buzz#\\1' + ) + ], + removeRuleIds: [] + }) + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipns/ipns.io/index.html?arg=foo&bar=buzz#hashTest') + } }) it('should be normalized if web+dweb:/ipfs/{CID}', async function () { const request = url2request('https://duckduckgo.com/?q=web%2Bdweb%3A%2Fipfs%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3Farg%3Dfoo%26bar%3Dbuzz%23hash&ia=software') - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?arg=foo&bar=buzz#hash') + + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args + expect(args).to.deep.equal({ + addRules: [ + generateAddRule( + args.addRules[0].id, + `^https?\\:\\/\\/duckduckgo\\.com\\/\\?q\\=web%2Bdweb%3A%2Fipfs%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3Farg%3Dfoo%26bar%3Dbuzz%23hash\\&ia\\=software${groupAtEndRegex}`, + 'https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?arg=foo&bar=buzz#hash\\1' + ) + ], + removeRuleIds: [] + }) + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?arg=foo&bar=buzz#hash') + } }) it('should not be normalized if web+dweb://ipfs/{CID}', async function () { const request = url2request('https://duckduckgo.com/?q=web%2Bdweb%3A%2F%2Fipfs%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3Farg%3Dfoo%26bar%3Dbuzz%23hash&ia=software') - expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) + } else { + expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + } }) it('should be normalized if web+dweb:/ipns/{foo}', async function () { const request = url2request('https://duckduckgo.com/?q=web%2Bdweb%3A%2Fipns%2Fipfs.io%2Findex.html%3Farg%3Dfoo%26bar%3Dbuzz%23hash&ia=web') - expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipns/ipfs.io/index.html?arg=foo&bar=buzz#hash') - }) - it('should not be normalized if web+dweb://ipns/{foo}', async function () { + + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args + expect(args).to.deep.equal({ + addRules: [ + generateAddRule( + args.addRules[0].id, + `^https?\\:\\/\\/duckduckgo\\.com\\/\\?q\\=web%2Bdweb%3A%2Fipns%2Fipfs\\.io%2Findex\\.html%3Farg%3Dfoo%26bar%3Dbuzz%23hash\\&ia\\=web${groupAtEndRegex}`, + 'https://ipfs.io/ipns/ipfs.io/index.html?arg=foo&bar=buzz#hash\\1' + ) + ], + removeRuleIds: [] + }) + } else { + expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipns/ipfs.io/index.html?arg=foo&bar=buzz#hash') + } + }) + it('should not be normalized if web+dweb://ipns/{foo}2', async function () { const request = url2request('https://duckduckgo.com/?q=web%2Bdweb%3A%2F%2Fipns%2Fipfs.io%2Findex.html%3Farg%3Dfoo%26bar%3Dbuzz%23hash&ia=web') - expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) + } else { + expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + } }) it('should not be normalized if disabled in Preferences', async function () { state.catchUnhandledProtocols = false const request = url2request('https://duckduckgo.com/?q=ipfs%3A%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest&foo=bar') - expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) + } else { + expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + } }) it('should not be normalized if CID is invalid', async function () { state.catchUnhandledProtocols = false const request = url2request('https://duckduckgo.com/?q=ipfs%3A%2FnotARealIpfsPathWithCid%3FargTest%23hashTest&foo=bar') - expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) + } else { + expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + } }) it('should not be normalized if presence of %3A%2F is a false-positive', async function () { state.catchUnhandledProtocols = false const request = url2request('https://duckduckgo.com/?q=foo%3A%2Fbar%3FargTest%23hashTest&foo=bar') - expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(request) + Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) + } else { + expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) + } }) it('should not be normalized if request.type != main_frame', async function () { const mediaRequest = { url: 'https://duckduckgo.com/?q=ipfs%3A%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest&foo=bar', type: 'media' } - expect(await modifyRequest.onBeforeRequest(mediaRequest)).to.equal(undefined) + + if (isMv3TestingEnabled) { + await modifyRequest.onBeforeRequest(mediaRequest) + Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) + } else { + expect(await modifyRequest.onBeforeRequest(mediaRequest)).to.equal(undefined) + } }) }) }) diff --git a/test/functional/lib/ipfs-request-protocol-handlers.test.mv3.js b/test/functional/lib/ipfs-request-protocol-handlers.test.mv3.js deleted file mode 100644 index 736bc039c..000000000 --- a/test/functional/lib/ipfs-request-protocol-handlers.test.mv3.js +++ /dev/null @@ -1,529 +0,0 @@ -'use strict' -import { describe, it, before, beforeEach, after } from 'mocha' -import { expect } from 'chai' -import { URL } from 'url' -import browser from 'sinon-chrome' -import { initState } from '../../../add-on/src/lib/state.js' -import createRuntimeChecks from '../../../add-on/src/lib/runtime-checks.js' -import { createRequestModifier } from '../../../add-on/src/lib/ipfs-request.js' -import createDnslinkResolver from '../../../add-on/src/lib/dnslink.js' -import { createIpfsPathValidator } from '../../../add-on/src/lib/ipfs-path.js' -import { optionDefaults } from '../../../add-on/src/lib/options.js' -import Sinon from 'sinon' -import { generateAddRule } from '../../../add-on/src/lib/redirect-handler/blockOrObserve.js' - -const url2request = (string) => { - return { url: string, type: 'main_frame' } -} - -const nodeTypes = ['external'] -const groupAtEndRegex = '((?:[^\\.]|$).*)$' - -describe('modifyRequest.onBeforeRequest:', function () { - let state, dnslinkResolver, ipfsPathValidator, modifyRequest, runtime - - before(function () { - global.URL = URL - }) - - beforeEach(async function () { - state = Object.assign(initState(optionDefaults), { - ipfsNodeType: 'external', - peerCount: 1, - redirect: true, - dnslinkPolicy: false, // dnslink test suite is in ipfs-request-dnslink.test.js - catchUnhandledProtocols: true, - gwURLString: 'http://127.0.0.1:8080', - pubGwURLString: 'https://ipfs.io' - }) - const getState = () => state - const getIpfs = () => {} - dnslinkResolver = createDnslinkResolver(getState) - runtime = Object.assign({}, await createRuntimeChecks(browser)) // make it mutable for tests - ipfsPathValidator = createIpfsPathValidator(getState, getIpfs, dnslinkResolver) - modifyRequest = createRequestModifier(getState, dnslinkResolver, ipfsPathValidator, runtime) - }) - - // tests in which results should be the same for all node types - nodeTypes.forEach(function (nodeType) { - beforeEach(function () { - state.ipfsNodeType = nodeType - }) - describe(`with ${nodeType} node:`, function () { - describe('request made via redirect-based protocol handler from manifest.json/protocol_handlers', function () { - // Note: requests done with custom protocol handler are always normalized to public gateway - // (if external node is enabled, redirect will happen in next iteration of modifyRequest) - beforeEach(function () { - // ..however to make tests easier we disable redirect from public to custom gateway - // (with this modifyRequest will return undefined for invalid URIs) - state.redirect = false - }) - - // without web+ prefix (Firefox > 59: https://github.com/ipfs-shipyard/ipfs-companion/issues/164#issuecomment-356301174) - it('should not be normalized if ipfs:/{CID}', async function () { - const request = url2request('https://dweb.link/ipfs/?uri=ipfs%3A%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest') - await modifyRequest.onBeforeRequest(request) - Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) - }) - it('should be normalized if ipfs://{CID}', async function () { - const request = url2request('https://dweb.link/ipfs/?uri=ipfs%3A%2F%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest') - // mv2 - // expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') - await modifyRequest.onBeforeRequest(request) - const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args - expect(args).to.deep.equal({ - addRules: [ - generateAddRule( - args.addRules[0].id, - `^https?\\:\\/\\/dweb\\.link\\/ipfs\\/\\?uri\\=ipfs%3A%2F%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23${groupAtEndRegex}`, - 'https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#\\1') - ], - removeRuleIds: [] - }) - }) - it('should not be normalized if ipns:/{fqdn}', async function () { - const request = url2request('https://dweb.link/ipfs/?uri=ipns%3A%2Fipfs.io%3FargTest%23hashTest') - // mv2 - // expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) - await modifyRequest.onBeforeRequest(request) - Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) - }) - it('should be normalized if ipns://{fqdn}', async function () { - const request = url2request('https://dweb.link/ipfs/?uri=ipns%3A%2F%2Fipfs.io%3FargTest%23hashTest') - // mv2 - // expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipns/ipfs.io?argTest#hashTest') - await modifyRequest.onBeforeRequest(request) - const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args - expect(args).to.deep.equal({ - addRules: [ - generateAddRule( - args.addRules[0].id, - `^https?\\:\\/\\/dweb\\.link\\/ipfs\\/\\?uri\\=ipns%3A%2F%2Fipfs\\.io%3FargTest%23${groupAtEndRegex}`, - 'https://ipfs.io/ipns/ipfs.io?argTest#\\1') - ], - removeRuleIds: [] - }) - }) - it('should be normalized if ipfs://{fqdn}', async function () { - const request = url2request('https://dweb.link/ipfs/?uri=ipfs%3A%2F%2Fipfs.io%3FargTest%23hashTest') - // mv2 - // expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipns/ipfs.io?argTest#hashTest') - await modifyRequest.onBeforeRequest(request) - const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args - expect(args).to.deep.equal({ - addRules: [ - generateAddRule( - args.addRules[0].id, - `^https?\\:\\/\\/dweb\\.link\\/ipfs\\/\\?uri\\=ipfs%3A%2F%2Fipfs\\.io%3FargTest%23${groupAtEndRegex}`, - 'https://ipfs.io/ipns/ipfs.io?argTest#\\1') - ], - removeRuleIds: [] - }) - }) - it('should be normalized if dweb:/ipfs/{CID}', async function () { - const request = url2request('https://dweb.link/ipfs/?uri=dweb%3A%2Fipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest') - // mv2 - // expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') - await modifyRequest.onBeforeRequest(request) - const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args - expect(args).to.deep.equal({ - addRules: [ - generateAddRule( - args.addRules[0].id, - `^https?\\:\\/\\/dweb\\.link\\/ipfs\\/\\?uri\\=dweb%3A%2Fipfs\\/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23${groupAtEndRegex}`, - 'https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#\\1') - ], - removeRuleIds: [] - }) - }) - it('should not be normalized if dweb://ipfs/{CID}', async function () { - const request = url2request('https://dweb.link/ipfs/?uri=dweb%3A%2F%2Fipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest') - // mv2 - // expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) - await modifyRequest.onBeforeRequest(request) - Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) - }) - it('should be normalized if dweb:/ipns/{foo}', async function () { - const request = url2request('https://dweb.link/ipfs/?uri=dweb%3A%2Fipns/ipfs.io%3FargTest%23hashTest') - // mv2 - // expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).equal('https://ipfs.io/ipns/ipfs.io?argTest#hashTest') - await modifyRequest.onBeforeRequest(request) - const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args - expect(args).to.deep.equal({ - addRules: [ - generateAddRule( - args.addRules[0].id, - `^https?\\:\\/\\/dweb\\.link\\/ipfs\\/\\?uri\\=dweb%3A%2Fipns\\/ipfs\\.io%3FargTest%23${groupAtEndRegex}`, - 'https://ipfs.io/ipns/ipfs.io?argTest#\\1') - ], - removeRuleIds: [] - }) - }) - it('should not be normalized if dweb://ipns/{foo}', async function () { - const request = url2request('https://dweb.link/ipfs/?uri=dweb%3A%2F%2Fipns/ipfs.io%3FargTest%23hashTest') - // mv2 - // expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) - await modifyRequest.onBeforeRequest(request) - Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) - }) - - // web+ prefixed versions (Firefox < 59 and Chrome) - it('should not be normalized if web+ipfs:/{CID}', async function () { - const request = url2request('https://dweb.link/ipfs/?uri=web%2Bipfs%3A%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest') - // mv2 - // expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) - await modifyRequest.onBeforeRequest(request) - Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) - }) - it('should be normalized if web+ipfs://{CID}', async function () { - const request = url2request('https://dweb.link/ipfs/?uri=web%2Bipfs%3A%2F%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest') - // mv2 - // expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') - await modifyRequest.onBeforeRequest(request) - const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args - expect(args).to.deep.equal({ - addRules: [ - generateAddRule( - args.addRules[0].id, - `^https?\\:\\/\\/dweb\\.link\\/ipfs\\/\\?uri\\=web%2Bipfs%3A%2F%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23${groupAtEndRegex}`, - 'https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#\\1') - ], - removeRuleIds: [] - }) - }) - it('should not be normalized if web+ipns:/{foo}', async function () { - const request = url2request('https://dweb.link/ipfs/?uri=web%2Bipns%3A%2Fipfs.io%3FargTest%23hashTest') - // mv2 - // expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) - await modifyRequest.onBeforeRequest(request) - Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) - }) - it('should be normalized if web+ipns://{foo}', async function () { - const request = url2request('https://dweb.link/ipfs/?uri=web%2Bipns%3A%2F%2Fipfs.io%3FargTest%23hashTest') - // mv2 - // expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipns/ipfs.io?argTest#hashTest') - await modifyRequest.onBeforeRequest(request) - const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args - expect(args).to.deep.equal({ - addRules: [ - generateAddRule( - args.addRules[0].id, - `^https?\\:\\/\\/dweb\\.link\\/ipfs\\/\\?uri\\=web%2Bipns%3A%2F%2Fipfs\\.io%3FargTest%23${groupAtEndRegex}`, - 'https://ipfs.io/ipns/ipfs.io?argTest#\\1') - ], - removeRuleIds: [] - }) - }) - it('should be normalized if web+dweb:/ipfs/{CID}', async function () { - const request = url2request('https://dweb.link/ipfs/?uri=web%2Bdweb%3A%2Fipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest') - // mv2 - // expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') - await modifyRequest.onBeforeRequest(request) - const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args - expect(args).to.deep.equal({ - addRules: [ - generateAddRule( - args.addRules[0].id, - `^https?\\:\\/\\/dweb\\.link\\/ipfs\\/\\?uri\\=web%2Bdweb%3A%2Fipfs\\/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23${groupAtEndRegex}`, - 'https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#\\1') - ], - removeRuleIds: [] - }) - }) - it('should not be normalized if web+dweb://ipfs/{CID}', async function () { - const request = url2request('https://dweb.link/ipfs/?uri=web%2Bdweb%3A%2F%2Fipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest') - // mv2 - // expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) - await modifyRequest.onBeforeRequest(request) - Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) - }) - it('should be normalized if web+dweb:/ipns/{foo}', async function () { - const request = url2request('https://dweb.link/ipfs/?uri=web%2Bdweb%3A%2Fipns/ipfs.io%3FargTest%23hashTest') - // mv2 - // expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).equal('https://ipfs.io/ipns/ipfs.io?argTest#hashTest') - await modifyRequest.onBeforeRequest(request) - const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args - expect(args).to.deep.equal({ - addRules: [ - generateAddRule( - args.addRules[0].id, - `^https?\\:\\/\\/dweb\\.link\\/ipfs\\/\\?uri\\=web%2Bdweb%3A%2Fipns\\/ipfs\\.io%3FargTest%23${groupAtEndRegex}`, - 'https://ipfs.io/ipns/ipfs.io?argTest#\\1') - ], - removeRuleIds: [] - }) - }) - it('should not be normalized if web+dweb://ipns/{foo}', async function () { - const request = url2request('https://dweb.link/ipfs/?uri=web%2Bdweb%3A%2F%2Fipns/ipfs.io%3FargTest%23hashTest') - // mv2 - // expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) - await modifyRequest.onBeforeRequest(request) - Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) - }) - it('should not be normalized if web+{foo}:/bar', async function () { - const request = url2request('https://dweb.link/ipfs/?uri=web%2Bfoo%3A%2Fbar%3FargTest%23hashTest') - // mv2 - // expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) - await modifyRequest.onBeforeRequest(request) - Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) - }) - it('should not be normalized if web+{foo}://bar', async function () { - const request = url2request('https://dweb.link/ipfs/?uri=web%2Bfoo%3A%2F%2Fbar%3FargTest%23hashTest') - // mv2 - // expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) - await modifyRequest.onBeforeRequest(request) - Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) - }) - }) - - describe('catching unhandled custom protocol request', function () { - it('should not be normalized if ipfs:/{CID}', async function () { - const request = url2request('https://duckduckgo.com/?q=ipfs%3A%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest&foo=bar') - // mv2 - // expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) - await modifyRequest.onBeforeRequest(request) - Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) - }) - it('should be normalized if ipfs://{CID}', async function () { - const request = url2request('https://duckduckgo.com/?q=ipfs%3A%2F%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest&foo=bar') - // mv2 - // expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') - await modifyRequest.onBeforeRequest(request) - const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args - expect(args).to.deep.equal({ - addRules: [ - generateAddRule( - args.addRules[0].id, - `^https?\\:\\/\\/duckduckgo\\.com\\/\\?q\\=ipfs%3A%2F%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest\\&foo\\=bar${groupAtEndRegex}`, - 'https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest\\1') - ], - removeRuleIds: [] - }) - }) - it('should not be normalized if ipns:/{foo}', async function () { - const request = url2request('https://duckduckgo.com/?q=ipns%3A%2Fipns.io%2Findex.html%3Farg%3Dfoo%26bar%3Dbuzz%23hashTest') - // mv2 - // expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) - await modifyRequest.onBeforeRequest(request) - Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) - }) - it('should be normalized if ipns://{foo}', async function () { - const request = url2request('https://duckduckgo.com/?q=ipns%3A%2F%2Fipns.io%2Findex.html%3Farg%3Dfoo%26bar%3Dbuzz%23hashTest') - // mv2 - // expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipns/ipns.io/index.html?arg=foo&bar=buzz#hashTest') - await modifyRequest.onBeforeRequest(request) - const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args - expect(args).to.deep.equal({ - addRules: [ - generateAddRule( - args.addRules[0].id, - `^https?\\:\\/\\/duckduckgo\\.com\\/\\?q\\=ipns%3A%2F%2Fipns\\.io%2Findex\\.html%3Farg%3Dfoo%26bar%3Dbuzz%23${groupAtEndRegex}`, - 'https://ipfs.io/ipns/ipns.io/index.html?arg=foo&bar=buzz#\\1') - ], - removeRuleIds: [] - }) - }) - it('should be normalized if ipfs://{fqdn}', async function () { - const request = url2request('https://duckduckgo.com/?q=ipfs%3A%2F%2Fipns.io%2Findex.html%3Farg%3Dfoo%26bar%3Dbuzz%23hashTest') - // mv2 - // expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipns/ipns.io/index.html?arg=foo&bar=buzz#hashTest') - await modifyRequest.onBeforeRequest(request) - const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args - expect(args).to.deep.equal({ - addRules: [ - generateAddRule( - args.addRules[0].id, - `^https?\\:\\/\\/duckduckgo\\.com\\/\\?q\\=ipfs%3A%2F%2Fipns\\.io%2Findex\\.html%3Farg%3Dfoo%26bar%3Dbuzz%23${groupAtEndRegex}`, - 'https://ipfs.io/ipns/ipns.io/index.html?arg=foo&bar=buzz#\\1' - ) - ], - removeRuleIds: [] - }) - }) - it('should be normalized if dweb:/ipfs/{CID}', async function () { - const request = url2request('https://duckduckgo.com/?q=dweb%3A%2Fipfs%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3Farg%3Dfoo%26bar%3Dbuzz%23hash&ia=software') - // mv2 - // expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?arg=foo&bar=buzz#hash') - await modifyRequest.onBeforeRequest(request) - const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args - expect(args).to.deep.equal({ - addRules: [ - generateAddRule( - args.addRules[0].id, - `^https?\\:\\/\\/duckduckgo\\.com\\/\\?q\\=dweb%3A%2Fipfs%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3Farg%3Dfoo%26bar%3Dbuzz%23hash\\&ia\\=software${groupAtEndRegex}`, - 'https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?arg=foo&bar=buzz#hash\\1' - ) - ], - removeRuleIds: [] - }) - }) - it('should not be normalized if dweb://ipfs/{CID}', async function () { - const request = url2request('https://duckduckgo.com/?q=dweb%3A%2F%2Fipfs%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3Farg%3Dfoo%26bar%3Dbuzz%23hash&ia=software') - // mv2 - // expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) - await modifyRequest.onBeforeRequest(request) - Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) - }) - it('should be normalized if dweb:/ipns/{foo}', async function () { - const request = url2request('https://duckduckgo.com/?q=dweb%3A%2Fipns%2Fipfs.io%2Findex.html%3Farg%3Dfoo%26bar%3Dbuzz%23hash&ia=web') - // mv2 - // expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipns/ipfs.io/index.html?arg=foo&bar=buzz#hash') - await modifyRequest.onBeforeRequest(request) - const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args - expect(args).to.deep.equal({ - addRules: [ - generateAddRule( - args.addRules[0].id, - `^https?\\:\\/\\/duckduckgo\\.com\\/\\?q\\=dweb%3A%2Fipns%2Fipfs\\.io%2Findex\\.html%3Farg%3Dfoo%26bar%3Dbuzz%23hash\\&ia\\=web${groupAtEndRegex}`, - 'https://ipfs.io/ipns/ipfs.io/index.html?arg=foo&bar=buzz#hash\\1' - ) - ], - removeRuleIds: [] - }) - }) - it('should not be normalized if dweb://ipns/{foo}', async function () { - const request = url2request('https://duckduckgo.com/?q=dweb%3A%2F%2Fipns%2Fipfs.io%2Findex.html%3Farg%3Dfoo%26bar%3Dbuzz%23hash&ia=web') - // mv2 - // expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) - await modifyRequest.onBeforeRequest(request) - Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) - }) - - it('should not be normalized if web+ipfs:/{CID}', async function () { - const request = url2request('https://duckduckgo.com/?q=web%2Bipfs%3A%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest&foo=bar') - // mv2 - // expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) - await modifyRequest.onBeforeRequest(request) - Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) - }) - it('should be normalized if web+ipfs://{CID}', async function () { - const request = url2request('https://duckduckgo.com/?q=web%2Bipfs%3A%2F%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest&foo=bar') - // mv2 - // expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest') - await modifyRequest.onBeforeRequest(request) - const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args - expect(args).to.deep.equal({ - addRules: [ - generateAddRule( - args.addRules[0].id, - `^https?\\:\\/\\/duckduckgo\\.com\\/\\?q\\=web%2Bipfs%3A%2F%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest\\&foo\\=bar${groupAtEndRegex}`, - 'https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?argTest#hashTest\\1' - ) - ], - removeRuleIds: [] - }) - }) - it('should not be normalized if web+ipns:/{foo}', async function () { - const request = url2request('https://duckduckgo.com/?q=web%2Bipns%3A%2Fipns.io%2Findex.html%3Farg%3Dfoo%26bar%3Dbuzz%23hashTest') - // mv2 - // expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) - await modifyRequest.onBeforeRequest(request) - Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) - }) - it('should be normalized if web+ipns://{foo}', async function () { - const request = url2request('https://duckduckgo.com/?q=web%2Bipns%3A%2F%2Fipns.io%2Findex.html%3Farg%3Dfoo%26bar%3Dbuzz%23hashTest') - // mv2 - // expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipns/ipns.io/index.html?arg=foo&bar=buzz#hashTest') - await modifyRequest.onBeforeRequest(request) - const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args - expect(args).to.deep.equal({ - addRules: [ - generateAddRule( - args.addRules[0].id, - `^https?\\:\\/\\/duckduckgo\\.com\\/\\?q\\=web%2Bipns%3A%2F%2Fipns\\.io%2Findex\\.html%3Farg%3Dfoo%26bar%3Dbuzz%23${groupAtEndRegex}`, - 'https://ipfs.io/ipns/ipns.io/index.html?arg=foo&bar=buzz#\\1' - ) - ], - removeRuleIds: [] - }) - }) - it('should be normalized if web+dweb:/ipfs/{CID}', async function () { - const request = url2request('https://duckduckgo.com/?q=web%2Bdweb%3A%2Fipfs%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3Farg%3Dfoo%26bar%3Dbuzz%23hash&ia=software') - // mv2 - // expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?arg=foo&bar=buzz#hash') - await modifyRequest.onBeforeRequest(request) - const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args - expect(args).to.deep.equal({ - addRules: [ - generateAddRule( - args.addRules[0].id, - `^https?\\:\\/\\/duckduckgo\\.com\\/\\?q\\=web%2Bdweb%3A%2Fipfs%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3Farg%3Dfoo%26bar%3Dbuzz%23hash\\&ia\\=software${groupAtEndRegex}`, - 'https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?arg=foo&bar=buzz#hash\\1' - ) - ], - removeRuleIds: [] - }) - }) - it('should not be normalized if web+dweb://ipfs/{CID}', async function () { - const request = url2request('https://duckduckgo.com/?q=web%2Bdweb%3A%2F%2Fipfs%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3Farg%3Dfoo%26bar%3Dbuzz%23hash&ia=software') - // mv2 - // expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) - await modifyRequest.onBeforeRequest(request) - Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) - }) - it('should be normalized if web+dweb:/ipns/{foo}', async function () { - const request = url2request('https://duckduckgo.com/?q=web%2Bdweb%3A%2Fipns%2Fipfs.io%2Findex.html%3Farg%3Dfoo%26bar%3Dbuzz%23hash&ia=web') - // mv2 - // expect((await modifyRequest.onBeforeRequest(request)).redirectUrl).to.equal('https://ipfs.io/ipns/ipfs.io/index.html?arg=foo&bar=buzz#hash') - await modifyRequest.onBeforeRequest(request) - const [args] = browser.declarativeNetRequest.updateDynamicRules.firstCall.args - expect(args).to.deep.equal({ - addRules: [ - generateAddRule( - args.addRules[0].id, - `^https?\\:\\/\\/duckduckgo\\.com\\/\\?q\\=web%2Bdweb%3A%2Fipns%2Fipfs\\.io%2Findex\\.html%3Farg%3Dfoo%26bar%3Dbuzz%23hash\\&ia\\=web${groupAtEndRegex}`, - 'https://ipfs.io/ipns/ipfs.io/index.html?arg=foo&bar=buzz#hash\\1' - ) - ], - removeRuleIds: [] - }) - }) - it('should not be normalized if web+dweb://ipns/{foo}', async function () { - const request = url2request('https://duckduckgo.com/?q=web%2Bdweb%3A%2F%2Fipns%2Fipfs.io%2Findex.html%3Farg%3Dfoo%26bar%3Dbuzz%23hash&ia=web') - // mv2 - // expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) - await modifyRequest.onBeforeRequest(request) - Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) - }) - - it('should not be normalized if disabled in Preferences', async function () { - state.catchUnhandledProtocols = false - const request = url2request('https://duckduckgo.com/?q=ipfs%3A%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest&foo=bar') - // mv2 - // expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) - await modifyRequest.onBeforeRequest(request) - Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) - }) - it('should not be normalized if CID is invalid', async function () { - state.catchUnhandledProtocols = false - const request = url2request('https://duckduckgo.com/?q=ipfs%3A%2FnotARealIpfsPathWithCid%3FargTest%23hashTest&foo=bar') - // mv2 - // expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) - await modifyRequest.onBeforeRequest(request) - Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) - }) - it('should not be normalized if presence of %3A%2F is a false-positive', async function () { - state.catchUnhandledProtocols = false - const request = url2request('https://duckduckgo.com/?q=foo%3A%2Fbar%3FargTest%23hashTest&foo=bar') - // mv2 - // expect(await modifyRequest.onBeforeRequest(request)).to.equal(undefined) - await modifyRequest.onBeforeRequest(request) - Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) - }) - it('should not be normalized if request.type != main_frame', async function () { - const mediaRequest = { url: 'https://duckduckgo.com/?q=ipfs%3A%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR%3FargTest%23hashTest&foo=bar', type: 'media' } - // mv2 - // expect(await modifyRequest.onBeforeRequest(mediaRequest)).to.equal(undefined) - await modifyRequest.onBeforeRequest(mediaRequest) - Sinon.assert.notCalled(browser.declarativeNetRequest.updateDynamicRules) - }) - }) - }) - }) - - after(function () { - delete global.URL - delete global.browser - browser.flush() - }) -}) diff --git a/test/functional/lib/ipfs-request-workarounds.test.js b/test/functional/lib/ipfs-request-workarounds.test.js index ecf75840e..140ea819a 100644 --- a/test/functional/lib/ipfs-request-workarounds.test.js +++ b/test/functional/lib/ipfs-request-workarounds.test.js @@ -1,21 +1,25 @@ 'use strict' -import { describe, it, before, beforeEach, after } from 'mocha' -import { expect, assert } from 'chai' -import { URL } from 'url' // URL implementation with support for .origin attribute +import { assert, expect } from 'chai' +import { after, before, beforeEach, describe, it } from 'mocha' import browser from 'sinon-chrome' -import { initState } from '../../../add-on/src/lib/state.js' -import createRuntimeChecks from '../../../add-on/src/lib/runtime-checks.js' -import { createRequestModifier } from '../../../add-on/src/lib/ipfs-request.js' +import { URL } from 'url' // URL implementation with support for .origin attribute import createDNSLinkResolver from '../../../add-on/src/lib/dnslink.js' +import { braveNodeType } from '../../../add-on/src/lib/ipfs-client/brave.js' import { createIpfsPathValidator } from '../../../add-on/src/lib/ipfs-path.js' +import { createRequestModifier } from '../../../add-on/src/lib/ipfs-request.js' import { optionDefaults } from '../../../add-on/src/lib/options.js' -import { braveNodeType } from '../../../add-on/src/lib/ipfs-client/brave.js' +import createRuntimeChecks from '../../../add-on/src/lib/runtime-checks.js' +import { initState } from '../../../add-on/src/lib/state.js' +import isMv3TestingEnabled from '../../helpers/is-mv3-testing-enabled.js' import { spoofDnsTxtRecord } from './dnslink.test.js' describe('modifyRequest processing', function () { let state, getState, dnslinkResolver, ipfsPathValidator, modifyRequest, runtime before(function () { + if (isMv3TestingEnabled) { + return this.skip() + } global.URL = URL global.browser = browser browser.runtime.id = 'testid' diff --git a/test/functional/lib/redirect-handler/blockOrObserve.test.mv3.ts b/test/functional/lib/redirect-handler/blockOrObserve.test.mv3.ts deleted file mode 100644 index 68807064b..000000000 --- a/test/functional/lib/redirect-handler/blockOrObserve.test.mv3.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { expect } from 'chai' -import { before, describe, it } from 'mocha' -import browserMock from 'sinon-chrome' - -import { supportsBlock } from '../../../../add-on/src/lib/redirect-handler/blockOrObserve.js' - -describe('lib/redirect-handler/blockOrObserve', () => { - describe('supportsBlock', () => { - it('should return false for MV3', () => { - expect(supportsBlock()).to.be.false - }) - }) -}) diff --git a/test/functional/lib/redirect-handler/blockOrObserve.test.ts b/test/functional/lib/redirect-handler/blockOrObserve.test.ts index 176e71080..e14bad8ec 100644 --- a/test/functional/lib/redirect-handler/blockOrObserve.test.ts +++ b/test/functional/lib/redirect-handler/blockOrObserve.test.ts @@ -6,6 +6,7 @@ import browserMock from 'sinon-chrome' import { optionDefaults } from '../../../../add-on/src/lib/options.js' import { addRuleToDynamicRuleSetGenerator, cleanupRules, isLocalHost, supportsBlock } from '../../../../add-on/src/lib/redirect-handler/blockOrObserve' import { initState } from '../../../../add-on/src/lib/state.js' +import isMv3TestingEnabled, { manifestVersion } from '../../../helpers/is-mv3-testing-enabled.js' import DeclarativeNetRequestMock from './declarativeNetRequest.mock.js' const dynamicRulesConditions = (regexFilter) => ({ @@ -30,6 +31,8 @@ const dynamicRulesConditions = (regexFilter) => ({ ] }) +const manifestVeresion = isMv3TestingEnabled ? 'MV3' : 'MV2' + describe('lib/redirect-handler/blockOrObserve', () => { before(function () { browserMock.runtime.id = 'testid' @@ -53,9 +56,13 @@ describe('lib/redirect-handler/blockOrObserve', () => { }) }) - describe('supportsBlock', () => { - it('should return true for MV2', () => { - expect(supportsBlock()).to.be.true + describe(`supportsBlock on ${manifestVersion}` , () => { + it(`should return ${isMv3TestingEnabled ? false : true} for ${manifestVersion}`, function () { + if (isMv3TestingEnabled) { + expect(supportsBlock()).to.be.false + } else { + expect(supportsBlock()).to.be.true + } }) }) diff --git a/test/helpers/is-mv3-testing-enabled.js b/test/helpers/is-mv3-testing-enabled.js new file mode 100644 index 000000000..30cc985c7 --- /dev/null +++ b/test/helpers/is-mv3-testing-enabled.js @@ -0,0 +1,4 @@ + +const isMv3TestingEnabled = process.env.TEST_MV3 === 'true' +export const manifestVersion = isMv3TestingEnabled ? 'MV3' : 'MV2' +export default isMv3TestingEnabled diff --git a/test/setup/mocha-setup.js b/test/setup/mocha-setup.js index 1eb01abba..30f277162 100644 --- a/test/setup/mocha-setup.js +++ b/test/setup/mocha-setup.js @@ -1,5 +1,10 @@ -import browser from 'sinon-chrome' import AbortController from 'abort-controller' +import { afterEach } from 'mocha' +import sinon, { useFakeTimers } from 'sinon' +import browser from 'sinon-chrome' +import DeclarativeNetRequestMock from '../functional/lib/redirect-handler/declarativeNetRequest.mock.js' +import isMv3TestingEnabled from '../helpers/is-mv3-testing-enabled.js' + browser.runtime.id = 'testid' global.browser = browser global.AbortController = AbortController @@ -9,3 +14,22 @@ global.navigator = { writeText: () => {} } } + +global.URL = URL +browser.tabs = { ...browser.tabs, getCurrent: sinon.stub().resolves({ id: 20 }) } + +// need to force Date to return a particular date +global.clock = useFakeTimers({ + now: new Date(2017, 10, 5, 12, 1, 1) +}) + +if (isMv3TestingEnabled) { + const sinonSandbox = sinon.createSandbox() + global.browser.declarativeNetRequest = sinonSandbox.spy(new DeclarativeNetRequestMock()) + + afterEach(function () { + sinonSandbox.resetHistory() + }) +} else { + // nothing needed here? +} diff --git a/test/setup/mocha-setup.mv3.js b/test/setup/mocha-setup.mv3.js deleted file mode 100644 index f57148a40..000000000 --- a/test/setup/mocha-setup.mv3.js +++ /dev/null @@ -1,21 +0,0 @@ -import AbortController from 'abort-controller' -import { afterEach } from 'mocha' -import sinon from 'sinon' -import browser from 'sinon-chrome' -import DeclarativeNetRequestMock from '../functional/lib/redirect-handler/declarativeNetRequest.mock.js' - -browser.runtime.id = 'testid' -global.browser = browser -global.AbortController = AbortController -global.chrome = browser -global.navigator = { - clipboard: { - writeText: () => {} - } -} -const sinonSandbox = sinon.createSandbox() -global.browser.declarativeNetRequest = sinonSandbox.spy(new DeclarativeNetRequestMock()) - -afterEach(function () { - sinonSandbox.resetHistory() -})