@@ -258,7 +258,7 @@ describe('.createApiServer', () => {
258258 } ) ;
259259 response = await request ( app . callback ( ) )
260260 . post ( '/games/foo/1/join' )
261- . send ( ' playerID=0& playerName= alice') ;
261+ . send ( { playerID : 0 , playerName : ' alice', data : 99 } ) ;
262262 } ) ;
263263
264264 test ( 'is successful' , async ( ) => {
@@ -281,6 +281,18 @@ describe('.createApiServer', () => {
281281 } )
282282 ) ;
283283 } ) ;
284+ test ( 'updates the player data' , async ( ) => {
285+ expect ( db . mocks . setMetadata ) . toHaveBeenCalledWith (
286+ '1' ,
287+ expect . objectContaining ( {
288+ players : expect . objectContaining ( {
289+ '0' : expect . objectContaining ( {
290+ data : 99 ,
291+ } ) ,
292+ } ) ,
293+ } )
294+ ) ;
295+ } ) ;
284296 } ) ;
285297
286298 describe ( 'when the playerID does not exist' , ( ) => {
@@ -353,7 +365,7 @@ describe('.createApiServer', () => {
353365 } ) ;
354366 } ) ;
355367
356- describe ( 'rename' , ( ) => {
368+ describe ( 'rename with deprecated endpoint ' , ( ) => {
357369 let response ;
358370 let db ;
359371 let games ;
@@ -407,6 +419,18 @@ describe('.createApiServer', () => {
407419 . send ( 'playerID=0&credentials=SECRET1&newName=ali' ) ;
408420 } ) ;
409421
422+ describe ( 'when the playerName is not a string' , ( ) => {
423+ test ( 'throws newName must be a string' , async ( ) => {
424+ const app = createApiServer ( { db, games } ) ;
425+ response = await request ( app . callback ( ) )
426+ . post ( '/games/foo/1/rename' )
427+ . send ( { playerID : 0 , credentials : 'SECRET1' , newName : 2 } ) ;
428+ expect ( response . text ) . toEqual (
429+ 'newName must be a string, got number'
430+ ) ;
431+ } ) ;
432+ } ) ;
433+
410434 test ( 'is successful' , async ( ) => {
411435 expect ( response . status ) . toEqual ( 200 ) ;
412436 } ) ;
@@ -472,6 +496,268 @@ describe('.createApiServer', () => {
472496 } ) ;
473497 } ) ;
474498
499+ describe ( 'rename with update endpoint' , ( ) => {
500+ let response ;
501+ let db ;
502+ let games ;
503+
504+ beforeEach ( ( ) => {
505+ games = [ ProcessGameConfig ( { name : 'foo' } ) ] ;
506+ } ) ;
507+
508+ describe ( 'for an unprotected lobby' , ( ) => {
509+ beforeEach ( ( ) => {
510+ delete process . env . API_SECRET ;
511+ } ) ;
512+
513+ describe ( 'when the game does not exist' , ( ) => {
514+ test ( 'throws game not found' , async ( ) => {
515+ db = new AsyncStorage ( {
516+ fetch : async ( ) => ( { metadata : null } ) ,
517+ } ) ;
518+ const app = createApiServer ( { db, games } ) ;
519+ response = await request ( app . callback ( ) )
520+ . post ( '/games/foo/1/update' )
521+ . send ( 'playerID=0&playerName=alice&newName=ali' ) ;
522+ expect ( response . text ) . toEqual ( 'Game 1 not found' ) ;
523+ } ) ;
524+ } ) ;
525+
526+ describe ( 'when the game does exist' , ( ) => {
527+ describe ( 'when the playerID does exist' , ( ) => {
528+ beforeEach ( async ( ) => {
529+ db = new AsyncStorage ( {
530+ fetch : async ( ) => {
531+ return {
532+ metadata : {
533+ players : {
534+ '0' : {
535+ name : 'alice' ,
536+ credentials : 'SECRET1' ,
537+ } ,
538+ '1' : {
539+ name : 'bob' ,
540+ credentials : 'SECRET2' ,
541+ } ,
542+ } ,
543+ } ,
544+ } ;
545+ } ,
546+ } ) ;
547+ const app = createApiServer ( { db, games } ) ;
548+ response = await request ( app . callback ( ) )
549+ . post ( '/games/foo/1/update' )
550+ . send ( 'playerID=0&credentials=SECRET1&newName=ali' ) ;
551+ } ) ;
552+
553+ describe ( 'when the playerName is not a string' , ( ) => {
554+ test ( 'throws newName must be a string' , async ( ) => {
555+ const app = createApiServer ( { db, games } ) ;
556+ response = await request ( app . callback ( ) )
557+ . post ( '/games/foo/1/update' )
558+ . send ( { playerID : 0 , credentials : 'SECRET1' , newName : 2 } ) ;
559+ expect ( response . text ) . toEqual (
560+ 'newName must be a string, got number'
561+ ) ;
562+ } ) ;
563+ } ) ;
564+
565+ test ( 'is successful' , async ( ) => {
566+ expect ( response . status ) . toEqual ( 200 ) ;
567+ } ) ;
568+
569+ test ( 'updates the players' , async ( ) => {
570+ expect ( db . mocks . setMetadata ) . toHaveBeenCalledWith (
571+ '1' ,
572+ expect . objectContaining ( {
573+ players : expect . objectContaining ( {
574+ '0' : expect . objectContaining ( {
575+ name : 'ali' ,
576+ } ) ,
577+ } ) ,
578+ } )
579+ ) ;
580+ } ) ;
581+ } ) ;
582+
583+ describe ( 'when the playerID does not exist' , ( ) => {
584+ test ( 'throws player not found' , async ( ) => {
585+ const app = createApiServer ( { db, games } ) ;
586+ response = await request ( app . callback ( ) )
587+ . post ( '/games/foo/1/update' )
588+ . send ( 'playerID=2&credentials=SECRET1&newName=joe' ) ;
589+ expect ( response . text ) . toEqual ( 'Player 2 not found' ) ;
590+ } ) ;
591+ } ) ;
592+
593+ describe ( 'when the credentials are invalid' , ( ) => {
594+ test ( 'throws invalid credentials' , async ( ) => {
595+ const app = createApiServer ( { db, games } ) ;
596+ response = await request ( app . callback ( ) )
597+ . post ( '/games/foo/1/update' )
598+ . send ( 'playerID=0&credentials=SECRET2&newName=mike' ) ;
599+ expect ( response . text ) . toEqual ( 'Invalid credentials SECRET2' ) ;
600+ } ) ;
601+ } ) ;
602+ describe ( 'when playerID is omitted' , ( ) => {
603+ beforeEach ( async ( ) => {
604+ const app = createApiServer ( { db, games } ) ;
605+ response = await request ( app . callback ( ) )
606+ . post ( '/games/foo/1/update' )
607+ . send ( 'credentials=foo&newName=bill' ) ;
608+ } ) ;
609+ test ( 'throws playerID is required' , async ( ) => {
610+ expect ( response . text ) . toEqual ( 'playerID is required' ) ;
611+ } ) ;
612+ describe ( 'when newName is omitted' , ( ) => {
613+ beforeEach ( async ( ) => {
614+ const app = createApiServer ( { db, games } ) ;
615+ response = await request ( app . callback ( ) )
616+ . post ( '/games/foo/1/update' )
617+ . send ( 'credentials=foo&playerID=0' ) ;
618+ } ) ;
619+
620+ test ( 'throws newName is required' , async ( ) => {
621+ expect ( response . text ) . toEqual ( 'newName or data is required' ) ;
622+ } ) ;
623+ } ) ;
624+ } ) ;
625+ } ) ;
626+ } ) ;
627+ } ) ;
628+
629+ describe ( 'updating player metadata' , ( ) => {
630+ let response ;
631+ let db ;
632+ let games ;
633+
634+ beforeEach ( ( ) => {
635+ games = [ ProcessGameConfig ( { name : 'foo' } ) ] ;
636+ } ) ;
637+
638+ describe ( 'for an unprotected lobby' , ( ) => {
639+ beforeEach ( ( ) => {
640+ delete process . env . API_SECRET ;
641+ } ) ;
642+ describe ( 'when the game does not exist' , ( ) => {
643+ test ( 'throws game not found' , async ( ) => {
644+ db = new AsyncStorage ( {
645+ fetch : async ( ) => ( { metadata : null } ) ,
646+ } ) ;
647+ const app = createApiServer ( { db, games } ) ;
648+ response = await request ( app . callback ( ) )
649+ . post ( '/games/foo/1/update' )
650+ . send ( { playerID : 0 , data : { subdata : 'text' } } ) ;
651+ expect ( response . text ) . toEqual ( 'Game 1 not found' ) ;
652+ } ) ;
653+ } ) ;
654+
655+ describe ( 'when the game does exist' , ( ) => {
656+ describe ( 'when the playerID does exist' , ( ) => {
657+ beforeEach ( async ( ) => {
658+ db = new AsyncStorage ( {
659+ fetch : async ( ) => {
660+ return {
661+ metadata : {
662+ players : {
663+ '0' : {
664+ name : 'alice' ,
665+ credentials : 'SECRET1' ,
666+ } ,
667+ '1' : {
668+ name : 'bob' ,
669+ credentials : 'SECRET2' ,
670+ } ,
671+ } ,
672+ } ,
673+ } ;
674+ } ,
675+ } ) ;
676+ const app = createApiServer ( { db, games } ) ;
677+ response = await request ( app . callback ( ) )
678+ . post ( '/games/foo/1/update' )
679+ . send ( {
680+ playerID : 0 ,
681+ credentials : 'SECRET1' ,
682+ data : { subdata : 'text' } ,
683+ } ) ;
684+ } ) ;
685+
686+ test ( 'is successful' , async ( ) => {
687+ expect ( response . status ) . toEqual ( 200 ) ;
688+ } ) ;
689+
690+ test ( 'updates the players' , async ( ) => {
691+ expect ( db . mocks . setMetadata ) . toHaveBeenCalledWith (
692+ '1' ,
693+ expect . objectContaining ( {
694+ players : expect . objectContaining ( {
695+ '0' : expect . objectContaining ( {
696+ data : expect . objectContaining ( {
697+ subdata : 'text' ,
698+ } ) ,
699+ } ) ,
700+ } ) ,
701+ } )
702+ ) ;
703+ } ) ;
704+ } ) ;
705+
706+ describe ( 'when the playerID does not exist' , ( ) => {
707+ test ( 'throws playerID not found' , async ( ) => {
708+ const app = createApiServer ( { db, games } ) ;
709+ response = await request ( app . callback ( ) )
710+ . post ( '/games/foo/1/update' )
711+ . send ( {
712+ playerID : 2 ,
713+ credentials : 'SECRET1' ,
714+ data : { subdata : 'text' } ,
715+ } ) ;
716+ expect ( response . text ) . toEqual ( 'Player 2 not found' ) ;
717+ } ) ;
718+ } ) ;
719+
720+ describe ( 'when the credentials are invalid' , ( ) => {
721+ test ( 'invalid credentials' , async ( ) => {
722+ const app = createApiServer ( { db, games } ) ;
723+ response = await request ( app . callback ( ) )
724+ . post ( '/games/foo/1/update' )
725+ . send ( {
726+ playerID : 0 ,
727+ credentials : 'SECRET2' ,
728+ data : { subdata : 'text' } ,
729+ } ) ;
730+ expect ( response . text ) . toEqual ( 'Invalid credentials SECRET2' ) ;
731+ } ) ;
732+ } ) ;
733+ describe ( 'when playerID is omitted' , ( ) => {
734+ beforeEach ( async ( ) => {
735+ const app = createApiServer ( { db, games } ) ;
736+ response = await request ( app . callback ( ) )
737+ . post ( '/games/foo/1/update' )
738+ . send ( { credentials : 'foo' , data : { subdata : 'text' } } ) ;
739+ } ) ;
740+
741+ test ( 'throws playerID is required' , async ( ) => {
742+ expect ( response . text ) . toEqual ( 'playerID is required' ) ;
743+ } ) ;
744+ describe ( 'when data is omitted' , ( ) => {
745+ beforeEach ( async ( ) => {
746+ const app = createApiServer ( { db, games } ) ;
747+ response = await request ( app . callback ( ) )
748+ . post ( '/games/foo/1/update' )
749+ . send ( { playerID : 0 , credentials : 'foo' } ) ;
750+ } ) ;
751+
752+ test ( 'throws data is required' , async ( ) => {
753+ expect ( response . text ) . toEqual ( 'newName or data is required' ) ;
754+ } ) ;
755+ } ) ;
756+ } ) ;
757+ } ) ;
758+ } ) ;
759+ } ) ;
760+
475761 describe ( 'leaving a room' , ( ) => {
476762 let response ;
477763 let db ;
0 commit comments