Skip to content

Commit

Permalink
Fix setting locale
Browse files Browse the repository at this point in the history
  • Loading branch information
core23 committed Jul 7, 2024
1 parent f56665d commit 34ba95a
Show file tree
Hide file tree
Showing 2 changed files with 186 additions and 12 deletions.
20 changes: 8 additions & 12 deletions src/EventListener/LocaleEventListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ public function onImplicitLogin(UserEvent $event): void
return;
}

$this->setLocale($event->getRequest(), $user);
$this->setTimezone($event->getRequest(), $user);
$this->setLocale($event->getRequest(), $user->getLocale());
$this->setTimezone($event->getRequest(), $user->getTimezone());
}

public function onSecurityInteractiveLogin(InteractiveLoginEvent $event): void
Expand All @@ -68,8 +68,8 @@ public function onSecurityInteractiveLogin(InteractiveLoginEvent $event): void
return;
}

$this->setLocale($event->getRequest(), $user);
$this->setTimezone($event->getRequest(), $user);
$this->setLocale($event->getRequest(), $user->getLocale());
$this->setTimezone($event->getRequest(), $user->getTimezone());
}

public function onKernelRequest(RequestEvent $event): void
Expand All @@ -92,7 +92,7 @@ public function onTimezoneChanged(UserEvent $event): void
$user = $event->getUser();

if ($user instanceof LocaleAwareUser && null !== $event->getRequest()) {
$this->setTimezone($event->getRequest(), $user);
$this->setTimezone($event->getRequest(), $user->getTimezone());
}
}

Expand All @@ -101,20 +101,18 @@ public function onLocaleChanged(UserEvent $event): void
$user = $event->getUser();

if ($user instanceof LocaleAwareUser && null !== $event->getRequest()) {
$this->setLocale($event->getRequest(), $user);
$this->setLocale($event->getRequest(), $user->getLocale());
}
}

private function setLocale(Request $request, LocaleAwareUser $user): void
private function setLocale(Request $request, ?string $locale): void
{
if (!$request->hasSession()) {
return;
}

$session = $request->getSession();

$locale = $user->getLocale();

if ('' === $locale || null === $locale) {
$session->remove(self::ATTR_LOCALE);

Expand All @@ -126,16 +124,14 @@ private function setLocale(Request $request, LocaleAwareUser $user): void
$session->set(self::ATTR_LOCALE, $locale);
}

private function setTimezone(Request $request, LocaleAwareUser $user): void
private function setTimezone(Request $request, ?string $timezone): void
{
if (!$request->hasSession()) {
return;
}

$session = $request->getSession();

$timezone = $user->getTimezone();

if ('' === $timezone || null === $timezone) {
$session->remove(self::ATTR_TIMEZONE);

Expand Down
178 changes: 178 additions & 0 deletions tests/EventListener/LocaleEventListenerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
<?php

/*
* This file is part of the NucleosUserBundle package.
*
* (c) Christian Gripp <mail@core23.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Nucleos\UserBundle\Tests\EventListener;

use Nucleos\UserBundle\Event\UserEvent;
use Nucleos\UserBundle\EventListener\LocaleEventListener;
use Nucleos\UserBundle\NucleosUserEvents;
use Nucleos\UserBundle\Tests\App\Entity\TestUser;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Symfony\Bundle\FrameworkBundle\Test\TestBrowserToken;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Contracts\Translation\LocaleAwareInterface as LocaleAwareTranslator;

final class LocaleEventListenerTest extends TestCase
{
/**
* @var LocaleAwareTranslator&MockObject
*/
private LocaleAwareTranslator $translator;

private LocaleEventListener $listener;

protected function setUp(): void
{
$this->translator = $this->createMock(LocaleAwareTranslator::class);
$this->listener = new LocaleEventListener($this->translator);
}

#[Test]
public function getSubscribedEvents(): void
{
self::assertSame([
NucleosUserEvents::SECURITY_IMPLICIT_LOGIN => 'onImplicitLogin',
SecurityEvents::INTERACTIVE_LOGIN => 'onSecurityInteractiveLogin',
KernelEvents::REQUEST => [['onKernelRequest', 20]],
NucleosUserEvents::USER_LOCALE_CHANGED => 'onLocaleChanged',
NucleosUserEvents::USER_TIMEZONE_CHANGED => 'onTimezoneChanged',
], LocaleEventListener::getSubscribedEvents());
}

#[Test]
public function onImplicitLogin(): void
{
$session = new Session(new MockArraySessionStorage());

$request = new Request();
$request->setSession($session);

$user = new TestUser();
$user->setLocale('fr');
$user->setTimezone('Europe/Paris');

$event = new UserEvent($user, $request);

$this->translator->expects(self::once())
->method('setLocale')
->with('fr')
;

$this->listener->onImplicitLogin($event);

self::assertSame('fr', $request->getLocale());
self::assertSame('fr', $session->get('_locale'));
self::assertSame('Europe/Paris', $session->get('_timezone'));
}

#[Test]
public function onSecurityInteractiveLogin(): void
{
$session = new Session(new MockArraySessionStorage());

$request = new Request();
$request->setSession($session);

$user = new TestUser();
$user->setLocale('fr');
$user->setTimezone('Europe/Paris');

$event = new InteractiveLoginEvent($request, new TestBrowserToken(user: $user));

$this->translator->expects(self::once())
->method('setLocale')
->with('fr')
;

$this->listener->onSecurityInteractiveLogin($event);

self::assertSame('fr', $request->getLocale());
self::assertSame('fr', $session->get('_locale'));
self::assertSame('Europe/Paris', $session->get('_timezone'));
}

#[Test]
public function onKernelRequest(): void
{
$session = new Session(new MockArraySessionStorage());
$session->set('_locale', 'fr');
$session->set('_timezone', 'Europe/Paris');

$request = new Request();
$request->setSession($session);
$request->cookies->set($session->getName(), $session->getId());

$event = new RequestEvent($this->createMock(KernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST);

$this->translator->expects(self::once())
->method('setLocale')
->with('fr')
;

$this->listener->onKernelRequest($event);

self::assertSame('fr', $request->getLocale());
self::assertSame('fr', $session->get('_locale'));
self::assertSame('Europe/Paris', $session->get('_timezone'));
}

#[Test]
public function onTimezoneChanged(): void
{
$session = new Session(new MockArraySessionStorage());

$request = new Request();
$request->setSession($session);

$user = new TestUser();
$user->setTimezone('Europe/Paris');

$event = new UserEvent($user, $request);

$this->listener->onTimezoneChanged($event);

self::assertSame('Europe/Paris', $session->get('_timezone'));
}

#[Test]
public function onLocaleChanged(): void
{
$session = new Session(new MockArraySessionStorage());

$request = new Request();
$request->setSession($session);

$user = new TestUser();
$user->setLocale('de');

$event = new UserEvent($user, $request);

$this->translator->expects(self::once())
->method('setLocale')
->with('de')
;

$this->listener->onLocaleChanged($event);

self::assertSame('de', $request->getLocale());
self::assertSame('de', $session->get('_locale'));
}
}

0 comments on commit 34ba95a

Please sign in to comment.