migrant-web/tests/Feature/SponsorAuthApiTest.php
2026-06-08 15:51:51 +05:30

375 lines
13 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\Sponsor;
use App\Models\User;
use App\Models\EmployerProfile;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Hash;
use Tests\TestCase;
class SponsorAuthApiTest extends TestCase
{
use RefreshDatabase;
/**
* Test a pure Sponsor can register with simple info and a license file upload.
*/
public function test_sponsor_can_register_with_license()
{
$licenseFile = UploadedFile::fake()->create('license.pdf', 500, 'application/pdf');
$response = $this->postJson('/api/sponsors/register', [
'full_name' => 'Test Sponsor Organization',
'mobile' => '+971509990001',
'password' => 'securepassword',
'license_file' => $licenseFile,
'organization_name' => 'Charity Co',
'nationality' => 'Emirati',
'city' => 'Abu Dhabi',
]);
$response->assertStatus(201)
->assertJsonStructure([
'success',
'message',
'data' => [
'sponsor' => [
'id',
'full_name',
'mobile',
'organization_name',
'nationality',
'city',
'license_file',
],
'token',
]
]);
$this->assertDatabaseHas('sponsors', [
'mobile' => '+971509990001',
'full_name' => 'Test Sponsor Organization',
]);
}
/**
* Test both Sponsor and Employer can log in using the unified login endpoint.
*/
public function test_unified_login_returns_correct_role_and_data()
{
// 1. Create a pure Sponsor (no User record)
$sponsorUser = Sponsor::create([
'full_name' => 'Sponsor User',
'email' => 'sponsor@example.com',
'mobile' => '+971509991111',
'password' => Hash::make('password123'),
'license_file' => 'uploads/licenses/fake.pdf',
'status' => 'active',
]);
// 2. Create an Employer (has both User and Sponsor records, legacy setup)
$employerUser = User::create([
'name' => 'Employer User',
'email' => 'employer@example.com',
'password' => Hash::make('password123'),
'role' => 'employer',
'api_token' => 'old_token',
]);
EmployerProfile::create([
'user_id' => $employerUser->id,
'company_name' => 'Employer Corp',
'phone' => '+971509992222',
'country' => 'United Arab Emirates',
'verification_status' => 'approved',
]);
Sponsor::create([
'full_name' => 'Employer User',
'email' => 'employer@example.com',
'mobile' => '+971509992222',
'password' => $employerUser->password,
'status' => 'active',
]);
// --- Test Sponsor Login via /api/employers/login ---
$responseSponsor = $this->postJson('/api/employers/login', [
'mobile' => '+971509991111',
'password' => 'password123',
]);
$responseSponsor->assertStatus(200)
->assertJson([
'success' => true,
'role' => 'sponsor',
])
->assertJsonStructure([
'data' => [
'sponsor',
'token',
]
]);
// --- Test Employer Login via /api/employers/login ---
$responseEmployer = $this->postJson('/api/employers/login', [
'mobile' => '+971509992222',
'password' => 'password123',
]);
$responseEmployer->assertStatus(200)
->assertJson([
'success' => true,
'role' => 'employer',
])
->assertJsonStructure([
'data' => [
'employer' => [
'id',
'name',
'email',
'employer_profile',
],
'token',
]
]);
}
/**
* Test that pure sponsors can only access their limited routes.
*/
public function test_sponsor_restricted_access()
{
$sponsor = Sponsor::create([
'full_name' => 'Pure Sponsor',
'email' => 'pure_sponsor@example.com',
'mobile' => '+971509993333',
'password' => Hash::make('password123'),
'api_token' => 'sponsor_token_abc',
'status' => 'active',
]);
// Access dashboard successfully
$responseDash = $this->withHeaders([
'Authorization' => 'Bearer sponsor_token_abc',
])->getJson('/api/sponsors/dashboard');
$responseDash->assertStatus(200);
// Try to access employer protected route (should get blocked as they don't have employer token/role)
$responseEmployerRoute = $this->withHeaders([
'Authorization' => 'Bearer sponsor_token_abc',
])->getJson('/api/employers/profile');
$responseEmployerRoute->assertStatus(401);
}
/**
* Test that a sponsor can post a charity event.
*/
public function test_sponsor_can_post_charity_event()
{
$sponsor = Sponsor::create([
'full_name' => 'Test Sponsor',
'organization_name' => 'Save the Children',
'email' => 'tsponsor@example.com',
'mobile' => '+971509994444',
'password' => Hash::make('password123'),
'api_token' => 'sponsor_token_xyz',
'status' => 'active',
]);
$response = $this->withHeaders([
'Authorization' => 'Bearer sponsor_token_xyz',
])->postJson('/api/sponsors/charity-events', [
'title' => 'Community Ramadan Iftar',
'body' => 'Join us for a free community Iftar gathering at the center.',
'type' => 'charity',
]);
$response->assertStatus(201)
->assertJson([
'success' => true,
'message' => 'Charity event posted successfully.',
])
->assertJsonStructure([
'data' => [
'id',
'title',
'body',
'type',
'posted_by',
'organization',
'created_at',
]
]);
$this->assertDatabaseHas('announcements', [
'title' => 'Community Ramadan Iftar',
'sponsor_id' => $sponsor->id,
'status' => 'pending',
]);
}
/**
* Test that a sponsor can list charity events showing both employer and sponsor events.
*/
public function test_sponsor_can_list_charity_events()
{
$sponsor = Sponsor::create([
'full_name' => 'Test Sponsor',
'organization_name' => 'Save the Children',
'email' => 'tsponsor@example.com',
'mobile' => '+971509994444',
'password' => Hash::make('password123'),
'api_token' => 'sponsor_token_xyz',
'status' => 'active',
]);
// Post a sponsor announcement
\App\Models\Announcement::create([
'title' => 'Sponsor Event',
'body' => 'Body of sponsor event',
'type' => 'charity',
'sponsor_id' => $sponsor->id,
'status' => 'approved',
]);
// Post an employer announcement
$employer = User::create([
'name' => 'Employer User',
'email' => 'employer@example.com',
'password' => Hash::make('password123'),
'role' => 'employer',
]);
EmployerProfile::create([
'user_id' => $employer->id,
'company_name' => 'Employer Co',
'phone' => '+971509995555',
'country' => 'United Arab Emirates',
]);
\App\Models\Announcement::create([
'title' => 'Employer Event',
'body' => 'Body of employer event',
'type' => 'charity',
'employer_id' => $employer->id,
'status' => 'approved',
]);
$response = $this->withHeaders([
'Authorization' => 'Bearer sponsor_token_xyz',
])->getJson('/api/sponsors/charity-events');
$response->assertStatus(200)
->assertJson([
'success' => true,
]);
$events = $response->json('data.events');
$this->assertCount(2, $events);
// Verify sponsor event details
$this->assertEquals('Sponsor Event', $events[0]['title']);
$this->assertEquals('Test Sponsor', $events[0]['posted_by']);
$this->assertEquals('Save the Children', $events[0]['organization']);
// Verify employer event details
$this->assertEquals('Employer Event', $events[1]['title']);
$this->assertEquals('Employer User', $events[1]['posted_by']);
$this->assertEquals('Employer Co', $events[1]['organization']);
}
/**
* Test that sponsor dashboard returns correct employer and worker counts.
*/
public function test_sponsor_dashboard_returns_stats()
{
$sponsor = Sponsor::create([
'full_name' => 'Test Sponsor',
'organization_name' => 'Save the Children',
'email' => 'tsponsor@example.com',
'mobile' => '+971509994444',
'password' => Hash::make('password123'),
'api_token' => 'sponsor_token_xyz',
'status' => 'active',
]);
// Create some employers (Users with role = employer)
User::create([
'name' => 'Emp 1',
'email' => 'emp1@example.com',
'password' => Hash::make('password123'),
'role' => 'employer',
'subscription_status' => 'active',
]);
User::create([
'name' => 'Emp 2',
'email' => 'emp2@example.com',
'password' => Hash::make('password123'),
'role' => 'employer',
'subscription_status' => 'none',
]);
$category = \App\Models\WorkerCategory::create([
'name' => 'Housemaid',
]);
// Create some workers
\App\Models\Worker::create([
'name' => 'Worker 1',
'email' => 'w1@example.com',
'phone' => '+971509998881',
'password' => Hash::make('password123'),
'status' => 'active',
'language' => 'en',
'nationality' => 'Indian',
'city' => 'Dubai',
'age' => 25,
'salary' => 1500,
'experience' => 'None',
'religion' => 'Christian',
'bio' => 'Test',
'category_id' => $category->id,
'availability' => 'Immediate',
]);
\App\Models\Worker::create([
'name' => 'Worker 2',
'email' => 'w2@example.com',
'phone' => '+971509998882',
'password' => Hash::make('password123'),
'status' => 'hidden',
'language' => 'en',
'nationality' => 'Indian',
'city' => 'Dubai',
'age' => 25,
'salary' => 1500,
'experience' => 'None',
'religion' => 'Christian',
'bio' => 'Test',
'category_id' => $category->id,
'availability' => 'Immediate',
]);
$response = $this->withHeaders([
'Authorization' => 'Bearer sponsor_token_xyz',
])->getJson('/api/sponsors/dashboard');
$response->assertStatus(200)
->assertJson([
'success' => true,
'data' => [
'employer_stats' => [
'total' => 2,
'active' => 1,
],
'worker_stats' => [
'total' => 2,
'active' => 1,
],
],
]);
}
}