324 lines
10 KiB
PHP
324 lines
10 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\Conversation;
|
|
use App\Models\Review;
|
|
use App\Models\User;
|
|
use App\Models\Worker;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Tests\TestCase;
|
|
|
|
class ReportApiTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
protected $worker;
|
|
protected $employer;
|
|
protected $workerToken;
|
|
protected $employerToken;
|
|
protected $category;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
// Create category
|
|
$this->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']);
|
|
}
|
|
}
|
|
|