Skip to content

Commit

Permalink
fix: remove dead code from get-identity
Browse files Browse the repository at this point in the history
  • Loading branch information
wraithgar authored and fritzy committed May 18, 2022
1 parent 124df81 commit ee3308a
Show file tree
Hide file tree
Showing 11 changed files with 159 additions and 375 deletions.
45 changes: 15 additions & 30 deletions lib/utils/get-identity.js
@@ -1,39 +1,24 @@
const npmFetch = require('npm-registry-fetch')

const needsAuthError = (msg) =>
Object.assign(new Error(msg), { code: 'ENEEDAUTH' })

module.exports = async (npm, opts = {}) => {
module.exports = async (npm, opts) => {
const { registry } = opts
if (!registry) {
throw Object.assign(new Error('No registry specified.'), { code: 'ENOREGISTRY' })
}

// First, check if we have a user/pass-based auth
const creds = npm.config.getCredentialsByURI(registry)
const { username: usernameFromURI, token } = creds
if (creds.username) {
return creds.username
}

if (usernameFromURI) {
// Found username; return it
return usernameFromURI
} else if (token) {
// No username, but we have a token; fetch the username from registry
const registryData = await npmFetch.json('/-/whoami', {
...opts,
})
const { username: usernameFromRegistry } = registryData
// Retrieved username from registry; return it
if (usernameFromRegistry) {
return usernameFromRegistry
} else {
// Didn't get username from registry; bad token
throw needsAuthError(
'Your auth token is no longer valid. Please login again.'
)
}
} else {
// At this point, if they have a credentials object, it doesn't have a
// token or auth in it. Probably just the default registry.
throw needsAuthError('This command requires you to be logged in.')
// No username, but we have a token; fetch the username from registry
if (creds.token) {
const registryData = await npmFetch.json('/-/whoami', { ...opts })
return registryData.username
}

// At this point, even if they have a credentials object, it doesn't have a
// valid token.
throw Object.assign(
new Error('This command requires you to be logged in.'),
{ code: 'ENEEDAUTH' }
)
}
Expand Up @@ -5,7 +5,7 @@
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/lib/utils/npm-usage.js TAP usage basic usage > must match snapshot 1`] = `
exports[`test/lib/npm.js TAP usage basic usage > must match snapshot 1`] = `
npm <command>
Usage:
Expand Down Expand Up @@ -41,7 +41,7 @@ Configuration fields: npm help 7 config
npm@{VERSION} {BASEDIR}
`

exports[`test/lib/utils/npm-usage.js TAP usage set process.stdout.columns columns=0 > must match snapshot 1`] = `
exports[`test/lib/npm.js TAP usage set process.stdout.columns columns=0 > must match snapshot 1`] = `
npm <command>
Usage:
Expand Down Expand Up @@ -77,7 +77,7 @@ Configuration fields: npm help 7 config
npm@{VERSION} {BASEDIR}
`

exports[`test/lib/utils/npm-usage.js TAP usage set process.stdout.columns columns=90 > must match snapshot 1`] = `
exports[`test/lib/npm.js TAP usage set process.stdout.columns columns=90 > must match snapshot 1`] = `
npm <command>
Usage:
Expand Down Expand Up @@ -113,7 +113,7 @@ Configuration fields: npm help 7 config
npm@{VERSION} {BASEDIR}
`

exports[`test/lib/utils/npm-usage.js TAP usage with browser > must match snapshot 1`] = `
exports[`test/lib/npm.js TAP usage with browser > must match snapshot 1`] = `
npm <command>
Usage:
Expand Down Expand Up @@ -149,7 +149,7 @@ Configuration fields: npm help 7 config
npm@{VERSION} {BASEDIR}
`

exports[`test/lib/utils/npm-usage.js TAP usage with long > must match snapshot 1`] = `
exports[`test/lib/npm.js TAP usage with long > must match snapshot 1`] = `
npm <command>
Usage:
Expand Down
4 changes: 4 additions & 0 deletions test/fixtures/mock-registry.js
Expand Up @@ -192,6 +192,10 @@ class MockRegistry {
}).reply(200, { ...manifest, users })
}

ping ({ body = {}, responseCode = 200 } = {}) {
this.nock = this.nock.get('/-/ping?write=true').reply(responseCode, body)
}

async package ({ manifest, times = 1, query, tarballs }) {
let nock = this.nock
const spec = npa(manifest.name)
Expand Down
2 changes: 1 addition & 1 deletion test/lib/commands/deprecate.js
Expand Up @@ -44,7 +44,7 @@ t.test('completion', async t => {

registry.whoami({ statusCode: 404, body: {} })

t.rejects(testComp([], []), { code: 'ENEEDAUTH' })
t.rejects(testComp([], []), { code: 'EINVALIDTYPE' })
})

t.test('no args', async t => {
Expand Down
154 changes: 54 additions & 100 deletions test/lib/commands/ping.js
@@ -1,113 +1,67 @@
const t = require('tap')
const { fake: mockNpm } = require('../../fixtures/mock-npm')
const { load: loadMockNpm } = require('../../fixtures/mock-npm.js')
const MockRegistry = require('../../fixtures/mock-registry.js')

t.test('pings', async t => {
t.plan(6)

const registry = 'https://registry.npmjs.org'
let noticeCalls = 0
const Ping = t.mock('../../../lib/commands/ping.js', {
'../../../lib/utils/ping.js': function (spec) {
t.equal(spec.registry, registry, 'passes flatOptions')
return {}
},
'proc-log': {
notice: (type, spec) => {
++noticeCalls
if (noticeCalls === 1) {
t.equal(type, 'PING', 'should log a PING')
t.equal(spec, registry, 'should log the registry url')
} else {
t.equal(type, 'PONG', 'should log a PONG')
t.match(spec, /\d+ms/, 'should log the elapsed milliseconds')
}
},
},
})
const npm = mockNpm({
config: { registry },
flatOptions: { registry },
t.test('no details', async t => {
const { npm, logs, joinedOutput } = await loadMockNpm(t)
const registry = new MockRegistry({
tap: t,
registry: npm.config.get('registry'),
})
const ping = new Ping(npm)

await ping.exec([])
t.equal(noticeCalls, 2, 'should have logged 2 lines')
registry.ping()
await npm.exec('ping', [])
t.match(logs.notice, [['PING', 'https://registry.npmjs.org/'], ['PONG', /[0-9]+ms/]])
t.equal(joinedOutput(), '')
})

t.test('pings and logs details', async t => {
t.plan(8)
t.test('with details', async t => {
const { npm, logs, joinedOutput } = await loadMockNpm(t)
const registry = new MockRegistry({
tap: t,
registry: npm.config.get('registry'),
})
registry.ping({ body: { test: true } })
await npm.exec('ping', [])
t.match(logs.notice, [
['PING', 'https://registry.npmjs.org/'],
['PONG', /[0-9]+ms/],
['PONG', '{\n "test": true\n}'],
])
t.match(joinedOutput(), '')
})

const registry = 'https://registry.npmjs.org'
const details = { extra: 'data' }
let noticeCalls = 0
const Ping = t.mock('../../../lib/commands/ping.js', {
'../../../lib/utils/ping.js': function (spec) {
t.equal(spec.registry, registry, 'passes flatOptions')
return details
},
'proc-log': {
notice: (type, spec) => {
++noticeCalls
if (noticeCalls === 1) {
t.equal(type, 'PING', 'should log a PING')
t.equal(spec, registry, 'should log the registry url')
} else if (noticeCalls === 2) {
t.equal(type, 'PONG', 'should log a PONG')
t.match(spec, /\d+ms/, 'should log the elapsed milliseconds')
} else {
t.equal(type, 'PONG', 'should log a PONG')
const parsed = JSON.parse(spec)
t.match(parsed, details, 'should log JSON stringified details')
}
},
},
t.test('valid json', async t => {
const { npm, logs, joinedOutput } = await loadMockNpm(t, {
config: { json: true },
})
const npm = mockNpm({
config: { registry },
flatOptions: { registry },
const registry = new MockRegistry({
tap: t,
registry: npm.config.get('registry'),
})
registry.ping()
await npm.exec('ping', [])
t.match(logs.notice, [['PING', 'https://registry.npmjs.org/'], ['PONG', /[0-9]+ms/]])
t.match(JSON.parse(joinedOutput()), {
registry: npm.config.get('registry'),
time: /[0-9]+/,
details: {},
})
const ping = new Ping(npm)

await ping.exec([])
t.equal(noticeCalls, 3, 'should have logged 3 lines')
})

t.test('pings and returns json', async t => {
t.plan(9)

const registry = 'https://registry.npmjs.org'
const details = { extra: 'data' }
let noticeCalls = 0
const Ping = t.mock('../../../lib/commands/ping.js', {
'../../../lib/utils/ping.js': function (spec) {
t.equal(spec.registry, registry, 'passes flatOptions')
return details
},
'proc-log': {
notice: (type, spec) => {
++noticeCalls
if (noticeCalls === 1) {
t.equal(type, 'PING', 'should log a PING')
t.equal(spec, registry, 'should log the registry url')
} else {
t.equal(type, 'PONG', 'should log a PONG')
t.match(spec, /\d+ms/, 'should log the elapsed milliseconds')
}
},
},
t.test('invalid json', async t => {
const { npm, logs, joinedOutput } = await loadMockNpm(t, {
config: { json: true },
})
const npm = mockNpm({
config: { registry, json: true },
flatOptions: { registry },
output: function (spec) {
const parsed = JSON.parse(spec)
t.equal(parsed.registry, registry, 'returns the correct registry url')
t.match(parsed.details, details, 'prints returned details')
t.type(parsed.time, 'number', 'returns time as a number')
},
const registry = new MockRegistry({
tap: t,
registry: npm.config.get('registry'),
})
registry.ping({ body: '{not: real"json]' })
await npm.exec('ping', [])
t.match(logs.notice, [['PING', 'https://registry.npmjs.org/'], ['PONG', /[0-9]+ms/]])
t.match(JSON.parse(joinedOutput()), {
registry: npm.config.get('registry'),
time: /[0-9]+/,
details: {},
})
const ping = new Ping(npm)

await ping.exec([])
t.equal(noticeCalls, 2, 'should have logged 2 lines')
})
24 changes: 22 additions & 2 deletions test/lib/commands/whoami.js
Expand Up @@ -5,7 +5,7 @@ const MockRegistry = require('../../fixtures/mock-registry.js')
const username = 'foo'
const auth = { '//registry.npmjs.org/:_authToken': 'test-auth-token' }

t.test('npm whoami', async (t) => {
t.test('npm whoami', async t => {
const { npm, joinedOutput } = await loadMockNpm(t, { config: auth })
const registry = new MockRegistry({
tap: t,
Expand All @@ -17,7 +17,7 @@ t.test('npm whoami', async (t) => {
t.equal(joinedOutput(), username, 'should print username')
})

t.test('npm whoami --json', async (t) => {
t.test('npm whoami --json', async t => {
const { npm, joinedOutput } = await loadMockNpm(t, {
config: {
json: true,
Expand All @@ -33,3 +33,23 @@ t.test('npm whoami --json', async (t) => {
await npm.exec('whoami', [])
t.equal(JSON.parse(joinedOutput()), username, 'should print username')
})

t.test('credentials from token', async t => {
const { npm, joinedOutput } = await loadMockNpm(t, {
config: {
'//registry.npmjs.org/:username': username,
'//registry.npmjs.org/:_password': 'hunter2',
},
})
await npm.exec('whoami', [])
t.equal(joinedOutput(), username, 'should print username')
})

t.test('not logged in', async t => {
const { npm } = await loadMockNpm(t, {
config: {
json: true,
},
})
await t.rejects(npm.exec('whoami', []), { code: 'ENEEDAUTH' })
})
58 changes: 58 additions & 0 deletions test/lib/npm.js
Expand Up @@ -654,3 +654,61 @@ t.test('implicit workspace accept', async t => {
})
await t.rejects(mock.npm.exec('org', []), /.*Usage/)
})

t.test('usage', async t => {
const { npm } = await loadMockNpm(t)
t.afterEach(() => {
npm.config.set('viewer', null)
npm.config.set('long', false)
npm.config.set('userconfig', '/some/config/file/.npmrc')
})
const { dirname } = require('path')
const basedir = dirname(dirname(__dirname))
t.cleanSnapshot = str => str.split(basedir).join('{BASEDIR}')
.split(require('../../package.json').version).join('{VERSION}')

npm.config.set('viewer', null)
npm.config.set('long', false)
npm.config.set('userconfig', '/some/config/file/.npmrc')

t.test('basic usage', async t => {
t.matchSnapshot(await npm.usage)
t.end()
})

t.test('with browser', async t => {
npm.config.set('viewer', 'browser')
t.matchSnapshot(await npm.usage)
t.end()
})

t.test('with long', async t => {
npm.config.set('long', true)
t.matchSnapshot(await npm.usage)
t.end()
})

t.test('set process.stdout.columns', async t => {
const { columns } = process.stdout
t.teardown(() => {
Object.defineProperty(process.stdout, 'columns', {
value: columns,
enumerable: true,
configurable: true,
writable: true,
})
})
const cases = [0, 90]
for (const cols of cases) {
t.test(`columns=${cols}`, async t => {
Object.defineProperty(process.stdout, 'columns', {
value: cols,
enumerable: true,
configurable: true,
writable: true,
})
t.matchSnapshot(await npm.usage)
})
}
})
})

0 comments on commit ee3308a

Please sign in to comment.