mirror of
https://github.com/MarijnDoeve/TijdVoorDeTest.git
synced 2026-07-09 00:50:14 +02:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
82f8f0e22a
|
@@ -10,10 +10,12 @@ use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\FormError;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Attribute\AsController;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
use Symfony\Component\Security\Http\Attribute\IsCsrfTokenValid;
|
||||
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
||||
use Symfony\Component\Validator\Constraints\Length;
|
||||
use Symfony\Component\Validator\Constraints\NotBlank;
|
||||
@@ -97,6 +99,24 @@ class SeasonController extends AbstractController
|
||||
]);
|
||||
}
|
||||
|
||||
#[IsCsrfTokenValid('regenerate_season_code')]
|
||||
#[IsGranted(SeasonVoter::EDIT, subject: 'season')]
|
||||
#[Route(
|
||||
'/backoffice/season/{seasonCode:season}/settings/regenerate-code',
|
||||
name: 'tvdt_backoffice_season_regenerate_code',
|
||||
requirements: ['seasonCode' => self::SEASON_CODE_REGEX],
|
||||
methods: ['POST'],
|
||||
)]
|
||||
public function regenerateSeasonCode(Season $season): RedirectResponse
|
||||
{
|
||||
$season->generateSeasonCode();
|
||||
$this->em->flush();
|
||||
|
||||
$this->addFlash(FlashType::Success, $this->translator->trans('Season code regenerated'));
|
||||
|
||||
return $this->redirectToRoute('tvdt_backoffice_season_settings', ['seasonCode' => $season->seasonCode]);
|
||||
}
|
||||
|
||||
#[IsGranted(SeasonVoter::EDIT, subject: 'season')]
|
||||
#[Route(
|
||||
'/backoffice/season/{seasonCode:season}/add-candidate',
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<h6>Seizoensinstellingen</h6>
|
||||
<p>Pas hier de weergave-instellingen van dit seizoen aan.</p>
|
||||
<p><strong>Nummers tonen:</strong> toont vraagnummers tijdens de test. <strong>Antwoord bevestigen:</strong> vraagt kandidaten om hun antwoord te bevestigen voordat ze doorgaan.</p>
|
||||
<p><strong>Seizoenscode:</strong> de code waarmee kandidaten dit seizoen kunnen vinden. Genereer een nieuwe code als de huidige per ongeluk gedeeld is, de oude code werkt daarna niet meer.</p>
|
||||
|
||||
@@ -1,8 +1,40 @@
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-12">
|
||||
{{ form(form) }}
|
||||
|
||||
<hr>
|
||||
|
||||
<h4 class="text-danger">{{ 'Season code'|trans }}</h4>
|
||||
<p>{{ 'The season code is used by candidates to join this season. Regenerating it invalidates the current code, so make sure to share the new one.'|trans }}</p>
|
||||
<p><strong>{{ 'Current code:'|trans }}</strong> {{ season.seasonCode }}</p>
|
||||
<button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#regenerateSeasonCodeModal">
|
||||
{{ 'Regenerate season code...'|trans }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-md-6 col-12">
|
||||
{{ include('backoffice/help/season_settings.html.twig') }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="regenerateSeasonCodeModal" data-bs-backdrop="static"
|
||||
tabindex="-1"
|
||||
aria-labelledby="regenerateSeasonCodeModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<form action="{{ path('tvdt_backoffice_season_regenerate_code', {seasonCode: season.seasonCode}) }}" method="POST">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="regenerateSeasonCodeModalLabel">{{ 'Regenerate season code'|trans }}</h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>{{ 'This invalidates the current season code. Anyone using the old code will no longer be able to join this season.'|trans }}</p>
|
||||
<input type="hidden" name="_token" value="{{ csrf_token('regenerate_season_code') }}">
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{ 'Cancel'|trans }}</button>
|
||||
<button type="submit" class="btn btn-danger">{{ 'Regenerate season code'|trans }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -8,13 +8,11 @@
|
||||
</div>
|
||||
<div class="list-group mb-3">
|
||||
{% for quiz in season.quizzes %}
|
||||
<a class="list-group-item list-group-item-action d-flex align-items-center gap-2{% if season.activeQuiz == quiz %} active{% endif %}"
|
||||
<a class="list-group-item list-group-item-action{% if season.activeQuiz == quiz %} active{% endif %}"
|
||||
href="{{ path('tvdt_backoffice_quiz', {seasonCode: season.seasonCode, quiz: quiz.id}) }}">
|
||||
{{ quiz.name }}
|
||||
{% if season.activeQuiz == quiz %}
|
||||
<span class="badge text-bg-light ms-auto">{{ 'Active'|trans }}</span>
|
||||
{% elseif quiz.isFinalized %}
|
||||
<span class="badge text-bg-success ms-auto">{{ 'Ready'|trans }}</span>
|
||||
{% if quiz.isFinalized %}
|
||||
<span class="badge text-bg-success">{{ 'Finalized'|trans }}</span>
|
||||
{% endif %}
|
||||
</a>
|
||||
{% else %}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tvdt\Tests\Controller\Backoffice;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Tvdt\Controller\Backoffice\SeasonController;
|
||||
use Tvdt\Entity\Season;
|
||||
use Tvdt\Entity\User;
|
||||
|
||||
#[CoversClass(SeasonController::class)]
|
||||
final class SeasonControllerTest extends WebTestCase
|
||||
{
|
||||
private KernelBrowser $client;
|
||||
|
||||
private EntityManagerInterface $entityManager;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->client = self::createClient();
|
||||
$this->entityManager = self::getContainer()->get(EntityManagerInterface::class);
|
||||
|
||||
$user = $this->entityManager->getRepository(User::class)->findOneBy(['email' => 'krtek-admin@example.org']);
|
||||
$this->assertInstanceOf(User::class, $user);
|
||||
$this->client->loginUser($user);
|
||||
}
|
||||
|
||||
public function testRegenerateSeasonCodeChangesTheCode(): void
|
||||
{
|
||||
$oldCode = 'krtek';
|
||||
$crawler = $this->client->request(Request::METHOD_GET, \sprintf('/backoffice/season/%s/settings', $oldCode));
|
||||
self::assertResponseIsSuccessful();
|
||||
|
||||
$token = (string) $crawler->filter('form[action*="/regenerate-code"] input[name="_token"]')->first()->attr('value');
|
||||
|
||||
$this->client->request(Request::METHOD_POST, \sprintf('/backoffice/season/%s/settings/regenerate-code', $oldCode), [
|
||||
'_token' => $token,
|
||||
]);
|
||||
|
||||
self::assertResponseRedirects();
|
||||
$this->entityManager->clear();
|
||||
|
||||
$this->assertNotInstanceOf(Season::class, $this->entityManager->getRepository(Season::class)->findOneBy(['seasonCode' => $oldCode]));
|
||||
|
||||
$location = (string) $this->client->getResponse()->headers->get('Location');
|
||||
$this->assertMatchesRegularExpression('#^/backoffice/season/[a-z]{5}/settings$#', $location);
|
||||
}
|
||||
|
||||
public function testRegenerateSeasonCodeIsDeniedForNonOwner(): void
|
||||
{
|
||||
$crawler = $this->client->request(Request::METHOD_GET, '/backoffice/season/krtek/settings');
|
||||
self::assertResponseIsSuccessful();
|
||||
$token = (string) $crawler->filter('form[action*="/regenerate-code"] input[name="_token"]')->first()->attr('value');
|
||||
|
||||
$user = $this->entityManager->getRepository(User::class)->findOneBy(['email' => 'test@example.org']);
|
||||
$this->assertInstanceOf(User::class, $user);
|
||||
$this->client->loginUser($user);
|
||||
|
||||
$this->client->request(Request::METHOD_POST, '/backoffice/season/krtek/settings/regenerate-code', [
|
||||
'_token' => $token,
|
||||
]);
|
||||
|
||||
self::assertResponseStatusCodeSame(403);
|
||||
}
|
||||
}
|
||||
@@ -221,6 +221,10 @@
|
||||
<source>Create an empty quiz and add questions from the question bank.</source>
|
||||
<target>Maak een lege quiz aan en voeg vragen toe vanuit de vragenbank.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="jrXhJOR" resname="Current code:">
|
||||
<source>Current code:</source>
|
||||
<target>Huidige code:</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="3leUyoA" resname="Current email address:">
|
||||
<source>Current email address:</source>
|
||||
<target>Huidig e-mailadres:</target>
|
||||
@@ -661,10 +665,6 @@
|
||||
<source>Re-opens the quiz for editing. Candidates will no longer be able to take the quiz until it is finalized again.</source>
|
||||
<target>Heropent de test voor bewerking. Deelnemers kunnen de test niet meer afnemen totdat deze opnieuw is afgerond.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="MuwD4xO" resname="Ready">
|
||||
<source>Ready</source>
|
||||
<target>Voorbereid</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="P1HcfAu" resname="Red">
|
||||
<source>Red</source>
|
||||
<target>Rood</target>
|
||||
@@ -673,6 +673,14 @@
|
||||
<source>Refresh the page to try again.</source>
|
||||
<target>Ververs de pagina om het opnieuw te proberen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="EGW_4W_" resname="Regenerate season code">
|
||||
<source>Regenerate season code</source>
|
||||
<target>Seizoenscode opnieuw genereren</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="EWuNNNu" resname="Regenerate season code...">
|
||||
<source>Regenerate season code...</source>
|
||||
<target>Seizoenscode opnieuw genereren...</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="fGfBzt6" resname="Register">
|
||||
<source>Register</source>
|
||||
<target>Registreren</target>
|
||||
@@ -733,6 +741,14 @@
|
||||
<source>Season Name</source>
|
||||
<target>Seizoennaam</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="IxKDF4a" resname="Season code">
|
||||
<source>Season code</source>
|
||||
<target>Seizoenscode</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="iigT2eM" resname="Season code regenerated">
|
||||
<source>Season code regenerated</source>
|
||||
<target>Seizoenscode opnieuw gegenereerd</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="kc_J96C" resname="Seasons">
|
||||
<source>Seasons</source>
|
||||
<target>Seizoenen</target>
|
||||
@@ -773,6 +789,14 @@
|
||||
<source>Sync latest changes to this quiz</source>
|
||||
<target>Laatste wijzigingen synchroniseren naar deze quiz</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="XwQ1Fav" resname="The confirmation email could not be sent. Please try again later.">
|
||||
<source>The confirmation email could not be sent. Please try again later.</source>
|
||||
<target>De bevestigingsmail kon niet worden verzonden. Probeer het later opnieuw.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="mMDwcxj" resname="The confirmation email could not be sent. Please use the resend button to try again.">
|
||||
<source>The confirmation email could not be sent. Please use the resend button to try again.</source>
|
||||
<target>De bevestigingsmail kon niet worden verzonden. Gebruik de knop om het opnieuw te proberen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="_z4el3Z" resname="The password fields must match.">
|
||||
<source>The password fields must match.</source>
|
||||
<target>De wachtwoorden moeten overeen komen.</target>
|
||||
@@ -797,6 +821,10 @@
|
||||
<source>The quiz must be finalized before it can be activated</source>
|
||||
<target>De test moet afgerond zijn voordat deze geactiveerd kan worden</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="IKPt_Pf" resname="The season code is used by candidates to join this season. Regenerating it invalidates the current code, so make sure to share the new one.">
|
||||
<source>The season code is used by candidates to join this season. Regenerating it invalidates the current code, so make sure to share the new one.</source>
|
||||
<target>De seizoenscode wordt door kandidaten gebruikt om dit seizoen te vinden. Als je een nieuwe code genereert, werkt de oude niet meer, dus deel de nieuwe code opnieuw.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="HuzRgeN" resname="There are no answers for this question">
|
||||
<source>There are no answers for this question</source>
|
||||
<target>Er zijn geen antwoorden voor deze vraag</target>
|
||||
@@ -813,6 +841,10 @@
|
||||
<source>This deletes your account and every season you are the only owner of. Enter your password to confirm.</source>
|
||||
<target>Dit verwijdert je account en alle seizoenen waarvan jij de enige eigenaar bent. Vul je wachtwoord in om te bevestigen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="EBWUWJu" resname="This invalidates the current season code. Anyone using the old code will no longer be able to join this season.">
|
||||
<source>This invalidates the current season code. Anyone using the old code will no longer be able to join this season.</source>
|
||||
<target>Hiermee wordt de huidige seizoenscode ongeldig. Iedereen die de oude code gebruikt, kan dit seizoen niet meer vinden.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="YueaA2f" resname="This link will expire in %count%.">
|
||||
<source>This link will expire in %count%.</source>
|
||||
<target>Deze link verloopt over %count%.</target>
|
||||
@@ -905,18 +937,14 @@
|
||||
<source>Your data</source>
|
||||
<target>Je gegevens</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sAb9l8I" resname="Your email address has been changed.">
|
||||
<source>Your email address has been changed.</source>
|
||||
<target>Je e-mailadres is gewijzigd.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="OqDtnJw" resname="Your email address has been changed. Please check your inbox to confirm it.">
|
||||
<source>Your email address has been changed. Please check your inbox to confirm it.</source>
|
||||
<target>Je e-mailadres is gewijzigd. Check je inbox om het te bevestigen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="kWpL7Rn" resname="The confirmation email could not be sent. Please use the resend button to try again.">
|
||||
<source>The confirmation email could not be sent. Please use the resend button to try again.</source>
|
||||
<target>De bevestigingsmail kon niet worden verzonden. Gebruik de knop om het opnieuw te proberen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="mQxV2Jf" resname="The confirmation email could not be sent. Please try again later.">
|
||||
<source>The confirmation email could not be sent. Please try again later.</source>
|
||||
<target>De bevestigingsmail kon niet worden verzonden. Probeer het later opnieuw.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="m80cBv0" resname="Your email address has been verified.">
|
||||
<source>Your email address has been verified.</source>
|
||||
<target>Je e-mailadres is geverifieerd.</target>
|
||||
|
||||
Reference in New Issue
Block a user