Skip to content

Commit 931a54b

Browse files
committed
Adding tests for basic CRUD operations on exercise file links.
1 parent 816da6e commit 931a54b

2 files changed

Lines changed: 222 additions & 8 deletions

File tree

app/V1Module/presenters/ExerciseFilesPresenter.php

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ public function actionCreateFileLink(string $id)
529529
$requiredRole = $req->getPost("requiredRole");
530530
$saveName = $req->getPost("saveName");
531531

532-
if (!$this->roles->validateRole($requiredRole)) {
532+
if ($requiredRole !== null && !$this->roles->validateRole($requiredRole)) {
533533
throw new InvalidApiArgumentException('requiredRole', "Unknown user role '$requiredRole'");
534534
}
535535

@@ -559,7 +559,7 @@ public function checkUpdateFileLink(string $id, string $linkId)
559559
}
560560
}
561561
/**
562-
* Update a specific exercise-file link.
562+
* Update a specific exercise-file link. Missing arguments are not changed.
563563
* @POST
564564
*/
565565
#[Path("id", new VUuid(), "of exercise", required: true)]
@@ -568,7 +568,7 @@ public function checkUpdateFileLink(string $id, string $linkId)
568568
"key",
569569
new VString(1, 16),
570570
"Internal user-selected identifier of the exercise file link within the exercise",
571-
required: true
571+
required: false
572572
)]
573573
#[Post(
574574
"requiredRole",
@@ -590,22 +590,25 @@ public function actionUpdateFileLink(string $id, string $linkId)
590590
$req = $this->getRequest();
591591
$post = $req->getPost();
592592

593+
$key = $req->getPost("key");
594+
if ($key) {
595+
$link->setKey($key); // if key is null, it is not changed
596+
}
597+
593598
if (array_key_exists("requiredRole", $post)) {
594-
// array_key_exists checks whether the key is present (even if null)
599+
// array_key_exists checks whether the requiredRole is present (even if null)
595600
$requiredRole = $post["requiredRole"];
596-
if (!$this->roles->validateRole($requiredRole)) {
601+
if ($requiredRole !== null && !$this->roles->validateRole($requiredRole)) {
597602
throw new InvalidApiArgumentException('requiredRole', "Unknown user role '$requiredRole'");
598603
}
599604
$link->setRequiredRole($requiredRole);
600605
}
601606

602607
if (array_key_exists("saveName", $post)) {
603-
// array_key_exists checks whether the key is present (even if null)
608+
// array_key_exists checks whether the saveName is present (even if null)
604609
$link->setSaveName($post["saveName"]);
605610
}
606611

607-
$link->setKey($req->getPost("key"));
608-
609612
$this->fileLinks->persist($link);
610613
$this->sendSuccessResponse($link);
611614
}

