xref: /third_party/node/deps/npm/test/lib/commands/team.js (revision 1cb0ef41)
1const t = require('tap')
2const mockNpm = require('../../fixtures/mock-npm')
3
4t.cleanSnapshot = s => s.trim().replace(/\n+/g, '\n')
5
6const mockTeam = async (t, { libnpmteam, ...opts } = {}) => {
7  const mock = await mockNpm(t, {
8    ...opts,
9    command: 'team',
10    mocks: {
11      // XXX: this should be refactored to use the mock registry
12      libnpmteam: libnpmteam || {
13        async add () {},
14        async create () {},
15        async destroy () {},
16        async lsTeams () {},
17        async lsUsers () {},
18        async rm () {},
19      },
20    },
21  })
22
23  return {
24    ...mock,
25    result: () => mock.joinedOutput(),
26  }
27}
28
29t.test('no args', async t => {
30  const { team } = await mockTeam(t)
31  await t.rejects(
32    team.exec([]),
33    'usage instructions',
34    'should throw usage instructions'
35  )
36})
37
38t.test('team add <scope:team> <user>', async t => {
39  t.test('default output', async t => {
40    const { team, result } = await mockTeam(t)
41
42    await team.exec(['add', '@npmcli:developers', 'foo'])
43
44    t.matchSnapshot(result(), 'should output success result for add user')
45  })
46
47  t.test('--parseable', async t => {
48    const { team, result } = await mockTeam(t, {
49      config: { parseable: true },
50    })
51
52    await team.exec(['add', '@npmcli:developers', 'foo'])
53
54    t.matchSnapshot(
55      result(),
56      'should output success result for parseable add user'
57    )
58  })
59
60  t.test('--json', async t => {
61    const { team, result } = await mockTeam(t, {
62      config: { json: true },
63    })
64
65    await team.exec(['add', '@npmcli:developers', 'foo'])
66
67    t.same(
68      JSON.parse(result()),
69      {
70        added: true,
71        team: 'npmcli:developers',
72        user: 'foo',
73      },
74      'should output success result for add user json'
75    )
76  })
77
78  t.test('--silent', async t => {
79    const { team, result } = await mockTeam(t, {
80      config: { silent: true },
81    })
82
83    await team.exec(['add', '@npmcli:developers', 'foo'])
84
85    t.same(result(), '', 'should not output success if silent')
86  })
87})
88
89t.test('team create <scope:team>', async t => {
90  t.test('default output', async t => {
91    const { team, result } = await mockTeam(t)
92
93    await team.exec(['create', '@npmcli:newteam'])
94
95    t.matchSnapshot(result(), 'should output success result for create team')
96  })
97
98  t.test('--parseable', async t => {
99    const { team, result } = await mockTeam(t, {
100      config: { parseable: true },
101    })
102
103    await team.exec(['create', '@npmcli:newteam'])
104
105    t.matchSnapshot(
106      result(),
107      'should output parseable success result for create team'
108    )
109  })
110
111  t.test('--json', async t => {
112    const { team, result } = await mockTeam(t, {
113      config: { json: true },
114    })
115
116    await team.exec(['create', '@npmcli:newteam'])
117
118    t.same(
119      JSON.parse(result()),
120      {
121        created: true,
122        team: 'npmcli:newteam',
123      },
124      'should output success result for create team'
125    )
126  })
127
128  t.test('--silent', async t => {
129    const { team, result } = await mockTeam(t, {
130      config: { silent: true },
131    })
132
133    await team.exec(['create', '@npmcli:newteam'])
134
135    t.same(result(), '', 'should not output create success if silent')
136  })
137})
138
139t.test('team destroy <scope:team>', async t => {
140  t.test('default output', async t => {
141    const { team, result } = await mockTeam(t)
142    await team.exec(['destroy', '@npmcli:newteam'])
143    t.matchSnapshot(result(), 'should output success result for destroy team')
144  })
145
146  t.test('--parseable', async t => {
147    const { team, result } = await mockTeam(t, {
148      config: { parseable: true },
149    })
150    await team.exec(['destroy', '@npmcli:newteam'])
151    t.matchSnapshot(result(), 'should output parseable result for destroy team')
152  })
153
154  t.test('--json', async t => {
155    const { team, result } = await mockTeam(t, {
156      config: { json: true },
157    })
158    await team.exec(['destroy', '@npmcli:newteam'])
159    t.same(
160      JSON.parse(result()),
161      {
162        deleted: true,
163        team: 'npmcli:newteam',
164      },
165      'should output parseable result for destroy team'
166    )
167  })
168
169  t.test('--silent', async t => {
170    const { team, result } = await mockTeam(t, {
171      config: { silent: true },
172    })
173    await team.exec(['destroy', '@npmcli:newteam'])
174    t.same(result(), '', 'should not output destroy if silent')
175  })
176})
177
178t.test('team ls <scope>', async t => {
179  const teams = {
180    async lsTeams () {
181      return [
182        'npmcli:developers',
183        'npmcli:designers',
184        'npmcli:product',
185      ]
186    },
187  }
188
189  const noTeam = {
190    async lsTeams () {
191      return []
192    },
193  }
194
195  const singleTeam = {
196    async lsTeams () {
197      return ['npmcli:developers']
198    },
199  }
200
201  t.test('default output', async t => {
202    const { team, result } = await mockTeam(t, {
203      libnpmteam: teams,
204    })
205    await team.exec(['ls', '@npmcli'])
206    t.matchSnapshot(result(), 'should list teams for a given scope')
207  })
208
209  t.test('--parseable', async t => {
210    const { team, result } = await mockTeam(t, {
211      libnpmteam: teams,
212      config: { parseable: true },
213    })
214    await team.exec(['ls', '@npmcli'])
215    t.matchSnapshot(result(), 'should list teams for a parseable scope')
216  })
217
218  t.test('--json', async t => {
219    const { team, result } = await mockTeam(t, {
220      libnpmteam: teams,
221      config: { json: true },
222    })
223    await team.exec(['ls', '@npmcli'])
224    t.same(
225      JSON.parse(result()),
226      [
227        'npmcli:designers',
228        'npmcli:developers',
229        'npmcli:product',
230      ],
231      'should json list teams for a scope json'
232    )
233  })
234
235  t.test('--silent', async t => {
236    const { team, result } = await mockTeam(t, {
237      libnpmteam: teams,
238      config: { silent: true },
239    })
240    await team.exec(['ls', '@npmcli'])
241    t.same(result(), '', 'should not list teams if silent')
242  })
243
244  t.test('no teams', async t => {
245    const { team, result } = await mockTeam(t, {
246      libnpmteam: noTeam,
247    })
248
249    await team.exec(['ls', '@npmcli'])
250
251    t.matchSnapshot(result(), 'should list no teams for a given scope')
252  })
253
254  t.test('single team', async t => {
255    const { team, result } = await mockTeam(t, {
256      libnpmteam: singleTeam,
257    })
258
259    await team.exec(['ls', '@npmcli'])
260    t.matchSnapshot(result(), 'should list single team for a given scope')
261  })
262})
263
264t.test('team ls <scope:team>', async t => {
265  const users = {
266    async lsUsers () {
267      return ['nlf', 'ruyadorno', 'darcyclarke', 'isaacs']
268    },
269  }
270
271  const singleUser = {
272    async lsUsers () {
273      return ['foo']
274    },
275  }
276
277  const noUsers = {
278    async lsUsers () {
279      return []
280    },
281  }
282
283  t.test('default output', async t => {
284    const { team, result } = await mockTeam(t, {
285      libnpmteam: users,
286    })
287    await team.exec(['ls', '@npmcli:developers'])
288    t.matchSnapshot(result(), 'should list users for a given scope:team')
289  })
290
291  t.test('--parseable', async t => {
292    const { team, result } = await mockTeam(t, {
293      libnpmteam: users,
294      config: { parseable: true },
295    })
296    await team.exec(['ls', '@npmcli:developers'])
297    t.matchSnapshot(result(), 'should list users for a parseable scope:team')
298  })
299
300  t.test('--json', async t => {
301    const { team, result } = await mockTeam(t, {
302      libnpmteam: users,
303      config: { json: true },
304    })
305    await team.exec(['ls', '@npmcli:developers'])
306    t.same(
307      JSON.parse(result()),
308      [
309        'darcyclarke',
310        'isaacs',
311        'nlf',
312        'ruyadorno',
313      ],
314      'should list users for a scope:team json'
315    )
316  })
317
318  t.test('--silent', async t => {
319    const { team, result } = await mockTeam(t, {
320      libnpmteam: users,
321      config: { silent: true },
322    })
323    await team.exec(['ls', '@npmcli:developers'])
324    t.same(result(), '', 'should not output users if silent')
325  })
326
327  t.test('no users', async t => {
328    const { team, result } = await mockTeam(t, {
329      libnpmteam: noUsers,
330    })
331
332    await team.exec(['ls', '@npmcli:developers'])
333    t.matchSnapshot(result(), 'should list no users for a given scope')
334  })
335
336  t.test('single user', async t => {
337    const { team, result } = await mockTeam(t, {
338      libnpmteam: singleUser,
339    })
340
341    await team.exec(['ls', '@npmcli:developers'])
342    t.matchSnapshot(result(), 'should list single user for a given scope')
343  })
344})
345
346t.test('team rm <scope:team> <user>', async t => {
347  t.test('default output', async t => {
348    const { team, result } = await mockTeam(t)
349    await team.exec(['rm', '@npmcli:newteam', 'foo'])
350    t.matchSnapshot(result(), 'should output success result for remove user')
351  })
352
353  t.test('--parseable', async t => {
354    const { team, result } = await mockTeam(t, {
355      config: { parseable: true },
356    })
357    await team.exec(['rm', '@npmcli:newteam', 'foo'])
358    t.matchSnapshot(result(), 'should output parseable result for remove user')
359  })
360
361  t.test('--json', async t => {
362    const { team, result } = await mockTeam(t, {
363      config: { json: true },
364    })
365    await team.exec(['rm', '@npmcli:newteam', 'foo'])
366    t.same(
367      JSON.parse(result()),
368      {
369        removed: true,
370        team: 'npmcli:newteam',
371        user: 'foo',
372      },
373      'should output json result for remove user'
374    )
375  })
376
377  t.test('--silent', async t => {
378    const { team, result } = await mockTeam(t, {
379      config: { silent: true },
380    })
381    await team.exec(['rm', '@npmcli:newteam', 'foo'])
382    t.same(result(), '', 'should not output rm result if silent')
383  })
384})
385
386t.test('completion', async t => {
387  const { team } = await mockTeam(t)
388
389  t.test('npm team autocomplete', async t => {
390    const res = await team.completion({
391      conf: {
392        argv: {
393          remain: ['npm', 'team'],
394        },
395      },
396    })
397    t.strictSame(
398      res,
399      ['create', 'destroy', 'add', 'rm', 'ls'],
400      'should auto complete with subcommands'
401    )
402    t.end()
403  })
404
405  t.test('npm team <subcommand> autocomplete', async t => {
406    for (const subcmd of ['create', 'destroy', 'add', 'rm', 'ls']) {
407      const res = await team.completion({
408        conf: {
409          argv: {
410            remain: ['npm', 'team', subcmd],
411          },
412        },
413      })
414      t.strictSame(
415        res,
416        [],
417        `should not autocomplete ${subcmd} subcommand`
418      )
419    }
420  })
421
422  t.test('npm team unknown subcommand autocomplete', async t => {
423    t.rejects(
424      team.completion({ conf: { argv: { remain: ['npm', 'team', 'missing-subcommand'] } } }),
425      { message: 'missing-subcommand not recognized' }, 'should throw a a not recognized error'
426    )
427
428    t.end()
429  })
430
431  t.end()
432})
433