238 lines
No EOL
6.6 KiB
PHP
238 lines
No EOL
6.6 KiB
PHP
<?php
|
|
|
|
namespace Tests\Unit\Actions\User;
|
|
|
|
use App\Actions\User\CreateUserAction;
|
|
use App\Models\Planner;
|
|
use App\Models\User;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Tests\TestCase;
|
|
|
|
class CreateUserActionTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
private CreateUserAction $action;
|
|
private Planner $planner;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
$this->action = new CreateUserAction();
|
|
|
|
// Create a planner for testing
|
|
$this->planner = Planner::factory()->create();
|
|
}
|
|
|
|
public function test_it_can_create_a_user_successfully(): void
|
|
{
|
|
// Arrange
|
|
$userData = [
|
|
'name' => 'Test User',
|
|
'planner_id' => $this->planner->id,
|
|
];
|
|
|
|
// Act
|
|
$user = $this->action->execute($userData);
|
|
|
|
// Assert
|
|
$this->assertInstanceOf(User::class, $user);
|
|
$this->assertEquals('Test User', $user->name);
|
|
$this->assertEquals($this->planner->id, $user->planner_id);
|
|
$this->assertDatabaseHas('users', [
|
|
'id' => $user->id,
|
|
'name' => 'Test User',
|
|
'planner_id' => $this->planner->id,
|
|
]);
|
|
}
|
|
|
|
public function test_it_throws_exception_when_name_is_empty(): void
|
|
{
|
|
// Arrange
|
|
$userData = [
|
|
'name' => '',
|
|
'planner_id' => $this->planner->id,
|
|
];
|
|
|
|
// Act & Assert
|
|
$this->expectException(\InvalidArgumentException::class);
|
|
$this->expectExceptionMessage('Name is required');
|
|
|
|
$this->action->execute($userData);
|
|
|
|
// Verify no user was created
|
|
$this->assertDatabaseMissing('users', [
|
|
'planner_id' => $this->planner->id,
|
|
]);
|
|
}
|
|
|
|
public function test_it_throws_exception_when_name_is_missing(): void
|
|
{
|
|
// Arrange
|
|
$userData = [
|
|
'planner_id' => $this->planner->id,
|
|
];
|
|
|
|
// Act & Assert
|
|
$this->expectException(\InvalidArgumentException::class);
|
|
$this->expectExceptionMessage('Name is required');
|
|
|
|
$this->action->execute($userData);
|
|
}
|
|
|
|
public function test_it_throws_exception_when_planner_id_is_empty(): void
|
|
{
|
|
// Arrange
|
|
$userData = [
|
|
'name' => 'Test User',
|
|
'planner_id' => '',
|
|
];
|
|
|
|
// Act & Assert
|
|
$this->expectException(\InvalidArgumentException::class);
|
|
$this->expectExceptionMessage('Planner ID is required');
|
|
|
|
$this->action->execute($userData);
|
|
}
|
|
|
|
public function test_it_throws_exception_when_planner_id_is_missing(): void
|
|
{
|
|
// Arrange
|
|
$userData = [
|
|
'name' => 'Test User',
|
|
];
|
|
|
|
// Act & Assert
|
|
$this->expectException(\InvalidArgumentException::class);
|
|
$this->expectExceptionMessage('Planner ID is required');
|
|
|
|
$this->action->execute($userData);
|
|
}
|
|
|
|
public function test_it_logs_creation_process(): void
|
|
{
|
|
// Arrange
|
|
Log::spy();
|
|
$userData = [
|
|
'name' => 'Test User',
|
|
'planner_id' => $this->planner->id,
|
|
];
|
|
|
|
// Act
|
|
$user = $this->action->execute($userData);
|
|
|
|
// Assert
|
|
Log::shouldHaveReceived('info')
|
|
->with('CreateUserAction: Starting user creation', [
|
|
'name' => 'Test User',
|
|
'planner_id' => $this->planner->id,
|
|
]);
|
|
|
|
Log::shouldHaveReceived('info')
|
|
->with('CreateUserAction: User successfully created', [
|
|
'user_id' => $user->id,
|
|
'name' => 'Test User',
|
|
'planner_id' => $this->planner->id,
|
|
]);
|
|
}
|
|
|
|
public function test_it_handles_database_transaction_rollback_on_failure(): void
|
|
{
|
|
// Arrange
|
|
$userData = [
|
|
'name' => 'Test User',
|
|
'planner_id' => 999999, // Non-existent planner ID should cause foreign key constraint error
|
|
];
|
|
|
|
// Act & Assert
|
|
$this->expectException(\Exception::class);
|
|
|
|
try {
|
|
$this->action->execute($userData);
|
|
} catch (\Exception $e) {
|
|
// Verify no user was created (transaction rolled back)
|
|
$this->assertDatabaseMissing('users', [
|
|
'name' => 'Test User',
|
|
]);
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
public function test_it_logs_errors_on_failure(): void
|
|
{
|
|
// Arrange
|
|
Log::spy();
|
|
$userData = [
|
|
'name' => 'Test User',
|
|
'planner_id' => 999999, // Non-existent planner ID
|
|
];
|
|
|
|
// Act & Assert
|
|
try {
|
|
$this->action->execute($userData);
|
|
} catch (\Exception $e) {
|
|
// Expected
|
|
}
|
|
|
|
// Assert
|
|
Log::shouldHaveReceived('error')
|
|
->with('CreateUserAction: User creation failed', \Mockery::on(function ($data) {
|
|
return $data['name'] === 'Test User' &&
|
|
$data['planner_id'] === 999999 &&
|
|
isset($data['error']) &&
|
|
isset($data['trace']);
|
|
}));
|
|
}
|
|
|
|
public function test_it_creates_user_with_whitespace_trimmed_name(): void
|
|
{
|
|
// Arrange
|
|
$userData = [
|
|
'name' => ' Test User ',
|
|
'planner_id' => $this->planner->id,
|
|
];
|
|
|
|
// Act
|
|
$user = $this->action->execute($userData);
|
|
|
|
// Assert
|
|
$this->assertEquals(' Test User ', $user->name); // Should preserve original data as passed
|
|
$this->assertDatabaseHas('users', [
|
|
'id' => $user->id,
|
|
'name' => ' Test User ',
|
|
'planner_id' => $this->planner->id,
|
|
]);
|
|
}
|
|
|
|
public function test_it_can_create_multiple_users_with_same_planner(): void
|
|
{
|
|
// Arrange
|
|
$userData1 = [
|
|
'name' => 'User One',
|
|
'planner_id' => $this->planner->id,
|
|
];
|
|
|
|
$userData2 = [
|
|
'name' => 'User Two',
|
|
'planner_id' => $this->planner->id,
|
|
];
|
|
|
|
// Act
|
|
$user1 = $this->action->execute($userData1);
|
|
$user2 = $this->action->execute($userData2);
|
|
|
|
// Assert
|
|
$this->assertNotEquals($user1->id, $user2->id);
|
|
$this->assertEquals($this->planner->id, $user1->planner_id);
|
|
$this->assertEquals($this->planner->id, $user2->planner_id);
|
|
$this->assertDatabaseHas('users', ['name' => 'User One']);
|
|
$this->assertDatabaseHas('users', ['name' => 'User Two']);
|
|
}
|
|
|
|
protected function tearDown(): void
|
|
{
|
|
\Mockery::close();
|
|
parent::tearDown();
|
|
}
|
|
} |