tests/Presenters/ExerciseFilesPresenter.phpt

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ use App\Helpers\FileStorage\LocalImmutableFile;
99
use App\Helpers\ExercisesConfig;
1010
use App\Helpers\TmpFilesHelper;
1111
use App\Model\Entity\AttachmentFile;
12+
use App\Model\Entity\Exercise;
13+
use App\Model\Entity\ExerciseFileLink;
1214
use App\Model\Entity\UploadedFile;
1315
use App\V1Module\Presenters\ExerciseFilesPresenter;
1416
use App\Model\Entity\ExerciseFile;
@@ -514,6 +516,215 @@ class TestExerciseFilesPresenter extends Tester\TestCase
514516
Assert::type(App\Model\Entity\AttachmentFile::class, $item);
515517
}
516518
}
519+
520+
private function getExerciseWithLinks(): Exercise
521+
{
522+
$exercises = array_filter(
523+
$this->exercises->findAll(),
524+
function (Exercise $e) {
525+
return !$e->getFileLinks()->isEmpty(); // select the exercise with file links
526+
}
527+
);
528+
Assert::count(1, $exercises);
529+
return array_pop($exercises);
530+
}
531+
532+
public function testGetExerciseFileLinks()
533+
{
534+
PresenterTestHelper::loginDefaultAdmin($this->container);
535+
$exercise = $this->getExerciseWithLinks();
536+
537+
$payload = PresenterTestHelper::performPresenterRequest(
538+
$this->presenter,
539+
"V1:ExerciseFiles",
540+
'GET',
541+
['action' => 'getFileLinks', 'id' => $exercise->getId()]
542+
);
543+
544+
$expectedLinks = [];
545+
foreach ($exercise->getFileLinks() as $link) {
546+
$expectedLinks[$link->getId()] = $link;
547+
}
548+
549+
foreach ($payload as $link) {
550+
Assert::true(array_key_exists($link->getId(), $expectedLinks));
551+
$expectedLink = $expectedLinks[$link->getId()];
552+
Assert::equal($expectedLink->getId(), $link->getId());
553+
Assert::equal($expectedLink->getExerciseFile()->getId(), $link->getExerciseFile()->getId());
554+
Assert::equal($expectedLink->getExercise()?->getId(), $link->getExercise()?->getId());
555+
Assert::equal($expectedLink->getKey(), $link->getKey());
556+
Assert::equal($expectedLink->getSaveName(), $link->getSaveName());
557+
Assert::equal($expectedLink->getRequiredRole(), $link->getRequiredRole());
558+
Assert::null($link->getAssignment());
559+
}
560+
}
561+
562+
public function testCreateExerciseFileLink()
563+
{
564+
PresenterTestHelper::loginDefaultAdmin($this->container);
565+
$exercise = $this->getExerciseWithLinks();
566+
$exerciseFile = $exercise->getExerciseFiles()->filter(function (ExerciseFile $ef) {
567+
return $ef->getName() === 'input.txt';
568+
})->first();
569+
Assert::truthy($exerciseFile);
570+
571+
$payload = PresenterTestHelper::performPresenterRequest(
572+
$this->presenter,
573+
"V1:ExerciseFiles",
574+
'POST',
575+
[
576+
'action' => 'createFileLink',
577+
'id' => $exercise->getId(),
578+
],
579+
[
580+
'exerciseFileId' => $exerciseFile->getId(),
581+
'key' => 'test-key',
582+
'requiredRole' => 'supervisor',
583+
'saveName' => 'rename.txt'
584+
]
585+
);
586+
587+
Assert::equal($exerciseFile->getId(), $payload->getExerciseFile()->getId());
588+
Assert::equal('test-key', $payload->getKey());
589+
Assert::equal('supervisor', $payload->getRequiredRole());
590+
Assert::equal('rename.txt', $payload->getSaveName());
591+
592+
Assert::count(3, $this->presenter->fileLinks->findAll());
593+
}
594+
595+
public function testCreateExerciseFileLinkWithoutOptionalFields()
596+
{
597+
PresenterTestHelper::loginDefaultAdmin($this->container);
598+
$exercise = $this->getExerciseWithLinks();
599+
$exerciseFile = $exercise->getExerciseFiles()->filter(function (ExerciseFile $ef) {
600+
return $ef->getName() === 'input.txt';
601+
})->first();
602+
Assert::truthy($exerciseFile);
603+
604+
$payload = PresenterTestHelper::performPresenterRequest(
605+
$this->presenter,
606+
"V1:ExerciseFiles",
607+
'POST',
608+
[
609+
'action' => 'createFileLink',
610+
'id' => $exercise->getId(),
611+
],
612+
[
613+
'exerciseFileId' => $exerciseFile->getId(),
614+
'key' => 'test-key',
615+
]
616+
);
617+
618+
Assert::equal($exerciseFile->getId(), $payload->getExerciseFile()->getId());
619+
Assert::equal('test-key', $payload->getKey());
620+
Assert::null($payload->getRequiredRole());
621+
Assert::null($payload->getSaveName());
622+
623+
Assert::count(3, $this->presenter->fileLinks->findAll());
624+
}
625+
626+
public function testUpdateExerciseFileLink()
627+
{
628+
PresenterTestHelper::loginDefaultAdmin($this->container);
629+
$exercise = $this->getExerciseWithLinks();
630+
$link = $exercise->getFileLinks()->filter(function (ExerciseFileLink $l) {
631+
return $l->getKey() === 'LIB';
632+
})->first();
633+
Assert::truthy($link);
634+
$exerciseFile = $link->getExerciseFile();
635+
$saveName = $link->getSaveName();
636+
637+
$payload = PresenterTestHelper::performPresenterRequest(
638+
$this->presenter,
639+
"V1:ExerciseFiles",
640+
'POST',
641+
[
642+
'action' => 'updateFileLink',
643+
'id' => $exercise->getId(),
644+
'linkId' => $link->getId(),
645+
],
646+
[
647+
'key' => 'SPAM',
648+
'requiredRole' => 'supervisor',
649+
]
650+
);
651+
652+
$this->presenter->fileLinks->refresh($link);
653+
654+
Assert::equal($link->getId(), $payload->getId());
655+
Assert::count(2, $this->presenter->fileLinks->findAll());
656+
657+
Assert::equal($exerciseFile->getId(), $payload->getExerciseFile()->getId());
658+
Assert::equal('SPAM', $payload->getKey());
659+
Assert::equal('supervisor', $payload->getRequiredRole());
660+
Assert::equal($saveName, $payload->getSaveName()); // wasn't changed
661+
662+
Assert::equal($exerciseFile->getId(), $link->getExerciseFile()->getId());
663+
Assert::equal('SPAM', $link->getKey());
664+
Assert::equal('supervisor', $link->getRequiredRole());
665+
Assert::equal($saveName, $link->getSaveName()); // wasn't changed
666+
}
667+
668+
public function testUpdateExerciseFileLinkSetNulls()
669+
{
670+
PresenterTestHelper::loginDefaultAdmin($this->container);
671+
$exercise = $this->getExerciseWithLinks();
672+
$link = $exercise->getFileLinks()->filter(function (ExerciseFileLink $l) {
673+
return $l->getKey() === 'LIB';
674+
})->first();
675+
Assert::truthy($link);
676+
$exerciseFile = $link->getExerciseFile();
677+
$key = $link->getKey();
678+
679+
$payload = PresenterTestHelper::performPresenterRequest(
680+
$this->presenter,
681+
"V1:ExerciseFiles",
682+
'POST',
683+
[
684+
'action' => 'updateFileLink',
685+
'id' => $exercise->getId(),
686+
'linkId' => $link->getId(),
687+
],
688+
[
689+
'requiredRole' => null,
690+
'saveName' => null,
691+
]
692+
);
693+
694+
$this->presenter->fileLinks->refresh($link);
695+
696+
Assert::equal($link->getId(), $payload->getId());
697+
Assert::count(2, $this->presenter->fileLinks->findAll());
698+
699+
Assert::equal($exerciseFile->getId(), $payload->getExerciseFile()->getId());
700+
Assert::equal($key, $payload->getKey()); // wasn't changed
701+
Assert::null($payload->getRequiredRole());
702+
Assert::null($payload->getSaveName());
703+
704+
Assert::equal($exerciseFile->getId(), $link->getExerciseFile()->getId());
705+
Assert::equal($key, $link->getKey()); // wasn't changed
706+
Assert::null($link->getRequiredRole());
707+
Assert::null($link->getSaveName());
708+
}
709+
710+
public function testDeleteExerciseFileLink()
711+
{
712+
PresenterTestHelper::loginDefaultAdmin($this->container);
713+
$exercise = $this->getExerciseWithLinks();
714+
$link = $exercise->getFileLinks()->first();
715+
Assert::truthy($link);
716+
717+
$payload = PresenterTestHelper::performPresenterRequest(
718+
$this->presenter,
719+
"V1:ExerciseFiles",
720+
'DELETE',
721+
['action' => 'deleteFileLink', 'id' => $exercise->getId(), 'linkId' => $link->getId()]
722+
);
723+
724+
Assert::count(1, $this->presenter->fileLinks->findAll());
725+
$remaining = current($this->presenter->fileLinks->findAll());
726+
Assert::notEqual($link->getId(), $remaining->getId());
727+
}
517728
}
518729

519730
(new TestExerciseFilesPresenter())->run();

0 commit comments

Comments
 (0)