employer = User::create([ 'name' => 'Employer User', 'email' => 'employer@example.com', 'password' => bcrypt('password'), 'role' => 'employer', 'subscription_status' => 'expired', 'subscription_expires_at' => null, ]); } public function test_purchase_when_no_active_subscription_activates_immediately() { $response = $this->actingAs($this->employer)->postJson(route('employer.subscription.purchase'), [ 'plan_id' => 'premium', ]); $response->assertStatus(200); $response->assertJsonPath('success', true); // Assert subscription is active $this->assertDatabaseHas('subscriptions', [ 'user_id' => $this->employer->id, 'plan_id' => 'premium', 'status' => 'active', ]); $this->employer->refresh(); $this->assertEquals('active', $this->employer->subscription_status); $this->assertNotNull($this->employer->subscription_expires_at); } public function test_purchase_when_active_subscription_exists_queues_pending() { // 1. Create active subscription $activeSub = Subscription::create([ 'user_id' => $this->employer->id, 'plan_id' => 'basic', 'amount_aed' => 99.00, 'starts_at' => now(), 'expires_at' => now()->addDays(30), 'status' => 'active', ]); $this->employer->update([ 'subscription_status' => 'active', 'subscription_expires_at' => $activeSub->expires_at, ]); // 2. Purchase another subscription $response = $this->actingAs($this->employer)->postJson(route('employer.subscription.purchase'), [ 'plan_id' => 'premium', ]); $response->assertStatus(200); // Assert new subscription is pending and queued chronologically $this->assertDatabaseHas('subscriptions', [ 'user_id' => $this->employer->id, 'plan_id' => 'premium', 'status' => 'pending', 'starts_at' => $activeSub->expires_at, ]); // User should still have active status with previous expiry $this->employer->refresh(); $this->assertEquals('active', $this->employer->subscription_status); $this->assertEquals($activeSub->expires_at->toDateTimeString(), $this->employer->subscription_expires_at->toDateTimeString()); } public function test_pending_subscription_activates_when_active_expires() { // 1. Create active subscription expiring in the past $expiredSub = Subscription::create([ 'user_id' => $this->employer->id, 'plan_id' => 'basic', 'amount_aed' => 99.00, 'starts_at' => now()->subDays(40), 'expires_at' => now()->subDays(10), // expired 10 days ago 'status' => 'active', ]); // 2. Create pending subscription queued to start when expired sub ended $pendingSub = Subscription::create([ 'user_id' => $this->employer->id, 'plan_id' => 'premium', 'amount_aed' => 199.00, 'starts_at' => $expiredSub->expires_at, 'expires_at' => $expiredSub->expires_at->copy()->addDays(30), 'status' => 'pending', ]); $this->employer->update([ 'subscription_status' => 'active', 'subscription_expires_at' => $expiredSub->expires_at, ]); // 3. Trigger check and activate routine User::checkAndActivatePendingSubscriptions($this->employer->id); // 4. Assert expired sub is set to expired $expiredSub->refresh(); $this->assertEquals('expired', $expiredSub->status); // 5. Assert pending sub is now active $pendingSub->refresh(); $this->assertEquals('active', $pendingSub->status); // 6. Assert user is active and has new expires_at set starting from now $this->employer->refresh(); $this->assertEquals('active', $this->employer->subscription_status); $this->assertTrue($this->employer->subscription_expires_at > now()); } public function test_expired_subscription_restricts_access_and_redirects_to_subscription_plans() { // 1. Create expired subscription Subscription::create([ 'user_id' => $this->employer->id, 'plan_id' => 'basic', 'amount_aed' => 99.00, 'starts_at' => now()->subDays(40), 'expires_at' => now()->subDays(10), // expired 10 days ago 'status' => 'expired', ]); $this->employer->update([ 'subscription_status' => 'expired', 'subscription_expires_at' => now()->subDays(10), ]); // 2. Try to view dashboard - should redirect to subscription $response = $this->actingAs($this->employer) ->withSession(['user' => $this->employer]) ->get('/employer/dashboard'); $response->assertRedirect(route('employer.subscription')); // 3. Accessing subscription page itself is allowed $subResponse = $this->actingAs($this->employer) ->withSession(['user' => $this->employer]) ->get(route('employer.subscription')); $subResponse->assertStatus(200); } public function test_contact_limit_blocks_new_conversations_but_allows_existing_ones() { // 1. Create a custom plan with max_contact_people = 2 Plan::create([ 'id' => 'test-plan-2', 'name' => 'Test Plan 2', 'price' => 10.00, 'duration' => 'Monthly', 'features' => ['Feature 1'], 'max_contact_people' => 2, 'unlimited_contacts' => false, 'enable_job_apply' => true, 'status' => 'Active', ]); Subscription::create([ 'user_id' => $this->employer->id, 'plan_id' => 'test-plan-2', 'amount_aed' => 10.00, 'starts_at' => now(), 'expires_at' => now()->addDays(30), 'status' => 'active', ]); $this->employer->update([ 'subscription_status' => 'active', 'subscription_expires_at' => now()->addDays(30), ]); // Create 3 workers $worker1 = \App\Models\Worker::create(['name' => 'Worker One', 'email' => 'w1@ex.com', 'phone' => '1111111', 'nationality' => 'Indian', 'status' => 'active', 'passport_status' => 'valid', 'age' => 25, 'salary' => 1500, 'availability' => 'Immediate', 'experience' => '2 Years', 'religion' => 'Christian', 'bio' => 'Helper']); $worker2 = \App\Models\Worker::create(['name' => 'Worker Two', 'email' => 'w2@ex.com', 'phone' => '2222222', 'nationality' => 'Indian', 'status' => 'active', 'passport_status' => 'valid', 'age' => 26, 'salary' => 1600, 'availability' => 'Immediate', 'experience' => '2 Years', 'religion' => 'Christian', 'bio' => 'Helper']); $worker3 = \App\Models\Worker::create(['name' => 'Worker Three', 'email' => 'w3@ex.com', 'phone' => '3333333', 'nationality' => 'Indian', 'status' => 'active', 'passport_status' => 'valid', 'age' => 27, 'salary' => 1700, 'availability' => 'Immediate', 'experience' => '2 Years', 'religion' => 'Christian', 'bio' => 'Helper']); // 2. Contact worker 1 -> Allowed $response1 = $this->actingAs($this->employer) ->withSession(['user' => $this->employer]) ->get(route('employer.messages.start', ['workerId' => $worker1->id])); $response1->assertRedirect(); $this->assertDatabaseHas('conversations', [ 'employer_id' => $this->employer->id, 'worker_id' => $worker1->id, ]); // 3. Contact worker 2 -> Allowed $response2 = $this->actingAs($this->employer) ->withSession(['user' => $this->employer]) ->get(route('employer.messages.start', ['workerId' => $worker2->id])); $response2->assertRedirect(); $this->assertDatabaseHas('conversations', [ 'employer_id' => $this->employer->id, 'worker_id' => $worker2->id, ]); // 4. Contact worker 3 -> Blocked (limit reached) $response3 = $this->actingAs($this->employer) ->withSession(['user' => $this->employer]) ->get(route('employer.messages.start', ['workerId' => $worker3->id])); $response3->assertRedirect(route('employer.subscription')); $response3->assertSessionHas('error'); $this->assertDatabaseMissing('conversations', [ 'employer_id' => $this->employer->id, 'worker_id' => $worker3->id, ]); // 5. Contact worker 1 again -> Allowed (already contacted) $response4 = $this->actingAs($this->employer) ->withSession(['user' => $this->employer]) ->get(route('employer.messages.start', ['workerId' => $worker1->id])); $response4->assertRedirect(); } public function test_api_expired_subscription_blocks_access() { $token = 'test_api_token_123'; $this->employer->update([ 'api_token' => $token, 'subscription_status' => 'expired', ]); // Access API dashboard -> Should get 403 Forbidden $response = $this->getJson('/api/employers/dashboard', [ 'Authorization' => 'Bearer ' . $token, ]); $response->assertStatus(403); $response->assertJsonPath('success', false); } }