1
1
'use strict'
2
2
const { stub } = require ( 'sinon' )
3
- const { describe, it, beforeEach } = require ( 'mocha' )
3
+ const { describe, it, beforeEach, afterEach } = require ( 'mocha' )
4
4
const { expect } = require ( 'chai' )
5
5
const { URL } = require ( 'url' )
6
6
const { normalizedIpfsPath, createIpfsPathValidator } = require ( '../../../add-on/src/lib/ipfs-path' )
@@ -10,14 +10,12 @@ const { optionDefaults } = require('../../../add-on/src/lib/options')
10
10
const { spoofCachedDnslink } = require ( './dnslink.test.js' )
11
11
12
12
function spoofIpnsRecord ( ipfs , ipnsPath , value ) {
13
- if ( ipfs . name . resolve . reset ) ipfs . name . resolve . reset ( )
14
13
const resolve = stub ( ipfs . name , 'resolve' )
15
14
resolve . withArgs ( ipnsPath ) . resolves ( value )
16
15
resolve . throws ( ( arg ) => new Error ( `Unexpected stubbed call ipfs.name.resolve(${ arg } )` ) )
17
16
}
18
17
19
18
function spoofIpfsResolve ( ipfs , path , value ) {
20
- if ( ipfs . resolve . reset ) ipfs . resolve . reset ( )
21
19
const resolve = stub ( ipfs , 'resolve' )
22
20
resolve . withArgs ( path ) . resolves ( value )
23
21
resolve . throws ( ( arg ) => new Error ( `Unexpected stubbed call ipfs.resolve(${ arg } )` ) )
@@ -44,6 +42,11 @@ describe('ipfs-path.js', function () {
44
42
ipfsPathValidator = createIpfsPathValidator ( ( ) => state , ( ) => ipfs , dnslinkResolver )
45
43
} )
46
44
45
+ afterEach ( function ( ) {
46
+ if ( ipfs . name . resolve . reset ) ipfs . name . resolve . reset ( )
47
+ if ( ipfs . resolve . reset ) ipfs . resolve . reset ( )
48
+ } )
49
+
47
50
describe ( 'normalizedIpfsPath' , function ( ) {
48
51
it ( 'should detect /ipfs/ path in URL from a public gateway' , function ( ) {
49
52
const url = 'https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR/foo/bar'
@@ -338,6 +341,22 @@ describe('ipfs-path.js', function () {
338
341
spoofIpnsRecord ( ipfs , `/ipns/${ hostname } ` , ipnsPointer )
339
342
expect ( await ipfsPathValidator . resolveToImmutableIpfsPath ( url ) ) . to . equal ( ipnsPointer + '/guides/concepts/dnslink/?argTest#hashTest' )
340
343
} )
344
+ // TODO: remove when https://github.com/ipfs/js-ipfs/issues/1918 is addressed
345
+ it ( 'should resolve URL of a DNSLink website to the immutable /ipfs/ address behind mutable /ipns/ DNSLink in cache (js-ipfs fallback)' , async function ( ) {
346
+ const url = 'https://docs.ipfs.io/guides/concepts/dnslink/?argTest#hashTest'
347
+ // Use IPNS in DNSLINK to ensure resolveToImmutableIpfsPath does resursive resolv to immutable address
348
+ const dnslinkValue = '/ipns/QmRV5iNhGoxBaAcbucMAW9WtVHbeehXhAdr5CZQDhL55Xk'
349
+ const ipnsPointer = '/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR'
350
+ const { hostname } = new URL ( url )
351
+ spoofCachedDnslink ( hostname , dnslinkResolver , dnslinkValue )
352
+ // js-ipfs v0.34 does not support DNSLinks in ipfs.name.resolve: https://github.com/ipfs/js-ipfs/issues/1918
353
+ const resolve = stub ( ipfs . name , 'resolve' )
354
+ resolve . withArgs ( `/ipns/${ hostname } ` ) . throws ( new Error ( 'Non-base58 character' ) )
355
+ // until it is implemented, we have a workaround that falls back to value from dnslink
356
+ resolve . withArgs ( dnslinkValue ) . resolves ( ipnsPointer )
357
+ resolve . throws ( ( arg ) => new Error ( `Unexpected stubbed call ipfs.name.resolve(${ arg } )` ) )
358
+ expect ( await ipfsPathValidator . resolveToImmutableIpfsPath ( url ) ) . to . equal ( ipnsPointer + '/guides/concepts/dnslink/?argTest#hashTest' )
359
+ } )
341
360
it ( 'should resolve to null if input is an invalid path' , async function ( ) {
342
361
const path = '/foo/bar/?argTest#hashTest'
343
362
expect ( await ipfsPathValidator . resolveToImmutableIpfsPath ( path ) ) . to . equal ( null )
@@ -398,6 +417,24 @@ describe('ipfs-path.js', function () {
398
417
spoofIpfsResolve ( ipfs , `/ipns/docs.ipfs.io/guides/concepts/dnslink/` , `/ipfs/${ expectedCid } ` )
399
418
expect ( await ipfsPathValidator . resolveToCid ( url ) ) . to . equal ( expectedCid )
400
419
} )
420
+ // TODO: remove when https://github.com/ipfs/js-ipfs/issues/1918 is addressed
421
+ it ( 'should resolve URL of a DNSLink website if DNSLink is in cache (js-ipfs fallback)' , async function ( ) {
422
+ const url = 'https://docs.ipfs.io/guides/concepts/dnslink/?argTest#hashTest'
423
+ // Use IPNS in DNSLINK to ensure resolveToImmutableIpfsPath does resursive resolv to immutable address
424
+ const expectedCid = 'QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR'
425
+ const dnslinkValue = '/ipns/QmRV5iNhGoxBaAcbucMAW9WtVHbeehXhAdr5CZQDhL55Xk'
426
+ const { hostname } = new URL ( url )
427
+ spoofCachedDnslink ( hostname , dnslinkResolver , dnslinkValue )
428
+ // Note the DNSLink value is ignored, and /ipns/<fqdn> is passed to ipfs.resolv internally
429
+ // This ensures the latest pointer is returned, instead of stale value from DNSLink cache
430
+ // js-ipfs v0.34 does not support DNSLinks in ipfs.name.resolve: https://github.com/ipfs/js-ipfs/issues/1918
431
+ const resolve = stub ( ipfs , 'resolve' )
432
+ resolve . withArgs ( `/ipns/docs.ipfs.io/guides/concepts/dnslink/` ) . throws ( new Error ( 'resolve non-IPFS names is not implemented' ) )
433
+ // until it is implemented, we have a workaround that falls back to value from dnslink
434
+ resolve . withArgs ( '/ipns/QmRV5iNhGoxBaAcbucMAW9WtVHbeehXhAdr5CZQDhL55Xk/guides/concepts/dnslink/' ) . resolves ( `/ipfs/${ expectedCid } ` )
435
+ resolve . throws ( ( arg ) => new Error ( `Unexpected stubbed call ipfs.resolve(${ arg } )` ) )
436
+ expect ( await ipfsPathValidator . resolveToCid ( url ) ) . to . equal ( expectedCid )
437
+ } )
401
438
it ( 'should resolve to null if input is an invalid path' , async function ( ) {
402
439
const path = '/foo/bar/?argTest#hashTest'
403
440
expect ( await ipfsPathValidator . resolveToCid ( path ) ) . to . equal ( null )
0 commit comments