employer = User::create([ 'name' => 'Test Employer', 'email' => 'employer@example.com', 'password' => bcrypt('password'), 'role' => 'employer', ]); // Create worker $this->worker = Worker::create([ 'name' => 'Worker User', 'email' => 'worker@example.com', 'password' => bcrypt('password'), 'phone' => '971501234567', 'nationality' => 'Indian', 'status' => 'active', 'api_token' => 'worker_api_token', 'age' => 25, 'salary' => 2000, 'availability' => 'Immediate', 'experience' => '2 Years', 'religion' => 'Christian', 'bio' => 'Helper info', 'passport_status' => 'valid', ]); // Create job post $this->job = JobPost::create([ 'employer_id' => $this->employer->id, 'title' => 'Test Job', 'location' => 'Dubai', 'salary' => 2500, 'workers_needed' => 1, 'job_type' => 'Full Time', 'start_date' => now()->subMonths(4)->toDateString(), 'description' => 'Test Job Description', 'status' => 'active', ]); } public function test_cannot_review_without_confirmed_hire_and_joining() { // Act: Try to review before any job application is made $response = $this->postJson('/api/workers/reviews', [ 'employer_id' => $this->employer->id, 'job_id' => $this->job->id, 'rating' => 5, 'comment' => 'Great employer!', ], [ 'Authorization' => 'Bearer worker_api_token' ]); $response->assertStatus(403); $response->assertJsonPath('success', false); $response->assertJsonPath('message', 'You can only review employers with a confirmed hire and completed joining.'); } public function test_cannot_review_before_3_months_since_joining() { // Setup job application with hired status but joining_confirmed_at is only 2 months ago JobApplication::create([ 'job_id' => $this->job->id, 'worker_id' => $this->worker->id, 'status' => 'hired', 'joining_confirmed_at' => now()->subMonths(2)->toDateString(), ]); // Act: Try to review $response = $this->postJson('/api/workers/reviews', [ 'employer_id' => $this->employer->id, 'job_id' => $this->job->id, 'rating' => 5, 'comment' => 'Great employer!', ], [ 'Authorization' => 'Bearer worker_api_token' ]); $response->assertStatus(403); $response->assertJsonPath('success', false); $response->assertJsonPath('message', 'You can write a review only after 3 months from the joining date.'); } public function test_can_review_after_3_months_since_joining() { // Setup job application with hired status and joining_confirmed_at 3.5 months ago JobApplication::create([ 'job_id' => $this->job->id, 'worker_id' => $this->worker->id, 'status' => 'hired', 'joining_confirmed_at' => now()->subMonths(3)->subDays(15)->toDateString(), ]); // Act: Post review $response = $this->postJson('/api/workers/reviews', [ 'employer_id' => $this->employer->id, 'job_id' => $this->job->id, 'rating' => 4, 'title' => 'Fair Employer', 'comment' => 'Very good experience overall.', ], [ 'Authorization' => 'Bearer worker_api_token' ]); $response->assertStatus(201); $response->assertJsonPath('success', true); $response->assertJsonPath('data.review.rating', 4); $response->assertJsonPath('data.review.title', 'Fair Employer'); $response->assertJsonPath('data.review.comment', 'Very good experience overall.'); $this->assertDatabaseHas('employer_reviews', [ 'worker_id' => $this->worker->id, 'employer_id' => $this->employer->id, 'job_id' => $this->job->id, 'rating' => 4, 'title' => 'Fair Employer', ]); } public function test_cannot_duplicate_reviews() { // Setup job application JobApplication::create([ 'job_id' => $this->job->id, 'worker_id' => $this->worker->id, 'status' => 'hired', 'joining_confirmed_at' => now()->subMonths(4)->toDateString(), ]); // Submit first review EmployerReview::create([ 'worker_id' => $this->worker->id, 'employer_id' => $this->employer->id, 'job_id' => $this->job->id, 'rating' => 5, 'comment' => 'Nice', ]); // Act: Try to submit duplicate review $response = $this->postJson('/api/workers/reviews', [ 'employer_id' => $this->employer->id, 'job_id' => $this->job->id, 'rating' => 4, 'comment' => 'Another review', ], [ 'Authorization' => 'Bearer worker_api_token' ]); $response->assertStatus(422); $response->assertJsonPath('success', false); $response->assertJsonPath('message', 'You have already submitted a review for this job/employer.'); } public function test_edit_review_within_7_days() { // Setup existing review created now $review = EmployerReview::create([ 'worker_id' => $this->worker->id, 'employer_id' => $this->employer->id, 'job_id' => $this->job->id, 'rating' => 3, 'title' => 'Initial Title', 'comment' => 'Initial Comment', ]); // Act: Edit the review $response = $this->putJson("/api/workers/reviews/{$review->id}", [ 'rating' => 5, 'title' => 'Updated Title', 'comment' => 'Updated Comment Details', ], [ 'Authorization' => 'Bearer worker_api_token' ]); $response->assertStatus(200); $response->assertJsonPath('success', true); $response->assertJsonPath('data.review.rating', 5); $response->assertJsonPath('data.review.title', 'Updated Title'); $response->assertJsonPath('data.review.comment', 'Updated Comment Details'); $this->assertDatabaseHas('employer_reviews', [ 'id' => $review->id, 'rating' => 5, 'title' => 'Updated Title', ]); } public function test_cannot_edit_review_after_7_days() { // Setup existing review created 8 days ago $review = EmployerReview::create([ 'worker_id' => $this->worker->id, 'employer_id' => $this->employer->id, 'job_id' => $this->job->id, 'rating' => 3, 'comment' => 'Initial Comment', ]); // Force creation date to be 8 days ago $review->created_at = now()->subDays(8); $review->save(); // Act: Attempt to edit $response = $this->putJson("/api/workers/reviews/{$review->id}", [ 'rating' => 5, 'comment' => 'Attempted Edit', ], [ 'Authorization' => 'Bearer worker_api_token' ]); $response->assertStatus(403); $response->assertJsonPath('success', false); $response->assertJsonPath('message', 'The 7-day edit window for this review has expired.'); } public function test_view_and_list_reviews() { // Create a review $review = EmployerReview::create([ 'worker_id' => $this->worker->id, 'employer_id' => $this->employer->id, 'job_id' => $this->job->id, 'rating' => 5, 'title' => 'Awesome place', 'comment' => 'Had a wonderful time.', ]); // 1. Get Single Review $response = $this->getJson("/api/workers/reviews/{$review->id}", [ 'Authorization' => 'Bearer worker_api_token' ]); $response->assertStatus(200); $response->assertJsonPath('success', true); $response->assertJsonPath('data.review.title', 'Awesome place'); $response->assertJsonPath('data.review.rating', 5); // 2. List Reviews $response = $this->getJson('/api/workers/reviews', [ 'Authorization' => 'Bearer worker_api_token' ]); $response->assertStatus(200); $response->assertJsonPath('success', true); $response->assertJsonCount(1, 'data.reviews'); $response->assertJsonPath('data.reviews.0.title', 'Awesome place'); } }