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