<?php

declare(strict_types=1);

/*
 * This file is part of the Ferienpass package.
 *
 * (c) Richard Henkenjohann <richard@ferienpass.online>
 *
 * For more information visit the project website <https://ferienpass.online>
 * or the documentation under <https://docs.ferienpass.online>.
 */

namespace Ferienpass\CmsBundle\Tests\EventListener\Security;

use Doctrine\ORM\EntityManagerInterface;
use Ferienpass\CmsBundle\EventListener\Security\ContaoBackendLogoutListener;
use Ferienpass\CmsBundle\EventListener\Security\LoginSuccessListener;
use Ferienpass\CoreBundle\Repository\AttendanceRepository;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Event\LoginSuccessEvent;
use Symfony\Component\Security\Http\Event\LogoutEvent;

final class SecurityListenersTest extends TestCase
{
    // ---- ContaoBackendLogoutListener ----

    public function testContaoBackendLogoutListenerSetsRedirectResponse(): void
    {
        $urlGenerator = $this->createMock(UrlGeneratorInterface::class);
        $urlGenerator->method('generate')->with('admin_index')->willReturn('/admin');

        $request = Request::create('/logout');
        $event = new LogoutEvent($request, null);

        new ContaoBackendLogoutListener($urlGenerator)->__invoke($event);

        $response = $event->getResponse();
        self::assertInstanceOf(RedirectResponse::class, $response);
        self::assertSame('/admin', $response->getTargetUrl());
    }

    // ---- LoginSuccessListener ----

    public function testLoginSuccessListenerDoesNothingWhenUserIsNotFerienpassUser(): void
    {
        $token = $this->createMock(TokenInterface::class);
        $token->method('getUser')->willReturn($this->createMock(\Symfony\Component\Security\Core\User\UserInterface::class));

        $event = $this->createMock(LoginSuccessEvent::class);
        $event->method('getAuthenticatedToken')->willReturn($token);
        $event->expects(self::never())->method('getRequest');

        $attendances = $this->createMock(AttendanceRepository::class);
        $attendances->expects(self::never())->method('hasOutstandingConsentsForUser');

        $urlGenerator = $this->createMock(UrlGeneratorInterface::class);

        new LoginSuccessListener($attendances, $urlGenerator, $this->createMock(EntityManagerInterface::class))->__invoke($event);
    }
}
