119 خطوط
4.9 KiB
PHP
119 خطوط
4.9 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\Attachment;
|
|
use App\Models\Company;
|
|
use App\Models\Contact;
|
|
use App\Models\ContactPhone;
|
|
use App\Models\Deal;
|
|
use App\Models\Lead;
|
|
use App\Models\Team;
|
|
use App\Models\User;
|
|
use Database\Seeders\RolePermissionSeeder;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Tests\TestCase;
|
|
|
|
class CoreCrmAuthorizationTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
$this->seed(RolePermissionSeeder::class);
|
|
}
|
|
|
|
public function test_agent_cannot_access_core_records_owned_by_another_agent(): void
|
|
{
|
|
$agent = $this->user('agent');
|
|
$otherAgent = $this->user('agent');
|
|
$lead = $this->lead($otherAgent);
|
|
$company = Company::create(['name' => 'Private Company', 'owner_id' => $otherAgent->id, 'created_by' => $otherAgent->id]);
|
|
$deal = Deal::create(['title' => 'Private Deal', 'owner_id' => $otherAgent->id, 'lead_id' => $lead->id, 'created_by' => $otherAgent->id]);
|
|
$contact = Contact::create(['name' => 'Private Contact', 'lead_id' => $lead->id, 'company_id' => $company->id, 'created_by' => $otherAgent->id]);
|
|
ContactPhone::create(['contact_id' => $contact->id, 'phone' => '09120000002', 'type' => 'mobile', 'status' => 'active']);
|
|
$attachment = Attachment::create([
|
|
'attachable_type' => Company::class,
|
|
'attachable_id' => $company->id,
|
|
'uploaded_by' => $otherAgent->id,
|
|
'original_name' => 'private.pdf',
|
|
'path' => 'attachments/private.pdf',
|
|
'mime_type' => 'application/pdf',
|
|
'size' => 10,
|
|
]);
|
|
|
|
$this->actingAs($agent)->getJson("/api/companies/{$company->id}")->assertForbidden();
|
|
$this->actingAs($agent)->getJson("/api/deals/{$deal->id}")->assertForbidden();
|
|
$this->actingAs($agent)->putJson("/api/contacts/{$contact->id}", ['name' => 'Tampered'])->assertForbidden();
|
|
$this->actingAs($agent)->postJson('/api/notes', [
|
|
'entity_type' => 'lead',
|
|
'entity_id' => $lead->id,
|
|
'content' => 'Unauthorized note',
|
|
])->assertForbidden();
|
|
$this->actingAs($agent)->getJson("/api/timeline?entity_type=lead&entity_id={$lead->id}")->assertForbidden();
|
|
$this->actingAs($agent)->getJson("/api/attachments?entity_type=company&entity_id={$company->id}")->assertForbidden();
|
|
$this->actingAs($agent)->getJson("/api/attachments/{$attachment->id}/download")->assertForbidden();
|
|
|
|
$contacts = $this->actingAs($agent)->getJson('/api/contacts')->assertOk();
|
|
$this->assertNotContains($contact->id, collect($contacts->json('data'))->pluck('id')->all());
|
|
}
|
|
|
|
public function test_duplicate_check_does_not_disclose_out_of_scope_lead(): void
|
|
{
|
|
$agent = $this->user('agent');
|
|
$otherAgent = $this->user('agent');
|
|
$lead = $this->lead($otherAgent, ['phone' => '09125556677', 'company' => 'Hidden Corp']);
|
|
|
|
$response = $this->actingAs($agent)->postJson('/api/duplicates/check', [
|
|
'entity_type' => 'lead',
|
|
'phone' => '09125556677',
|
|
])->assertOk();
|
|
|
|
$this->assertNotContains($lead->id, collect($response->json('data'))->pluck('id')->all());
|
|
}
|
|
|
|
public function test_supervisor_can_access_team_records_but_not_other_teams(): void
|
|
{
|
|
$supervisor = $this->user('supervisor');
|
|
$teamAgent = $this->user('agent');
|
|
$otherAgent = $this->user('agent');
|
|
$team = Team::create(['name' => 'Own Team', 'supervisor_id' => $supervisor->id, 'is_active' => true]);
|
|
$otherTeam = Team::create(['name' => 'Other Team', 'is_active' => true]);
|
|
$supervisor->teams()->attach($team);
|
|
$teamAgent->teams()->attach($team);
|
|
$otherAgent->teams()->attach($otherTeam);
|
|
|
|
$teamLead = $this->lead($teamAgent, ['team_id' => $team->id]);
|
|
$otherLead = $this->lead($otherAgent, ['team_id' => $otherTeam->id]);
|
|
|
|
$this->actingAs($supervisor)->getJson("/api/leads/{$teamLead->id}")->assertOk();
|
|
$this->actingAs($supervisor)->getJson("/api/leads/{$otherLead->id}")->assertForbidden();
|
|
$this->actingAs($supervisor)->postJson('/api/notes', [
|
|
'entity_type' => 'lead',
|
|
'entity_id' => $otherLead->id,
|
|
'content' => 'Unauthorized supervisor note',
|
|
])->assertForbidden();
|
|
}
|
|
|
|
private function user(string $role): User
|
|
{
|
|
$user = User::factory()->create(['is_active' => true]);
|
|
$user->assignRole($role);
|
|
|
|
return $user;
|
|
}
|
|
|
|
private function lead(User $agent, array $attributes = []): Lead
|
|
{
|
|
return Lead::create(array_merge([
|
|
'company' => 'Scoped Company',
|
|
'first_name' => 'Ali',
|
|
'last_name' => 'Karimi',
|
|
'phone' => fake()->unique()->numerify('021########'),
|
|
'assigned_to' => $agent->id,
|
|
'is_unassigned' => false,
|
|
], $attributes));
|
|
}
|
|
}
|