artisan('db:seed', ['--class' => AnnouncementsDatabaseSeeder::class]); } /** @test */ public function guests_cannot_paginate_announcements() { $this->getJson('/api/announcements')->assertStatus(401); } /** @test */ public function any_authenticated_users_can_paginate_announcements() { $user = UserFactory::user()->create(); $announcements = Announcement::factory()->times(11)->create(); $response = $this->actingAs($user, self::API_GUARD) ->getJson('/api/announcements?per_page=10') ->assertOk(); $transformed = AnnouncementResource::collection($announcements->take(10))->resolve(); $this->assertEquals($response->json('data'), $transformed); $response->assertJson([ 'meta' => [ 'current_page' => 1, 'from' => 1, 'to' => 10, 'last_page' => 2, 'path' => url('api/announcements'), 'total' => 11, 'per_page' => 10, ], ]); } /** @test */ public function paginate_announcements_with_more_records_per_page_than_allowed() { $this->actingAs($this->validUser(), self::API_GUARD) ->getJson('/api/announcements?per_page=140') ->assertStatus(422); } /** @test */ public function guests_cannot_create_announcements() { $this->postJson('/api/announcements', $this->validParams()) ->assertUnauthorized(); $this->assertEquals(0, Announcement::count()); } /** @test */ public function users_without_appropriate_permission_cannot_create_announcements() { $user = UserFactory::user()->create(); $this->actingAs($user, self::API_GUARD) ->postJson('/api/announcements', $this->validParams()) ->assertForbidden(); $this->assertEquals(0, Announcement::count()); } /** @test */ public function users_with_appropriate_permission_can_create_announcements() { $user = $this->validUser(); $data = $this->validParams(); $response = $this->actingAs($user, self::API_GUARD) ->postJson('/api/announcements', $data) ->assertStatus(201); $announcement = Announcement::first(); $response->assertExactJson([ 'data' => (new AnnouncementResource($announcement))->resolve(), ]); $this->assertEquals($user->id, $announcement->user_id); $this->assertEquals($data['title'], $announcement->title); $this->assertEquals($data['body'], $announcement->body); } /** @test */ public function an_email_notification_can_be_triggered_when_an_announcement_is_created() { Mail::fake(); $data = $this->validParams(['email_notification' => true]); $this->actingAs($this->validUser(), self::API_GUARD) ->postJson('/api/announcements', $data) ->assertStatus(201); $announcement = Announcement::first(); Mail::assertQueued(AnnouncementEmail::class, function ($mail) use ($announcement) { return $mail->announcement->id === $announcement->id; }); } /** @test */ public function title_field_is_required_when_creating_an_announcement() { $data = $this->validParams(['title' => '']); $this->actingAs($this->validUser(), self::API_GUARD) ->postJson('/api/announcements', $data) ->assertStatus(422) ->assertJsonValidationErrors('title'); $this->assertEquals(0, Announcement::count()); } /** @test */ public function body_field_is_required_when_creating_an_announcement() { $data = $this->validParams(['body' => '']); $this->actingAs($this->validUser(), self::API_GUARD) ->postJson('/api/announcements', $data) ->assertStatus(422) ->assertJsonValidationErrors('body'); $this->assertEquals(0, Announcement::count()); } /** @test */ public function guests_cannot_view_an_announcement() { $announcement = Announcement::factory()->create(); $this->getJson("/api/announcements/{$announcement->id}") ->assertUnauthorized(); } /** @test */ public function authenticated_users_can_view_any_announcement() { $user = UserFactory::user()->create(); $announcement = Announcement::factory()->create(); $this->actingAs($user, self::API_GUARD) ->getJson("/api/announcements/{$announcement->id}") ->assertOk() ->assertExactJson([ 'data' => (new AnnouncementResource($announcement))->resolve(), ]); } /** @test */ public function guests_cannot_update_an_announcement() { $announcement = Announcement::factory()->create(); $this->putJson("/api/announcements/{$announcement->id}", $this->validParams()) ->assertUnauthorized(); } /** @test */ public function users_without_approprite_permission_cannot_update_an_announcement() { $user = UserFactory::user()->create(); $announcement = Announcement::factory()->create(); $this->actingAs($user, self::API_GUARD) ->putJson("/api/announcements/{$announcement->id}", $this->validParams()) ->assertForbidden(); } /** @test */ public function users_with_approprite_permission_can_update_an_announcement() { $user = $this->validUser(); $announcement = Announcement::factory()->create(); $this->actingAs($user, self::API_GUARD) ->putJson("/api/announcements/{$announcement->id}", $this->validParams()) ->assertOk() ->assertExactJson([ 'data' => (new AnnouncementResource($announcement->fresh()))->resolve(), ]); } /** @test */ public function title_field_is_required_when_updating_an_announcement() { $data = $this->validParams(['title' => '']); $announcement = Announcement::factory()->create(); $this->actingAs($this->validUser(), self::API_GUARD) ->putJson("/api/announcements/{$announcement->id}", $data) ->assertStatus(422) ->assertJsonValidationErrors('title'); } /** @test */ public function body_field_is_required_when_updating_an_announcement() { $data = $this->validParams(['body' => '']); $announcement = Announcement::factory()->create(); $this->actingAs($this->validUser(), self::API_GUARD) ->putJson("/api/announcements/{$announcement->id}", $data) ->assertStatus(422) ->assertJsonValidationErrors('body'); } /** @test */ public function guests_cannot_delete_an_announcement() { $announcement = Announcement::factory()->create(); $this->deleteJson("/api/announcements/{$announcement->id}") ->assertUnauthorized(); } /** @test */ public function users_without_appropriate_permission_cannot_delete_an_announcement() { $user = UserFactory::user()->create(); $announcement = Announcement::factory()->create(); $this->actingAs($user, self::API_GUARD) ->deleteJson("/api/announcements/{$announcement->id}") ->assertForbidden(); } /** @test */ public function users_with_appropriate_permission_can_delete_an_announcement() { $announcement = Announcement::factory()->create(); $this->actingAs($this->validUser(), self::API_GUARD) ->deleteJson("/api/announcements/{$announcement->id}") ->assertOk(); $this->assertNull($announcement->fresh()); } /** @test */ public function user_announcements_can_be_marked_as_read() { $user = UserFactory::user()->create([ 'announcements_last_read_at' => null, ]); Carbon::setTestNow(now()); $this->actingAs($user, self::API_GUARD) ->post('/api/announcements/read'); $this->assertEquals( now()->format('Y-m-d H:i:s'), $user->fresh()->announcements_last_read_at ); } /** * @return mixed */ private function validUser() { return UserFactory::user()->withPermissions('announcements.manage')->create(); } /** * @return array */ private function validParams(array $overrides = []) { return array_merge([ 'title' => 'Foo Announcement', 'body' => 'This is the announcement body.', 'email_notification' => false, ], $overrides); } }