diff --git a/database/factories/CommentFactory.php b/database/factories/CommentFactory.php index e9809318..4bcb9d82 100644 --- a/database/factories/CommentFactory.php +++ b/database/factories/CommentFactory.php @@ -70,6 +70,7 @@ public function definition(): array public function configure() { + // TODO: Consider making the increment part of the dispatch event? return $this->afterCreating(function (Comment $comment) { if ($comment->root_comment_id) { Comment::where('id', $comment->root_comment_id) diff --git a/database/factories/ComputerScienceResourceFactory.php b/database/factories/ComputerScienceResourceFactory.php index 818b1444..85f56495 100644 --- a/database/factories/ComputerScienceResourceFactory.php +++ b/database/factories/ComputerScienceResourceFactory.php @@ -28,7 +28,7 @@ public function definition(): array return [ 'name' => fake()->name(), 'description' => fake()->realText(), - 'user_id' => User::all()->random()->id, + 'user_id' => User::inRandomOrder()->first() ?? User::factory()->create(), 'image_url' => 'https://cdn.iconscout.com/icon/free/png-256/free-leetcode-logo-icon-download-in-svg-png-gif-file-formats--technology-social-media-company-vol-1-pack-logos-icons-3030025.png', 'page_url' => fake()->url(), diff --git a/tests/Feature/CommentsTest.php b/tests/Feature/CommentsTest.php index 9b07669d..be52eda7 100644 --- a/tests/Feature/CommentsTest.php +++ b/tests/Feature/CommentsTest.php @@ -84,7 +84,6 @@ public function test_cannot_comment_on_non_existent_resource() /** * Test that commenting works on all commentable types defined in config. */ - // TODO: public function test_can_comment_all_commentable_types() { $user = User::factory()->create(); diff --git a/tests/Feature/ResourceReviewsTest.php b/tests/Feature/ResourceReviewsTest.php index 8be0005a..09d58ab1 100644 --- a/tests/Feature/ResourceReviewsTest.php +++ b/tests/Feature/ResourceReviewsTest.php @@ -2,29 +2,134 @@ namespace Tests\Feature; +use App\Models\ComputerScienceResource; +use App\Models\User; use Illuminate\Foundation\Testing\RefreshDatabase; -use Illuminate\Foundation\Testing\WithFaker; use Tests\TestCase; +use Tests\TestResources\ResourceReviewTestResource; class ResourceReviewsTest extends TestCase { - /** - * A basic feature test example. - */ + use RefreshDatabase; + public function test_example(): void { $response = $this->get('/'); - $response->assertStatus(200); } - // Test this: - // Cannot post any form of invalid data - // Do 3 tests of invalid data testing - + public function test_invalid_data_missing_required_fields(): void + { + $user = User::factory()->create(); + $resource = ComputerScienceResource::factory()->create(); + + $invalidData = ResourceReviewTestResource::fake(); + unset($invalidData['title'], $invalidData['description']); + + $response = $this->actingAs($user) + ->post(route('reviews.store', $resource), $invalidData); + + $response->assertSessionHasErrors(['title', 'description']); + } + + public function test_invalid_data_invalid_rating(): void + { + $user = User::factory()->create(); + $resource = ComputerScienceResource::factory()->create(); + + $invalidData = ResourceReviewTestResource::fake(); + $invalidData['community'] = 0; + + $response = $this->actingAs($user) + ->post(route('reviews.store', $resource), $invalidData); + + $response->assertSessionHasErrors(['community']); + } + + public function test_invalid_data_invalid_pros_field(): void + { + $user = User::factory()->create(); + $resource = ComputerScienceResource::factory()->create(); + + $invalidData = ResourceReviewTestResource::fake(); + $invalidData['pros'] = 'Not an array'; + + $response = $this->actingAs($user) + ->post(route('reviews.store', $resource), $invalidData); + + $response->assertSessionHasErrors(['pros']); + } + + public function test_resource_review_can_be_posted(): void + { + $user = User::factory()->create(); + $resource = ComputerScienceResource::factory()->create(); + + $data = ResourceReviewTestResource::fake(); + + $response = $this->actingAs($user) + ->post(route('reviews.store', $resource), $data); + + $response->assertRedirect(route('resources.show', ['computerScienceResource' => $resource->id])) + ->assertSessionHas('success', 'Review created successfully!'); + + $this->assertDatabaseHas('resource_reviews', [ + 'computer_science_resource_id' => $resource->id, + 'title' => $data['title'] + ]); + } + + public function test_resource_average_has_changed(): void + { + $user = User::factory()->create(); + $resource = ComputerScienceResource::factory()->create(); + + $data = ResourceReviewTestResource::fake(); - // test that the resource's average has changed + $this->actingAs($user) + ->post(route('reviews.store', $resource), $data); - // Test that the resource review can be posted - // + $this->assertDatabaseHas('resource_review_summaries', [ + 'computer_science_resource_id' => $resource->id, + 'community' => $data['community'], + 'teaching_clarity' => $data['teaching_clarity'], + 'engagement' => $data['engagement'], + 'practicality' => $data['practicality'], + 'user_friendliness' => $data['user_friendliness'], + 'updates' => $data['updates'], + 'review_count' => 1, + ]); + } + + public function test_resource_review_average_updates_correctly(): void + { + $resource = ComputerScienceResource::factory()->create(); + $total = [ + 'community' => 0, + 'teaching_clarity' => 0, + 'engagement' => 0, + 'practicality' => 0, + 'user_friendliness' => 0, + 'updates' => 0, + ]; + + $reviewCount = 5; + + for ($i = 0; $i < $reviewCount; $i++) { + $user = User::factory()->create(); + $data = ResourceReviewTestResource::fake(); + + // Add to total for averaging later + foreach (array_keys($total) as $key) { + $total[$key] += $data[$key]; + } + + $this->actingAs($user)->post(route('reviews.store', $resource), $data); + } + + $this->assertDatabaseHas('resource_review_summaries', array_merge([ + 'computer_science_resource_id' => $resource->id, + 'review_count' => $reviewCount, + ], $total)); + } } diff --git a/tests/TestResources/ComputerScienceResourceTestResource.php b/tests/TestResources/ComputerScienceResourceTestResource.php index 4268842d..77f0f3c1 100644 --- a/tests/TestResources/ComputerScienceResourceTestResource.php +++ b/tests/TestResources/ComputerScienceResourceTestResource.php @@ -3,6 +3,7 @@ namespace Tests\TestResources; use App\Models\ComputerScienceResource; +use Event; use Illuminate\Http\Request; use Illuminate\Http\Resources\Json\JsonResource; @@ -26,7 +27,8 @@ public function toArray(Request $request): array public static function fake(): array { - $model = ComputerScienceResource::factory()->create(); + // Create the model with disabled events + $model = Event::fakeFor(fn() => ComputerScienceResource::factory()->create()); // Transform it to API form $formData = (new self($model))->toArray(request()); diff --git a/tests/TestResources/ResourceReviewTestResource.php b/tests/TestResources/ResourceReviewTestResource.php new file mode 100644 index 00000000..d9a5f8eb --- /dev/null +++ b/tests/TestResources/ResourceReviewTestResource.php @@ -0,0 +1,41 @@ + $this->title, + 'description'=> $this->description, + 'community'=> $this->community, + 'teaching_clarity'=> $this->teaching_clarity, + 'engagement'=> $this->engagement, + 'practicality'=> $this->practicality, + 'user_friendliness'=> $this->user_friendliness, + 'updates'=> $this->updates, + 'pros'=> $this->pros, + 'cons'=> $this->cons, + ]; + } + + public static function fake(): array + { + // Create the model with disabled events + $model = Event::fakeFor(fn() => ResourceReview::factory()->create()); + + // Transform it to API form + $formData = (new self($model))->toArray(request()); + + // Delete after getting the array to avoid polluting the DB + $model->delete(); + + return $formData; + } +}