mirror of
https://github.com/MarijnDoeve/TijdVoorDeTest.git
synced 2026-07-12 21:05:19 +02:00
Add reset progress action for a candidate's quiz attempt, and modal-based candidate editing (#204)
* feat: add reset progress action for a candidate's quiz attempt Admins previously had no way to let a candidate retake a quiz once started. Adds a backoffice action that clears a candidate's given answers and start timestamp for a quiz, closes #20. * fix: wrap candidate progress reset in a transaction Avoids leaving a candidate half-reset (answers deleted but started still set) if the second flush fails. Addresses CodeRabbit review comment on PR #204. * feat: open candidate edit/add forms in modals with dirty-aware dismissal Rename-candidate modal always blocked backdrop-click dismissal via a hardcoded static backdrop; wire it into the existing bo--modal controller so outside clicks/Escape only get blocked once the name field has actually been edited. Also move "Add Candidate" from a full-page navigation into the same turbo-frame modal pattern already used for editing quiz questions, keeping the full-page form as a fallback for non-JS/turbo requests. * feat: show a hint for the candidates textarea and gate translations in CI Add a help hint on the add-candidates form explaining one candidate per line, and translate it plus a few strings from the earlier reset-progress feature that had been missed. Also add a CI step that re-runs translation:extract and fails the build if it produces uncommitted changes, so untranslated/stale strings can't slip through review again. * Just links
This commit is contained in:
@@ -104,6 +104,42 @@ final class SeasonControllerTest extends AbstractControllerWebTestCase
|
||||
$this->assertNotInstanceOf(Candidate::class, $this->entityManager->getRepository(Candidate::class)->find($candidateId));
|
||||
}
|
||||
|
||||
public function testAddCandidates(): void
|
||||
{
|
||||
$this->client->request(Request::METHOD_GET, '/backoffice/season/krtek/add-candidate');
|
||||
$form = $this->client->getCrawler()->filter('form')->form([
|
||||
'add_candidates_form[candidates]' => "Nora\nPiet",
|
||||
]);
|
||||
$this->client->submit($form);
|
||||
|
||||
self::assertResponseRedirects('/backoffice/season/krtek/candidates');
|
||||
$this->entityManager->clear();
|
||||
|
||||
$season = $this->entityManager->getRepository(Season::class)->findOneBy(['seasonCode' => 'krtek']);
|
||||
$this->assertInstanceOf(Season::class, $season);
|
||||
$names = array_map(static fn (Candidate $candidate): string => $candidate->name, $season->candidates->toArray());
|
||||
$this->assertContains('Nora', $names);
|
||||
$this->assertContains('Piet', $names);
|
||||
}
|
||||
|
||||
public function testAddCandidatesViaTurboFrameReturnsEmptyFrame(): void
|
||||
{
|
||||
$this->client->xmlHttpRequest(Request::METHOD_GET, '/backoffice/season/krtek/add-candidate', server: ['HTTP_TURBO-FRAME' => 'add-candidates-modal-frame']);
|
||||
$form = $this->client->getCrawler()->filter('form')->form([
|
||||
'add_candidates_form[candidates]' => 'Sanne',
|
||||
]);
|
||||
$this->client->submit($form, [], ['HTTP_TURBO-FRAME' => 'add-candidates-modal-frame']);
|
||||
|
||||
self::assertResponseIsSuccessful();
|
||||
$this->assertStringContainsString('<turbo-frame id="add-candidates-modal-frame"></turbo-frame>', (string) $this->client->getResponse()->getContent());
|
||||
$this->entityManager->clear();
|
||||
|
||||
$season = $this->entityManager->getRepository(Season::class)->findOneBy(['seasonCode' => 'krtek']);
|
||||
$this->assertInstanceOf(Season::class, $season);
|
||||
$names = array_map(static fn (Candidate $candidate): string => $candidate->name, $season->candidates->toArray());
|
||||
$this->assertContains('Sanne', $names);
|
||||
}
|
||||
|
||||
public function testRenameCandidateIsDeniedForNonOwner(): void
|
||||
{
|
||||
$candidate = $this->getCandidate('Tom');
|
||||
|
||||
Reference in New Issue
Block a user