category = \App\Models\WorkerCategory::create([ 'name' => 'Housemaid', ]); // Create worker $this->workerToken = 'worker-token-xyz'; $this->worker = Worker::create([ 'name' => 'Jane Worker', 'email' => 'jane.worker@example.com', 'phone' => '+971500000001', 'password' => bcrypt('password'), 'api_token' => $this->workerToken, 'status' => 'Available', 'nationality' => 'Ethiopian', 'age' => 28, 'salary' => 1500.00, 'availability' => 'Immediate', 'experience' => '2 Years', 'religion' => 'Christian', 'bio' => 'Experienced housemaid seeking employment.', 'category_id' => $this->category->id, ]); // Create employer user $this->employerToken = 'employer-token-abc'; $this->employer = User::create([ 'name' => 'John Employer', 'email' => 'john.employer@example.com', 'password' => bcrypt('password'), 'role' => 'employer', 'api_token' => $this->employerToken, ]); } /** * Test worker can report a chat conversation. */ public function test_worker_can_report_chat() { $conversation = Conversation::create([ 'employer_id' => $this->employer->id, 'worker_id' => $this->worker->id, ]); $response = $this->withHeaders([ 'Authorization' => 'Bearer ' . $this->workerToken, ])->postJson('/api/workers/report', [ 'type' => 'Chat', 'item_id' => $conversation->id, 'reason' => 'Inappropriate messages', 'description' => 'The employer sent abusive messages.', ]); $response->assertStatus(201) ->assertJson([ 'success' => true, 'message' => 'Report submitted successfully. Our safety team will review it shortly.', ]); $this->assertDatabaseHas('moderation_reports', [ 'type' => 'Chat', 'reported_user_name' => $this->employer->name, 'reported_user_role' => 'Sponsor', 'reported_by_name' => $this->worker->name, 'reported_by_role' => 'Worker', 'reason' => 'Inappropriate messages', 'description' => 'The employer sent abusive messages.', 'status' => 'Pending', ]); $this->assertDatabaseHas('audit_logs', [ 'category' => 'user_activity', 'user' => 'Jane Worker (Worker)', ]); } /** * Test worker can report a review. */ public function test_worker_can_report_review() { $review = Review::create([ 'employer_id' => $this->employer->id, 'worker_id' => $this->worker->id, 'rating' => 1, 'comment' => 'Very bad attitude.', ]); $response = $this->withHeaders([ 'Authorization' => 'Bearer ' . $this->workerToken, ])->postJson('/api/workers/report', [ 'type' => 'Review', 'item_id' => $review->id, 'reason' => 'False accusation', 'description' => 'The review contains false claims.', ]); $response->assertStatus(201) ->assertJson([ 'success' => true, ]); $this->assertDatabaseHas('moderation_reports', [ 'type' => 'Review', 'reported_user_name' => $this->employer->name, 'reported_user_role' => 'Sponsor', 'reported_by_name' => $this->worker->name, 'reported_by_role' => 'Worker', 'reason' => 'False accusation', 'status' => 'Pending', ]); } /** * Test worker reporting non-existent/unauthorized review. */ public function test_worker_report_invalid_review_returns_404() { // Review for a different worker $otherWorker = Worker::create([ 'name' => 'Other Worker', 'email' => 'other@example.com', 'phone' => '+971500000009', 'password' => bcrypt('password'), 'category_id' => $this->category->id, 'nationality' => 'Indian', 'age' => 30, 'salary' => 1800.00, 'availability' => 'Immediate', 'experience' => '3 Years', 'religion' => 'Hindu', 'bio' => 'Experienced helper.', ]); $review = Review::create([ 'employer_id' => $this->employer->id, 'worker_id' => $otherWorker->id, 'rating' => 2, 'comment' => 'Okay review.', ]); $response = $this->withHeaders([ 'Authorization' => 'Bearer ' . $this->workerToken, ])->postJson('/api/workers/report', [ 'type' => 'Review', 'item_id' => $review->id, 'reason' => 'Spam', ]); $response->assertStatus(404); } /** * Test employer can report a chat conversation. */ public function test_employer_can_report_chat() { $conversation = Conversation::create([ 'employer_id' => $this->employer->id, 'worker_id' => $this->worker->id, ]); $response = $this->withHeaders([ 'Authorization' => 'Bearer ' . $this->employerToken, ])->postJson('/api/employers/report', [ 'type' => 'Chat', 'item_id' => $conversation->id, 'reason' => 'Abusive worker', 'description' => 'Worker requested payment outside platform.', ]); $response->assertStatus(201) ->assertJson([ 'success' => true, ]); $this->assertDatabaseHas('moderation_reports', [ 'type' => 'Chat', 'reported_user_name' => $this->worker->name, 'reported_user_role' => 'Worker', 'reported_by_name' => $this->employer->name, 'reported_by_role' => 'Sponsor', 'reason' => 'Abusive worker', 'status' => 'Pending', ]); $this->assertDatabaseHas('audit_logs', [ 'category' => 'user_activity', 'user' => 'John Employer (Sponsor)', ]); } /** * Test employer can report a review. */ public function test_employer_can_report_review() { $review = Review::create([ 'employer_id' => $this->employer->id, 'worker_id' => $this->worker->id, 'rating' => 5, 'comment' => 'Great helper.', ]); $response = $this->withHeaders([ 'Authorization' => 'Bearer ' . $this->employerToken, ])->postJson('/api/employers/report', [ 'type' => 'Review', 'item_id' => $review->id, 'reason' => 'Report my own review mistake', 'description' => 'I selected wrong worker.', ]); $response->assertStatus(201); } /** * Test validation error on invalid input. */ public function test_report_validation_errors() { $response = $this->withHeaders([ 'Authorization' => 'Bearer ' . $this->workerToken, ])->postJson('/api/workers/report', [ 'type' => 'InvalidType', 'item_id' => '', 'reason' => '', ]); $response->assertStatus(422) ->assertJsonValidationErrors(['type', 'item_id', 'reason']); } /** * Test unauthenticated access. */ public function test_report_endpoints_require_auth() { $response = $this->postJson('/api/workers/report', [ 'type' => 'Chat', 'item_id' => 1, 'reason' => 'Abuse', ]); $response->assertStatus(401); } /** * Test retrieving report reasons. */ public function test_get_report_reasons_filtering() { // Clear reasons table and seed specific reasons for testing \DB::table('report_reasons')->truncate(); \DB::table('report_reasons')->insert([ ['reason' => 'Chat Spam', 'status' => 'Active', 'type' => 'Chat'], ['reason' => 'Review Abuse', 'status' => 'Active', 'type' => 'Review'], ['reason' => 'General Impersonation', 'status' => 'Active', 'type' => 'Both'], ['reason' => 'Inactive Reason', 'status' => 'Inactive', 'type' => 'Both'], ]); // 1. Worker retrieves all Active reasons $response = $this->withHeaders([ 'Authorization' => 'Bearer ' . $this->workerToken, ])->getJson('/api/workers/report-reasons'); $response->assertStatus(200) ->assertJsonCount(3, 'reasons') ->assertJsonFragment(['reason' => 'Chat Spam']) ->assertJsonFragment(['reason' => 'Review Abuse']) ->assertJsonFragment(['reason' => 'General Impersonation']) ->assertJsonMissing(['reason' => 'Inactive Reason']); // 2. Worker retrieves Chat reasons only $responseChat = $this->withHeaders([ 'Authorization' => 'Bearer ' . $this->workerToken, ])->getJson('/api/workers/report-reasons?type=Chat'); $responseChat->assertStatus(200) ->assertJsonCount(2, 'reasons') ->assertJsonFragment(['reason' => 'Chat Spam']) ->assertJsonFragment(['reason' => 'General Impersonation']) ->assertJsonMissing(['reason' => 'Review Abuse']); // 3. Worker retrieves Review reasons only $responseReview = $this->withHeaders([ 'Authorization' => 'Bearer ' . $this->workerToken, ])->getJson('/api/workers/report-reasons?type=Review'); $responseReview->assertStatus(200) ->assertJsonCount(2, 'reasons') ->assertJsonFragment(['reason' => 'Review Abuse']) ->assertJsonFragment(['reason' => 'General Impersonation']) ->assertJsonMissing(['reason' => 'Chat Spam']); } }