• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1const t = require('tap')
2const fs = require('fs/promises')
3const npmFetch = require('npm-registry-fetch')
4const mockNpm = require('../../fixtures/mock-npm')
5const { join } = require('path')
6
7const mockLogout = async (t, { userRc = [], ...npmOpts } = {}) => {
8  let result = null
9
10  const mock = await mockNpm(t, {
11    command: 'logout',
12    mocks: {
13      // XXX: refactor to use mock registry
14      'npm-registry-fetch': Object.assign(async (url, opts) => {
15        result = { url, opts }
16      }, npmFetch),
17    },
18    ...npmOpts,
19    homeDir: {
20      '.npmrc': userRc.join('\n'),
21    },
22  })
23
24  return {
25    ...mock,
26    result: () => result,
27    // get only the message portion of the verbose log from the command
28    logMsg: () => mock.logs.verbose.find(l => l[0] === 'logout')[1],
29    userRc: () => fs.readFile(join(mock.home, '.npmrc'), 'utf-8').then(r => r.trim()),
30  }
31}
32
33t.test('token logout', async t => {
34  const { logout, logMsg, result, userRc } = await mockLogout(t, {
35    userRc: [
36      '//registry.npmjs.org/:_authToken=@foo/',
37      'other-config=true',
38    ],
39  })
40
41  await logout.exec([])
42
43  t.equal(
44    logMsg(),
45    'clearing token for https://registry.npmjs.org/',
46    'should log message with correct registry'
47  )
48
49  t.match(
50    result(),
51    {
52      url: '/-/user/token/%40foo%2F',
53      opts: {
54        registry: 'https://registry.npmjs.org/',
55        scope: '',
56        '//registry.npmjs.org/:_authToken': '@foo/',
57        method: 'DELETE',
58        ignoreBody: true,
59      },
60    },
61    'should call npm-registry-fetch with expected values'
62  )
63
64  t.equal(await userRc(), 'other-config=true')
65})
66
67t.test('token scoped logout', async t => {
68  const { logout, logMsg, result, userRc } = await mockLogout(t, {
69    config: { scope: '@myscope' },
70    userRc: [
71      '//diff-registry.npmjs.com/:_authToken=@bar/',
72      '//registry.npmjs.org/:_authToken=@foo/',
73      '@myscope:registry=https://diff-registry.npmjs.com/',
74    ],
75  })
76
77  await logout.exec([])
78
79  t.equal(
80    logMsg(),
81    'clearing token for https://diff-registry.npmjs.com/',
82    'should log message with correct registry'
83  )
84
85  t.match(
86    result(),
87    {
88      url: '/-/user/token/%40bar%2F',
89      opts: {
90        registry: 'https://registry.npmjs.org/',
91        '@myscope:registry': 'https://diff-registry.npmjs.com/',
92        scope: '@myscope',
93        '//registry.npmjs.org/:_authToken': '@foo/', // <- removed by npm-registry-fetch
94        '//diff-registry.npmjs.com/:_authToken': '@bar/',
95        method: 'DELETE',
96        ignoreBody: true,
97      },
98    },
99    'should call npm-registry-fetch with expected values'
100  )
101
102  t.equal(await userRc(), '//registry.npmjs.org/:_authToken=@foo/')
103})
104
105t.test('user/pass logout', async t => {
106  const { logout, logMsg, userRc } = await mockLogout(t, {
107    userRc: [
108      '//registry.npmjs.org/:username=foo',
109      '//registry.npmjs.org/:_password=bar',
110      'other-config=true',
111    ],
112  })
113
114  await logout.exec([])
115
116  t.equal(
117    logMsg(),
118    'clearing user credentials for https://registry.npmjs.org/',
119    'should log message with correct registry'
120  )
121
122  t.equal(await userRc(), 'other-config=true')
123})
124
125t.test('missing credentials', async t => {
126  const { logout } = await mockLogout(t)
127
128  await t.rejects(
129    logout.exec([]),
130    {
131      code: 'ENEEDAUTH',
132      message: /not logged in to https:\/\/registry.npmjs.org\/, so can't log out!/,
133    },
134    'should throw with expected error code'
135  )
136})
137
138t.test('ignore invalid scoped registry config', async t => {
139  const { logout, logMsg, result, userRc } = await mockLogout(t, {
140    config: { scope: '@myscope' },
141    userRc: [
142      '//registry.npmjs.org/:_authToken=@foo/',
143      'other-config=true',
144    ],
145  })
146
147  await logout.exec([])
148
149  t.equal(
150    logMsg(),
151    'clearing token for https://registry.npmjs.org/',
152    'should log message with correct registry'
153  )
154
155  t.match(
156    result(),
157    {
158      url: '/-/user/token/%40foo%2F',
159      opts: {
160        '//registry.npmjs.org/:_authToken': '@foo/',
161        registry: 'https://registry.npmjs.org/',
162        method: 'DELETE',
163        ignoreBody: true,
164      },
165    },
166    'should call npm-registry-fetch with expected values'
167  )
168
169  t.equal(await userRc(), 'other-config=true')
170})
171