11cb0ef41Sopenharmony_ciconst t = require('tap') 21cb0ef41Sopenharmony_ciconst tmock = require('../../fixtures/tmock') 31cb0ef41Sopenharmony_ciconst mockNpm = require('../../fixtures/mock-npm') 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ciconst mockOpenUrl = async (t, args, { openerResult, ...config } = {}) => { 61cb0ef41Sopenharmony_ci let openerUrl = null 71cb0ef41Sopenharmony_ci let openerOpts = null 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_ci const open = async (url, options) => { 101cb0ef41Sopenharmony_ci openerUrl = url 111cb0ef41Sopenharmony_ci openerOpts = options 121cb0ef41Sopenharmony_ci if (openerResult) { 131cb0ef41Sopenharmony_ci throw openerResult 141cb0ef41Sopenharmony_ci } 151cb0ef41Sopenharmony_ci } 161cb0ef41Sopenharmony_ci 171cb0ef41Sopenharmony_ci const mock = await mockNpm(t, { config }) 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ci const openUrl = tmock(t, '{LIB}/utils/open-url.js', { 201cb0ef41Sopenharmony_ci '@npmcli/promise-spawn': { open }, 211cb0ef41Sopenharmony_ci }) 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_ci const openWithNpm = (...a) => openUrl(mock.npm, ...a) 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_ci if (args) { 261cb0ef41Sopenharmony_ci await openWithNpm(...args) 271cb0ef41Sopenharmony_ci } 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_ci return { 301cb0ef41Sopenharmony_ci ...mock, 311cb0ef41Sopenharmony_ci openUrl: openWithNpm, 321cb0ef41Sopenharmony_ci openerUrl: () => openerUrl, 331cb0ef41Sopenharmony_ci openerOpts: () => openerOpts, 341cb0ef41Sopenharmony_ci } 351cb0ef41Sopenharmony_ci} 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_cit.test('opens a url', async t => { 381cb0ef41Sopenharmony_ci const { openerUrl, openerOpts, joinedOutput } = await mockOpenUrl(t, 391cb0ef41Sopenharmony_ci ['https://www.npmjs.com', 'npm home']) 401cb0ef41Sopenharmony_ci t.equal(openerUrl(), 'https://www.npmjs.com', 'opened the given url') 411cb0ef41Sopenharmony_ci t.same(openerOpts(), { command: null }, 'passed command as null (the default)') 421cb0ef41Sopenharmony_ci t.same(joinedOutput(), '', 'printed no output') 431cb0ef41Sopenharmony_ci}) 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_cit.test('returns error for non-https url', async t => { 461cb0ef41Sopenharmony_ci const { openUrl, openerUrl, openerOpts, joinedOutput } = await mockOpenUrl(t) 471cb0ef41Sopenharmony_ci await t.rejects( 481cb0ef41Sopenharmony_ci openUrl('ftp://www.npmjs.com', 'npm home'), 491cb0ef41Sopenharmony_ci /Invalid URL/, 501cb0ef41Sopenharmony_ci 'got the correct error' 511cb0ef41Sopenharmony_ci ) 521cb0ef41Sopenharmony_ci t.equal(openerUrl(), null, 'did not open') 531cb0ef41Sopenharmony_ci t.same(openerOpts(), null, 'did not open') 541cb0ef41Sopenharmony_ci t.same(joinedOutput(), '', 'printed no output') 551cb0ef41Sopenharmony_ci}) 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_cit.test('returns error for file url', async t => { 581cb0ef41Sopenharmony_ci const { openUrl, openerUrl, openerOpts, joinedOutput } = await mockOpenUrl(t) 591cb0ef41Sopenharmony_ci await t.rejects( 601cb0ef41Sopenharmony_ci openUrl('file:///usr/local/bin/ls', 'npm home'), 611cb0ef41Sopenharmony_ci /Invalid URL/, 621cb0ef41Sopenharmony_ci 'got the correct error' 631cb0ef41Sopenharmony_ci ) 641cb0ef41Sopenharmony_ci t.equal(openerUrl(), null, 'did not open') 651cb0ef41Sopenharmony_ci t.same(openerOpts(), null, 'did not open') 661cb0ef41Sopenharmony_ci t.same(joinedOutput(), '', 'printed no output') 671cb0ef41Sopenharmony_ci}) 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_cit.test('file url allowed if explicitly asked for', async t => { 701cb0ef41Sopenharmony_ci const { openerUrl, openerOpts, joinedOutput } = await mockOpenUrl(t, 711cb0ef41Sopenharmony_ci ['file:///man/page/npm-install', 'npm home', true]) 721cb0ef41Sopenharmony_ci t.equal(openerUrl(), 'file:///man/page/npm-install', 'opened the given url') 731cb0ef41Sopenharmony_ci t.same(openerOpts(), { command: null }, 'passed command as null (the default)') 741cb0ef41Sopenharmony_ci t.same(joinedOutput(), '', 'printed no output') 751cb0ef41Sopenharmony_ci}) 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_cit.test('returns error for non-parseable url', async t => { 781cb0ef41Sopenharmony_ci const { openUrl, openerUrl, openerOpts, joinedOutput } = await mockOpenUrl(t) 791cb0ef41Sopenharmony_ci await t.rejects( 801cb0ef41Sopenharmony_ci openUrl('git+ssh://user@host:repo.git', 'npm home'), 811cb0ef41Sopenharmony_ci /Invalid URL/, 821cb0ef41Sopenharmony_ci 'got the correct error' 831cb0ef41Sopenharmony_ci ) 841cb0ef41Sopenharmony_ci t.equal(openerUrl(), null, 'did not open') 851cb0ef41Sopenharmony_ci t.same(openerOpts(), null, 'did not open') 861cb0ef41Sopenharmony_ci t.same(joinedOutput(), '', 'printed no output') 871cb0ef41Sopenharmony_ci}) 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_cit.test('encodes non-URL-safe characters in url provided', async t => { 901cb0ef41Sopenharmony_ci const { openerUrl, openerOpts, joinedOutput } = await mockOpenUrl(t, 911cb0ef41Sopenharmony_ci ['https://www.npmjs.com/|cat', 'npm home']) 921cb0ef41Sopenharmony_ci t.equal(openerUrl(), 'https://www.npmjs.com/%7Ccat', 'opened the encoded url') 931cb0ef41Sopenharmony_ci t.same(openerOpts(), { command: null }, 'passed command as null (the default)') 941cb0ef41Sopenharmony_ci t.same(joinedOutput(), '', 'printed no output') 951cb0ef41Sopenharmony_ci}) 961cb0ef41Sopenharmony_ci 971cb0ef41Sopenharmony_cit.test('opens a url with the given browser', async t => { 981cb0ef41Sopenharmony_ci const { openerUrl, openerOpts, joinedOutput } = await mockOpenUrl(t, 991cb0ef41Sopenharmony_ci ['https://www.npmjs.com', 'npm home'], { browser: 'chrome' }) 1001cb0ef41Sopenharmony_ci t.equal(openerUrl(), 'https://www.npmjs.com', 'opened the given url') 1011cb0ef41Sopenharmony_ci // FIXME: browser string is parsed as a boolean in config layer 1021cb0ef41Sopenharmony_ci // this is a bug that should be fixed or the config should not allow it 1031cb0ef41Sopenharmony_ci t.same(openerOpts(), { command: null }, 'passed the given browser as command') 1041cb0ef41Sopenharmony_ci t.same(joinedOutput(), '', 'printed no output') 1051cb0ef41Sopenharmony_ci}) 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_cit.test('prints where to go when browser is disabled', async t => { 1081cb0ef41Sopenharmony_ci const { openerUrl, openerOpts, joinedOutput } = await mockOpenUrl(t, 1091cb0ef41Sopenharmony_ci ['https://www.npmjs.com', 'npm home'], { browser: false }) 1101cb0ef41Sopenharmony_ci t.equal(openerUrl(), null, 'did not open') 1111cb0ef41Sopenharmony_ci t.same(openerOpts(), null, 'did not open') 1121cb0ef41Sopenharmony_ci t.matchSnapshot(joinedOutput(), 'printed expected message') 1131cb0ef41Sopenharmony_ci}) 1141cb0ef41Sopenharmony_ci 1151cb0ef41Sopenharmony_cit.test('prints where to go when browser is disabled and json is enabled', async t => { 1161cb0ef41Sopenharmony_ci const { openerUrl, openerOpts, joinedOutput } = await mockOpenUrl(t, 1171cb0ef41Sopenharmony_ci ['https://www.npmjs.com', 'npm home'], { browser: false, json: true }) 1181cb0ef41Sopenharmony_ci t.equal(openerUrl(), null, 'did not open') 1191cb0ef41Sopenharmony_ci t.same(openerOpts(), null, 'did not open') 1201cb0ef41Sopenharmony_ci t.matchSnapshot(joinedOutput(), 'printed expected message') 1211cb0ef41Sopenharmony_ci}) 1221cb0ef41Sopenharmony_ci 1231cb0ef41Sopenharmony_cit.test('prints where to go when given browser does not exist', async t => { 1241cb0ef41Sopenharmony_ci const { openerUrl, openerOpts, joinedOutput } = await mockOpenUrl(t, 1251cb0ef41Sopenharmony_ci ['https://www.npmjs.com', 'npm home'], 1261cb0ef41Sopenharmony_ci { 1271cb0ef41Sopenharmony_ci openerResult: Object.assign(new Error('failed'), { code: 127 }), 1281cb0ef41Sopenharmony_ci } 1291cb0ef41Sopenharmony_ci ) 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ci t.equal(openerUrl(), 'https://www.npmjs.com', 'tried to open the correct url') 1321cb0ef41Sopenharmony_ci t.same(openerOpts(), { command: null }, 'tried to use the correct browser') 1331cb0ef41Sopenharmony_ci t.matchSnapshot(joinedOutput(), 'printed expected message') 1341cb0ef41Sopenharmony_ci}) 1351cb0ef41Sopenharmony_ci 1361cb0ef41Sopenharmony_cit.test('handles unknown opener error', async t => { 1371cb0ef41Sopenharmony_ci const { openUrl } = await mockOpenUrl(t, null, { 1381cb0ef41Sopenharmony_ci browser: 'firefox', 1391cb0ef41Sopenharmony_ci openerResult: Object.assign(new Error('failed'), { code: 'ENOBRIAN' }), 1401cb0ef41Sopenharmony_ci }) 1411cb0ef41Sopenharmony_ci 1421cb0ef41Sopenharmony_ci await t.rejects(openUrl('https://www.npmjs.com', 'npm home'), 'failed', 'got the correct error') 1431cb0ef41Sopenharmony_ci}) 144