getJson('/api/tasks') ->assertUnauthorized(); $this->postJson('/api/tasks') ->assertUnauthorized(); } public function test_authenticated_user_can_create_task(): void { $user = User::factory()->create(); Sanctum::actingAs($user); $payload = [ 'title' => 'Новая задача', 'description' => 'Описание задачи', 'status' => TaskStatus::PENDING, 'due_date' => now()->addDay()->toDateString(), ]; $response = $this->postJson('/api/tasks', $payload); $response ->assertCreated() ->assertJsonFragment([ 'title' => 'Новая задача', 'status' => TaskStatus::PENDING, ]); $this->assertDatabaseHas('tasks', [ 'title' => 'Новая задача', 'user_id' => $user->id, ]); } /** * @throws Throwable */ public function test_authenticated_user_can_create_task_and_notification_is_queued(): void { Notification::fake(); $user = User::factory()->create(); Sanctum::actingAs($user); $payload = [ 'title' => 'Новая задача', 'description' => 'Описание задачи', 'status' => TaskStatus::PENDING, 'due_date' => now()->addDay()->toDateString(), ]; $response = $this->postJson('/api/tasks', $payload); $response ->assertCreated() ->assertHeader('Location') ->assertJsonFragment([ 'title' => 'Новая задача', 'status' => TaskStatus::PENDING, ]); $task = Task::where('title', 'Новая задача')->firstOrFail(); Notification::assertSentTo( $user, TaskCreatedNotification::class, function (TaskCreatedNotification $notification) use ($task) { return $notification->task->id === $task->id; } ); } public function test_user_cannot_access_task_of_another_user(): void { $owner = User::factory()->create(); $wrong = User::factory()->create(); /** * @var Task $task */ $task = Task::factory()->for($owner)->create(); Sanctum::actingAs($wrong); $this->getJson("/api/tasks/$task->id") ->assertForbidden(); $this->putJson("/api/tasks/$task->id", [ 'title' => 'йоу', ])->assertForbidden(); $this->deleteJson("/api/tasks/$task->id") ->assertForbidden(); } /** * @throws Throwable */ public function test_overdue_task_sends_notification(): void { Notification::fake(); $user = User::factory()->create(); /** * @var Task $task */ $task = Task::factory()->for($user)->create([ 'status' => TaskStatus::PENDING, 'due_date' => now()->subDay(), 'notified_at' => null, ]); $this->artisan('tasks:notify-overdue') ->assertExitCode(0); Notification::assertSentTo( $user, TaskOverdueNotification::class, fn($notification) => $notification->task->id === $task->id ); } public function test_real_user_can_login_and_create_task(): void { $user = User::where('email', 'yo_yo@example.com')->first(); $loginResponse = $this->postJson('/api/login', [ 'email' => 'yo_yo@example.com', 'password' => '123', ]); $loginResponse->assertOk(); $token = $loginResponse->json('token'); $this->assertNotEmpty($token); $payload = [ 'title' => '123 задача', 'description' => 'Описание реальной задачи', 'status' => TaskStatus::PENDING, 'due_date' => now()->addDay()->toDateString(), ]; $taskResponse = $this->withHeader('Authorization', "Bearer $token") ->postJson('/api/tasks', $payload); $taskResponse ->assertCreated() ->assertJsonFragment([ 'title' => '123 задача', 'status' => TaskStatus::PENDING, ]); $this->assertDatabaseHas('tasks', [ 'title' => '123 задача', 'user_id' => $user->id, ]); } public function test_authenticated_user_can_list_tasks(): void { $user = User::factory()->create(); Task::factory(3)->for($user)->create(); Sanctum::actingAs($user); $response = $this->getJson('/api/tasks'); $response->assertOk() ->assertJsonStructure([ 'data' => [ '*' => [ 'id', 'title', 'description', 'status', 'due_date', 'created_at', 'updated_at', ] ], 'links', 'meta', ]); } }