<?php

declare(strict_types=1);

namespace CodelyTv\Tests\Backoffice\Auth\Application\Authenticate;

use CodelyTv\Backoffice\Auth\Application\Authenticate\AuthenticateUserCommandHandler;
use CodelyTv\Backoffice\Auth\Application\Authenticate\UserAuthenticator;
use CodelyTv\Backoffice\Auth\Domain\InvalidAuthCredentials;
use CodelyTv\Backoffice\Auth\Domain\InvalidAuthUsername;
use CodelyTv\Tests\Backoffice\Auth\AuthModuleUnitTestCase;
use CodelyTv\Tests\Backoffice\Auth\Domain\AuthUserMother;
use CodelyTv\Tests\Backoffice\Auth\Domain\AuthUsernameMother;

final class AuthenticateUserCommandHandlerTest extends AuthModuleUnitTestCase
{
	private AuthenticateUserCommandHandler|null $handler;

	protected function setUp(): void
	{
		parent::setUp();

		$this->handler = new AuthenticateUserCommandHandler(new UserAuthenticator($this->repository()));
	}

	/** @test */
	public function it_should_authenticate_a_valid_user(): void
	{
		$command = AuthenticateUserCommandMother::create();
		$authUser = AuthUserMother::fromCommand($command);

		$this->shouldSearch($authUser->username(), $authUser);

		$this->dispatch($command, $this->handler);
	}

	/** @test */
	public function it_should_throw_an_exception_when_the_user_does_not_exist(): void
	{
		$this->expectException(InvalidAuthUsername::class);

		$command = AuthenticateUserCommandMother::create();
		$username = AuthUsernameMother::create($command->username());

		$this->shouldSearch($username);

		$this->dispatch($command, $this->handler);
	}

	/** @test */
	public function it_should_throw_an_exception_when_the_password_does_not_math(): void
	{
		$this->expectException(InvalidAuthCredentials::class);

		$command = AuthenticateUserCommandMother::create();
		$authUser = AuthUserMother::create(username: AuthUsernameMother::create($command->username()));

		$this->shouldSearch($authUser->username(), $authUser);

		$this->dispatch($command, $this->handler);
	}
}
