@@ -6,6 +6,7 @@ import { once } from 'node:events'
6
6
import {
7
7
COORDINATOR_ROLE_ID ,
8
8
CREATOR_ROLE ,
9
+ CREATOR_ROLE_ID ,
9
10
ROLES ,
10
11
MEMBER_ROLE_ID ,
11
12
NO_ROLE ,
@@ -18,6 +19,8 @@ import {
18
19
waitForSync ,
19
20
} from './utils.js'
20
21
import { kDataTypes } from '../src/mapeo-project.js'
22
+ /** @import { MapeoProject } from '../src/mapeo-project.js' */
23
+ /** @import { RoleId } from '../src/roles.js' */
21
24
22
25
test ( 'getting yourself after creating project' , async ( t ) => {
23
26
const [ manager ] = await createManagers ( 1 , t , 'tablet' )
@@ -355,8 +358,8 @@ test('roles - getMany() on newly invited device before sync', async (t) => {
355
358
} )
356
359
357
360
test ( 'roles - assignRole()' , async ( t ) => {
358
- const managers = await createManagers ( 2 , t )
359
- const [ invitor , invitee ] = managers
361
+ const managers = await createManagers ( 3 , t )
362
+ const [ invitor , invitee , invitee2 ] = managers
360
363
const disconnectPeers = connectPeers ( managers )
361
364
t . after ( disconnectPeers )
362
365
@@ -365,21 +368,48 @@ test('roles - assignRole()', async (t) => {
365
368
await invite ( {
366
369
invitor,
367
370
projectId,
368
- invitees : [ invitee ] ,
371
+ invitees : [ invitee , invitee2 ] ,
369
372
roleId : MEMBER_ROLE_ID ,
370
373
} )
371
374
372
375
const projects = await Promise . all (
373
376
managers . map ( ( m ) => m . getProject ( projectId ) )
374
377
)
375
378
376
- const [ invitorProject , inviteeProject ] = projects
379
+ const [ invitorProject , inviteeProject , invitee2Project ] = projects
380
+
381
+ /**
382
+ * @param {MapeoProject } project
383
+ * @param {string } otherDeviceId
384
+ * @param {RoleId } expectedRoleId
385
+ * @param {string } message
386
+ * @returns {Promise<void> }
387
+ */
388
+ const assertRole = async (
389
+ project ,
390
+ otherDeviceId ,
391
+ expectedRoleId ,
392
+ message
393
+ ) => {
394
+ assert . equal (
395
+ ( await project . $member . getById ( otherDeviceId ) ) . role . roleId ,
396
+ expectedRoleId ,
397
+ message
398
+ )
399
+ }
377
400
378
- assert . deepEqual (
379
- ( await invitorProject . $member . getById ( invitee . deviceId ) ) . role ,
380
- ROLES [ MEMBER_ROLE_ID ] ,
401
+ await assertRole (
402
+ invitorProject ,
403
+ invitee . deviceId ,
404
+ MEMBER_ROLE_ID ,
381
405
'invitee has member role from invitor perspective'
382
406
)
407
+ await assertRole (
408
+ invitorProject ,
409
+ invitee2 . deviceId ,
410
+ MEMBER_ROLE_ID ,
411
+ 'invitee 2 has member role from invitor perspective'
412
+ )
383
413
384
414
assert . deepEqual (
385
415
await inviteeProject . $getOwnRole ( ) ,
@@ -410,9 +440,10 @@ test('roles - assignRole()', async (t) => {
410
440
411
441
await waitForSync ( projects , 'initial' )
412
442
413
- assert . deepEqual (
414
- ( await invitorProject . $member . getById ( invitee . deviceId ) ) . role ,
415
- ROLES [ COORDINATOR_ROLE_ID ] ,
443
+ await assertRole (
444
+ invitorProject ,
445
+ invitee . deviceId ,
446
+ COORDINATOR_ROLE_ID ,
416
447
'invitee now has coordinator role from invitor perspective'
417
448
)
418
449
@@ -447,9 +478,10 @@ test('roles - assignRole()', async (t) => {
447
478
448
479
await waitForSync ( projects , 'initial' )
449
480
450
- assert . deepEqual (
451
- ( await invitorProject . $member . getById ( invitee . deviceId ) ) . role ,
452
- ROLES [ MEMBER_ROLE_ID ] ,
481
+ await assertRole (
482
+ invitorProject ,
483
+ invitee . deviceId ,
484
+ MEMBER_ROLE_ID ,
453
485
'invitee now has member role from invitor perspective'
454
486
)
455
487
@@ -459,6 +491,84 @@ test('roles - assignRole()', async (t) => {
459
491
'invitee now has member role from invitee perspective'
460
492
)
461
493
} )
494
+
495
+ await t . test (
496
+ 'regular members cannot assign roles to coordinator' ,
497
+ async ( ) => {
498
+ await Promise . all (
499
+ [ invitorProject , inviteeProject , invitee2Project ] . flatMap ( ( project ) => [
500
+ assertRole (
501
+ project ,
502
+ invitee . deviceId ,
503
+ MEMBER_ROLE_ID ,
504
+ 'test setup: everyone believes invitee 1 is a regular member'
505
+ ) ,
506
+ assertRole (
507
+ project ,
508
+ invitee2 . deviceId ,
509
+ MEMBER_ROLE_ID ,
510
+ 'test setup: everyone believes invitee 2 is a regular member'
511
+ ) ,
512
+ ] )
513
+ )
514
+
515
+ await assert . rejects ( ( ) =>
516
+ inviteeProject . $member . assignRole ( invitee . deviceId , COORDINATOR_ROLE_ID )
517
+ )
518
+ await assert . rejects ( ( ) =>
519
+ inviteeProject . $member . assignRole (
520
+ invitee2 . deviceId ,
521
+ COORDINATOR_ROLE_ID
522
+ )
523
+ )
524
+
525
+ await waitForSync ( projects , 'initial' )
526
+
527
+ await Promise . all (
528
+ [ invitorProject , inviteeProject , invitee2Project ] . flatMap ( ( project ) => [
529
+ assertRole (
530
+ project ,
531
+ invitee . deviceId ,
532
+ MEMBER_ROLE_ID ,
533
+ 'everyone believes invitee 1 is a regular member, even after attempting to assign higher role'
534
+ ) ,
535
+ assertRole (
536
+ project ,
537
+ invitee2 . deviceId ,
538
+ MEMBER_ROLE_ID ,
539
+ 'everyone believes invitee 2 is a regular member, even after attempting to assign higher role'
540
+ ) ,
541
+ ] )
542
+ )
543
+ }
544
+ )
545
+
546
+ await t . test (
547
+ 'non-creator members cannot change roles of creator' ,
548
+ async ( ) => {
549
+ await invitorProject . $member . assignRole (
550
+ invitee . deviceId ,
551
+ COORDINATOR_ROLE_ID
552
+ )
553
+ await waitForSync ( projects , 'initial' )
554
+
555
+ await assert . rejects ( ( ) =>
556
+ inviteeProject . $member . assignRole ( invitor . deviceId , COORDINATOR_ROLE_ID )
557
+ )
558
+
559
+ await waitForSync ( projects , 'initial' )
560
+ await Promise . all (
561
+ [ invitorProject , inviteeProject , invitee2Project ] . map ( ( project ) =>
562
+ assertRole (
563
+ project ,
564
+ invitor . deviceId ,
565
+ CREATOR_ROLE_ID ,
566
+ 'everyone still believes creator to be a creator'
567
+ )
568
+ )
569
+ )
570
+ }
571
+ )
462
572
} )
463
573
464
574
test ( 'roles - assignRole() with forked role' , async ( t ) => {
0 commit comments