@@ -401,12 +401,12 @@ public function testGetPartialForm(array $expected) {
401401 $ form ->setLastUpdated (123456789 );
402402
403403 $ this ->submissionMapper ->expects ($ this ->once ())
404- ->method ('countSubmissions ' )
405- ->with (42 )
406- ->willReturn (123 );
404+ ->method ('countSubmissionsByForms ' )
405+ ->with ([ 42 ] )
406+ ->willReturn ([ 42 => 123 ] );
407407
408408 // Run the test
409- $ this ->assertEquals ($ expected , $ this ->formsService ->getPartialFormArray ( $ form) );
409+ $ this ->assertEquals ($ expected , $ this ->formsService ->getPartialFormArrays ([ $ form])[ 0 ] );
410410 }
411411
412412 public static function dataGetPartialFormShared () {
@@ -454,12 +454,143 @@ public function testGetPartialFormShared(array $expected) {
454454 ->willReturn ([$ share ]);
455455
456456 $ this ->submissionMapper ->expects ($ this ->once ())
457- ->method ('countSubmissions ' )
458- ->with (42 )
459- ->willReturn (123 );
457+ ->method ('countSubmissionsByForms ' )
458+ ->with ([ 42 ] )
459+ ->willReturn ([ 42 => 123 ] );
460460
461461 // Run the test
462- $ this ->assertEquals ($ expected , $ this ->formsService ->getPartialFormArray ($ form ));
462+ $ this ->assertEquals ($ expected , $ this ->formsService ->getPartialFormArrays ([$ form ])[0 ]);
463+ }
464+
465+ /**
466+ * Shared users without results permission get the count of their own
467+ * submissions and the `results` permission appended once they submitted.
468+ */
469+ public function testGetPartialFormSharedUserSubmissions () {
470+ $ expected = [
471+ 'id ' => 42 ,
472+ 'hash ' => 'abcdefg ' ,
473+ 'title ' => 'Form 1 ' ,
474+ 'expires ' => 0 ,
475+ 'lastUpdated ' => 123456789 ,
476+ 'permissions ' => ['submit ' , 'results ' ],
477+ 'submissionCount ' => 2 ,
478+ 'state ' => 0 ,
479+ 'partial ' => true ,
480+ 'lockedBy ' => null ,
481+ 'lockedUntil ' => null ,
482+ ];
483+
484+ $ form = new Form ();
485+ $ form ->setId (42 );
486+ $ form ->setState (0 );
487+ $ form ->setHash ('abcdefg ' );
488+ $ form ->setTitle ('Form 1 ' );
489+ $ form ->setOwnerId ('otherUser ' );
490+ $ form ->setExpires (0 );
491+ $ form ->setLastUpdated (123456789 );
492+
493+ $ share = new Share ();
494+ $ share ->setFormId (42 );
495+ $ share ->setPermissions ([Constants::PERMISSION_SUBMIT ]);
496+ $ share ->setShareType (IShare::TYPE_USER );
497+ $ share ->setShareWith ('currentUser ' );
498+
499+ $ this ->shareMapper ->expects ($ this ->any ())
500+ ->method ('findByForm ' )
501+ ->with (42 )
502+ ->willReturn ([$ share ]);
503+
504+ $ this ->submissionMapper ->expects ($ this ->exactly (2 ))
505+ ->method ('countSubmissionsByForms ' )
506+ ->willReturnCallback (function (array $ formIds , ?string $ userId = null ): array {
507+ if ($ userId === null ) {
508+ $ this ->assertSame ([], $ formIds );
509+ return [];
510+ }
511+ $ this ->assertSame ([42 ], $ formIds );
512+ $ this ->assertSame ('currentUser ' , $ userId );
513+ return [42 => 2 ];
514+ });
515+
516+ $ this ->assertEquals ($ expected , $ this ->formsService ->getPartialFormArrays ([$ form ])[0 ]);
517+ }
518+
519+ /**
520+ * Submission counts for multiple forms are fetched with a single query per
521+ * permission bucket instead of one query per form.
522+ */
523+ public function testGetPartialFormArraysCountsInBulk () {
524+ $ ownedForm = new Form ();
525+ $ ownedForm ->setId (42 );
526+ $ ownedForm ->setState (0 );
527+ $ ownedForm ->setHash ('abcdefg ' );
528+ $ ownedForm ->setTitle ('Form 1 ' );
529+ $ ownedForm ->setOwnerId ('currentUser ' );
530+ $ ownedForm ->setExpires (0 );
531+ $ ownedForm ->setLastUpdated (123456789 );
532+
533+ $ sharedForm = new Form ();
534+ $ sharedForm ->setId (43 );
535+ $ sharedForm ->setState (0 );
536+ $ sharedForm ->setHash ('hijklmn ' );
537+ $ sharedForm ->setTitle ('Form 2 ' );
538+ $ sharedForm ->setOwnerId ('otherUser ' );
539+ $ sharedForm ->setExpires (0 );
540+ $ sharedForm ->setLastUpdated (123456789 );
541+
542+ $ share = new Share ();
543+ $ share ->setFormId (43 );
544+ $ share ->setPermissions ([Constants::PERMISSION_SUBMIT ]);
545+ $ share ->setShareType (IShare::TYPE_USER );
546+ $ share ->setShareWith ('currentUser ' );
547+
548+ $ this ->shareMapper ->expects ($ this ->any ())
549+ ->method ('findByForm ' )
550+ ->with (43 )
551+ ->willReturn ([$ share ]);
552+
553+ $ this ->submissionMapper ->expects ($ this ->exactly (2 ))
554+ ->method ('countSubmissionsByForms ' )
555+ ->willReturnCallback (function (array $ formIds , ?string $ userId = null ): array {
556+ if ($ userId === null ) {
557+ $ this ->assertSame ([42 ], $ formIds );
558+ return [42 => 7 ];
559+ }
560+ $ this ->assertSame ('currentUser ' , $ userId );
561+ $ this ->assertSame ([43 ], $ formIds );
562+ return [];
563+ });
564+
565+ $ expected = [
566+ [
567+ 'id ' => 42 ,
568+ 'hash ' => 'abcdefg ' ,
569+ 'title ' => 'Form 1 ' ,
570+ 'expires ' => 0 ,
571+ 'lastUpdated ' => 123456789 ,
572+ 'permissions ' => Constants::PERMISSION_ALL ,
573+ 'partial ' => true ,
574+ 'state ' => 0 ,
575+ 'lockedBy ' => null ,
576+ 'lockedUntil ' => null ,
577+ 'submissionCount ' => 7 ,
578+ ],
579+ [
580+ 'id ' => 43 ,
581+ 'hash ' => 'hijklmn ' ,
582+ 'title ' => 'Form 2 ' ,
583+ 'expires ' => 0 ,
584+ 'lastUpdated ' => 123456789 ,
585+ 'permissions ' => ['submit ' ],
586+ 'partial ' => true ,
587+ 'state ' => 0 ,
588+ 'lockedBy ' => null ,
589+ 'lockedUntil ' => null ,
590+ ],
591+ ];
592+
593+ $ this ->assertEquals ($ expected , $ this ->formsService ->getPartialFormArrays ([$ ownedForm , $ sharedForm ]));
463594 }
464595
465596 public static function dataGetPublicForm () {
0 commit comments