Skip to content

Add UserManager::findUserByUsername() #200

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Command/AutoClosingCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
*/
class AutoClosingCommand extends ContainerAwareCommand
{
use UserManagerTrait;
use UserManagerAwareTrait;

protected static $defaultName = 'ticket:autoclosing';

Expand Down
2 changes: 1 addition & 1 deletion Command/TicketManagerCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
*/
class TicketManagerCommand extends ContainerAwareCommand
{
use UserManagerTrait;
use UserManagerAwareTrait;

protected static $defaultName = 'ticket:create';

Expand Down
21 changes: 10 additions & 11 deletions Command/UserManagerTrait.php → Command/UserManagerAwareTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,28 @@

namespace Hackzilla\Bundle\TicketBundle\Command;

use Doctrine\Persistence\ObjectRepository;
use Hackzilla\Bundle\TicketBundle\Manager\UserManagerInterface;
use Hackzilla\Bundle\TicketBundle\Model\UserInterface;

/**
* NEXT_MAJOR: Inject the object repository and the user class directly in the command
* classes and remove this trait.
* NEXT_MAJOR: Inject the user manager directly in the command classes and remove this trait.
*
* @author Javier Spagnoletti <phansys@gmail.com>
*/
trait UserManagerTrait
trait UserManagerAwareTrait
{
/**
* @var ObjectRepository
* @var UserManagerInterface
*/
private $userRepository;
private $userManager;

public function __construct(string $name = null, ?ObjectRepository $userRepository = null)
public function __construct(string $name = null, ?UserManagerInterface $userManager = null)
{
parent::__construct($name);

$this->userRepository = $userRepository;
$this->userManager = $userManager;

if (null === $userRepository) {
if (null === $userManager) {
@trigger_error(sprintf(
'Omitting or passing null as argument 2 for "%s()" is deprecated since hackzilla/ticket-bundle 3.x.',
__METHOD__
Expand All @@ -43,8 +42,8 @@ public function __construct(string $name = null, ?ObjectRepository $userReposito

private function findUser(string $username): ?UserInterface
{
if (null !== $this->userRepository) {
return $this->userRepository->findBy(['username' => $username]);
if (null !== $this->userManager) {
return $this->userManager->findUserByUsername($username);
}

if (!$this->getContainer()->has('fos_user.user_manager')) {
Expand Down
20 changes: 11 additions & 9 deletions EventListener/UserLoad.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace Hackzilla\Bundle\TicketBundle\EventListener;

use Doctrine\ORM\Event\LifecycleEventArgs;
use Hackzilla\Bundle\TicketBundle\Manager\UserManagerInterface;
use Hackzilla\Bundle\TicketBundle\Model\TicketInterface;
use Hackzilla\Bundle\TicketBundle\Model\TicketMessageInterface;

Expand All @@ -20,11 +21,14 @@
*/
class UserLoad
{
protected $userRepository;
/**
* @var UserManagerInterface
*/
protected $userManager;

public function __construct($userRepository)
public function __construct(UserManagerInterface $userManager)
{
$this->userRepository = $userRepository;
$this->userManager = $userManager;
}

public function getSubscribedEvents()
Expand All @@ -38,23 +42,21 @@ public function postLoad(LifecycleEventArgs $args)
{
$entity = $args->getEntity();

// Ignore any entity lifecycle events not relating to this bundles entities.
// Ignore any entity lifecycle events not related to this bundle's entities.
if (!$entity instanceof TicketInterface && !$entity instanceof TicketMessageInterface) {
return;
}

$userRepository = $args->getEntityManager()->getRepository($this->userRepository);

if ($entity instanceof TicketInterface) {
if (null === $entity->getUserCreatedObject()) {
$entity->setUserCreated($userRepository->find($entity->getUserCreated()));
$entity->setUserCreated($this->userManager->getUserById($entity->getUserCreated()));
}
if (null === $entity->getLastUserObject()) {
$entity->setLastUser($userRepository->find($entity->getLastUser()));
$entity->setLastUser($this->userManager->getUserById($entity->getLastUser()));
}
} elseif ($entity instanceof TicketMessageInterface) {
if (null === $entity->getUserObject()) {
$entity->setUser($userRepository->find($entity->getUser()));
$entity->setUser($this->userManager->getUserById($entity->getUser()));
}
}
}
Expand Down
19 changes: 19 additions & 0 deletions Manager/UserManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,15 @@ public function __construct(
AuthorizationCheckerInterface $authorizationChecker
) {
$this->tokenStorage = $tokenStorage;

if (!is_subclass_of($userRepository->getClassName(), UserInterface::class)) {
throw new \InvalidArgumentException(sprintf(
'Argument 2 passed to "%s()" MUST be an object repository for a class implementing "%s".',
__METHOD__,
UserInterface::class
));
}

$this->userRepository = $userRepository;
$this->authorizationChecker = $authorizationChecker;
}
Expand All @@ -58,6 +67,11 @@ public function getCurrentUser()

if ('anon.' === $user) {
$user = 0;
} elseif (!$user instanceof UserInterface) {
throw new \LogicException(sprintf(
'The object representing the authenticated user MUST implement "%s".',
UserInterface::class
));
}

return $user;
Expand Down Expand Up @@ -100,4 +114,9 @@ public function hasPermission($user, TicketInterface $ticket)
throw new AccessDeniedHttpException();
}
}

public function findUserByUsername(string $username): ?UserInterface
{
return $this->userRepository->findOneBy(['username' => $username]);
}
}
6 changes: 6 additions & 0 deletions Manager/UserManagerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
use Hackzilla\Bundle\TicketBundle\Model\TicketInterface;
use Hackzilla\Bundle\TicketBundle\Model\UserInterface;

/**
* @method ?UserInterface findUserByUsername(string $username)
*/
interface UserManagerInterface
{
public function getCurrentUser();
Expand All @@ -26,4 +29,7 @@ public function hasRole(UserInterface $user, $role);
* @param \Hackzilla\Bundle\TicketBundle\Model\UserInterface|string $user
*/
public function hasPermission($user, TicketInterface $ticket);

// NEXT_MAJOR: Uncomment this method.
// public function findUserByUsername(string $username): ?UserInterface;
}
4 changes: 2 additions & 2 deletions Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,14 @@ services:
class: Hackzilla\Bundle\TicketBundle\Command\AutoClosingCommand
arguments:
- null
- '@hackzilla_ticket.user_repository'
- '@hackzilla_ticket.user_manager'
tags:
- { name: console.command, command: 'ticket:autoclosing' }

hackzilla_ticket.command.create:
class: Hackzilla\Bundle\TicketBundle\Command\TicketManagerCommand
arguments:
- null
- '@hackzilla_ticket.user_repository'
- '@hackzilla_ticket.user_manager'
tags:
- { name: console.command, command: 'ticket:create' }
107 changes: 100 additions & 7 deletions Tests/EventListener/UserLoadTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,126 @@

namespace Hackzilla\Bundle\TicketBundle\Tests\EventListener;

use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\Persistence\ObjectManager;
use Hackzilla\Bundle\TicketBundle\Entity\Ticket;
use Hackzilla\Bundle\TicketBundle\Entity\TicketMessage;
use Hackzilla\Bundle\TicketBundle\EventListener\UserLoad;
use Hackzilla\Bundle\TicketBundle\Manager\UserManager;
use Hackzilla\Bundle\TicketBundle\Model\UserInterface;
use Hackzilla\Bundle\TicketBundle\Tests\Functional\Entity\User;
use PHPUnit\Framework\MockObject\MockObject;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

final class UserLoadTest extends WebTestCase
{
private $object;
private const USER_CREATED_ID = 42;
private const LAST_USER_ID = 43;
private const USER_MESSAGE_ID = 44;

/**
* @var UserLoad
*/
private $userLoad;

/**
* @var UserInterface
*/
private $userCreated;

/**
* @var UserInterface
*/
private $lastUser;

/**
* @var UserInterface
*/
private $userMessage;

protected function setUp(): void
{
$this->userCreated = new User();
$this->lastUser = new User();
$this->userMessage = new User();

(\Closure::bind(function ($id): void {
$this->id = $id;
}, $this->userCreated, User::class))(self::USER_CREATED_ID);

(\Closure::bind(function ($id): void {
$this->id = $id;
}, $this->lastUser, User::class))(self::LAST_USER_ID);

(\Closure::bind(function ($id): void {
$this->id = $id;
}, $this->userMessage, User::class))(self::USER_MESSAGE_ID);

$userManager = $this->getUserManagerMock();

$this->object = new UserLoad($userManager);
$this->userLoad = new UserLoad($userManager);
}

protected function tearDown(): void
{
$this->object = null;
$this->userCreated = null;
$this->lastUser = null;
$this->userMessage = null;
$this->userLoad = null;
}

public function getUserManagerMock()
public function testObjectCreated(): void
{
return $this->createMock(UserManager::class);
$this->assertInstanceOf(UserLoad::class, $this->userLoad);
}

public function testObjectCreated()
public function testPostLoad(): void
{
$this->assertInstanceOf(UserLoad::class, $this->object);
$objectManager = $this->createStub(ObjectManager::class);

$ticket = new Ticket();
$ticket->setUserCreated(self::USER_CREATED_ID);
$ticket->setLastUser(self::LAST_USER_ID);

$this->assertNull($ticket->getUserCreatedObject());
$this->assertNull($ticket->getLastUserObject());

$this->userLoad->postLoad(new LifecycleEventArgs($ticket, $objectManager));

$this->assertSame($this->userCreated, $ticket->getUserCreatedObject());
$this->assertSame($this->lastUser, $ticket->getLastUserObject());

$message = new TicketMessage();
$message->setUser(self::USER_MESSAGE_ID);

$this->assertNull($message->getUserObject());

$this->userLoad->postLoad(new LifecycleEventArgs($message, $objectManager));

$this->assertSame($this->userMessage, $message->getUserObject());
}

private function getUserManagerMock(): MockObject
{
$userManager = $this->createMock(UserManager::class);
$userManager
->method('getUserById')
->willReturnCallback(function ($userId): ?UserInterface {
if ($userId === $this->userCreated->getId()) {
return $this->userCreated;
}

if ($userId === $this->lastUser->getId()) {
return $this->lastUser;
}

if ($userId === $this->userMessage->getId()) {
return $this->userMessage;
}

return null;
});

return $userManager;
}
}
2 changes: 1 addition & 1 deletion Tests/Manager/TicketManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/

namespace Hackzilla\Bundle\TicketBundle\Tests\User;
namespace Hackzilla\Bundle\TicketBundle\Tests\Manager;

use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
Expand Down
10 changes: 8 additions & 2 deletions Tests/Manager/UserManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@
* file that was distributed with this source code.
*/

namespace Hackzilla\Bundle\TicketBundle\Tests\User;
namespace Hackzilla\Bundle\TicketBundle\Tests\Manager;

use Doctrine\ORM\EntityRepository;
use Hackzilla\Bundle\TicketBundle\Manager\UserManager;
use Hackzilla\Bundle\TicketBundle\Tests\Functional\Entity\User;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager;
use Symfony\Component\Security\Core\Authentication\Provider\AnonymousAuthenticationProvider;
Expand Down Expand Up @@ -54,6 +55,11 @@ public function testObjectCreated()

private function getMockUserRepository()
{
return $this->createMock(EntityRepository::class);
$userRepository = $this->createMock(EntityRepository::class);
$userRepository
->method('getClassName')
->willReturn(User::class);

return $userRepository;
}
}