CRM/backend/tests/Feature/CoreCrmIntegrityTest.php

116 خطوط
4.4 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\Company;
use App\Models\Contact;
use App\Models\Deal;
use App\Models\Lead;
use App\Models\SalesScript;
use App\Models\User;
use Database\Seeders\RolePermissionSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Schema;
use Tests\TestCase;
class CoreCrmIntegrityTest extends TestCase
{
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
$this->seed(RolePermissionSeeder::class);
}
public function test_campaign_assignments_store_the_correct_pivot_role_and_load_script(): void
{
$admin = $this->user('admin');
$agent = $this->user('agent');
$supervisor = $this->user('supervisor');
$script = SalesScript::create(['title' => 'Default script']);
$campaignId = $this->actingAs($admin)->postJson('/api/campaigns', [
'name' => 'Summer Campaign',
'status' => 'active',
'sales_script_id' => $script->id,
'agent_ids' => [$agent->id],
'supervisor_ids' => [$supervisor->id],
])->assertCreated()->json('data.id');
$this->assertDatabaseHas('campaign_user', ['campaign_id' => $campaignId, 'user_id' => $agent->id, 'role' => 'agent']);
$this->assertDatabaseHas('campaign_user', ['campaign_id' => $campaignId, 'user_id' => $supervisor->id, 'role' => 'supervisor']);
$this->actingAs($admin)->getJson("/api/campaigns/{$campaignId}")
->assertOk()
->assertJsonPath('data.sales_script.id', $script->id);
}
public function test_deal_show_loads_notes_without_missing_relation_error(): void
{
$admin = $this->user('admin');
$deal = Deal::create(['title' => 'Safe Deal', 'owner_id' => $admin->id, 'created_by' => $admin->id]);
$deal->notes()->create([
'user_id' => $admin->id,
'content' => 'Deal note',
]);
$this->actingAs($admin)->getJson("/api/deals/{$deal->id}")
->assertOk()
->assertJsonPath('notes.0.content', 'Deal note');
}
public function test_primary_contact_change_is_limited_to_the_same_parent_scope(): void
{
$admin = $this->user('admin');
$otherAdmin = $this->user('admin');
$first = Contact::create(['name' => 'First', 'created_by' => $admin->id, 'is_primary' => true]);
$second = Contact::create(['name' => 'Second', 'created_by' => $admin->id, 'is_primary' => false]);
$unrelated = Contact::create(['name' => 'Unrelated', 'created_by' => $otherAdmin->id, 'is_primary' => true]);
$this->actingAs($admin)->patchJson("/api/contacts/{$second->id}/primary", ['reason' => 'Main contact'])->assertOk();
$this->assertFalse($first->fresh()->is_primary);
$this->assertTrue($second->fresh()->is_primary);
$this->assertTrue($unrelated->fresh()->is_primary);
}
public function test_sales_script_relationship_has_one_canonical_foreign_key_direction(): void
{
$this->assertFalse(Schema::hasColumn('sales_scripts', 'campaign_id'));
$this->assertFalse(Schema::hasColumn('sales_scripts', 'product_id'));
$this->assertTrue(Schema::hasColumn('campaigns', 'sales_script_id'));
$this->assertTrue(Schema::hasColumn('products', 'sales_script_id'));
}
public function test_contact_rejects_incompatible_parent_relationships(): void
{
$admin = $this->user('admin');
$firstCompany = Company::create(['name' => 'First company', 'created_by' => $admin->id]);
$secondCompany = Company::create(['name' => 'Second company', 'created_by' => $admin->id]);
$lead = Lead::create([
'company_id' => $firstCompany->id,
'first_name' => 'Ali',
'last_name' => 'Ahmadi',
'phone' => '09121111111',
]);
$this->actingAs($admin)->postJson('/api/contacts', [
'name' => 'Invalid contact',
'lead_id' => $lead->id,
'company_id' => $secondCompany->id,
'phones' => [['phone' => '09120000000', 'type' => 'mobile']],
])->assertUnprocessable()
->assertJsonValidationErrors('relationships');
$this->assertDatabaseMissing('contacts', ['name' => 'Invalid contact']);
}
private function user(string $role): User
{
$user = User::factory()->create(['is_active' => true]);
$user->assignRole($role);
return $user;
}
}