1const t = require('tap')
2const realFetch = require('npm-registry-fetch')
3const mockNpm = require('../../fixtures/mock-npm')
4
5const noop = () => {}
6
7const mockStars = async (t, { npmFetch = noop, exec = true, ...opts }) => {
8  const mock = await mockNpm(t, {
9    command: 'stars',
10    exec,
11    mocks: {
12      'npm-registry-fetch': Object.assign(noop, realFetch, { json: npmFetch }),
13      '{LIB}/utils/get-identity.js': async () => 'foo',
14    },
15    ...opts,
16  })
17
18  return {
19    ...mock,
20    result: mock.stars.output,
21    logs: () => mock.logs.filter(l => l[1] === 'stars').map(l => l[2]),
22  }
23}
24
25t.test('no args', async t => {
26  t.plan(3)
27
28  const npmFetch = async (uri, opts) => {
29    t.equal(uri, '/-/_view/starredByUser', 'should fetch from expected uri')
30    t.equal(opts.query.key, '"foo"', 'should match logged in username')
31
32    return {
33      rows: [
34        { value: '@npmcli/arborist' },
35        { value: '@npmcli/map-workspaces' },
36        { value: 'libnpmfund' },
37        { value: 'libnpmpublish' },
38        { value: 'ipt' },
39      ],
40    }
41  }
42
43  const { result } = await mockStars(t, { npmFetch })
44
45  t.matchSnapshot(
46    result,
47    'should output a list of starred packages'
48  )
49})
50
51t.test('npm star <user>', async t => {
52  t.plan(3)
53
54  const npmFetch = async (uri, opts) => {
55    t.equal(uri, '/-/_view/starredByUser', 'should fetch from expected uri')
56    t.equal(opts.query.key, '"ruyadorno"', 'should match username')
57
58    return {
59      rows: [{ value: '@npmcli/arborist' }],
60    }
61  }
62
63  const { result } = await mockStars(t, { npmFetch, exec: ['ruyadorno'] })
64
65  t.match(
66    result,
67    '@npmcli/arborist',
68    'should output expected list of starred packages'
69  )
70})
71
72t.test('unauthorized request', async t => {
73  const npmFetch = async () => {
74    throw Object.assign(
75      new Error('Not logged in'),
76      { code: 'ENEEDAUTH' }
77    )
78  }
79
80  const { joinedOutput, stars, logs } = await mockStars(t, { npmFetch, exec: false })
81
82  await t.rejects(
83    stars.exec([]),
84    /Not logged in/,
85    'should throw unauthorized request msg'
86  )
87
88  t.strictSame(
89    logs(),
90    ['auth is required to look up your username'],
91    'should warn auth required msg'
92  )
93
94  t.equal(
95    joinedOutput(),
96    '',
97    'should have empty output'
98  )
99})
100
101t.test('unexpected error', async t => {
102  const npmFetch = async () => {
103    throw new Error('ERROR')
104  }
105
106  const { stars, logs } = await mockStars(t, { npmFetch, exec: false })
107
108  await t.rejects(
109    stars.exec([]),
110    /ERROR/,
111    'should throw unexpected error message'
112  )
113
114  t.strictSame(logs(), [], 'no logs')
115})
116
117t.test('no pkg starred', async t => {
118  const npmFetch = async () => ({ rows: [] })
119
120  const { logs } = await mockStars(t, { npmFetch })
121
122  t.strictSame(
123    logs(),
124    ['user has not starred any packages'],
125    'should warn no starred packages msg'
126  )
127})
128