libra/tests/Feature/Admin/AccountConversionTest.php

418 lines
15 KiB
PHP

<?php
use App\Enums\UserType;
use App\Models\AdminLog;
use App\Models\User;
use App\Notifications\AccountTypeChangedNotification;
use Illuminate\Support\Facades\Notification;
use Livewire\Volt\Volt;
beforeEach(function () {
$this->admin = User::factory()->admin()->create();
Notification::fake();
});
// ===========================================
// Individual to Company Conversion Tests
// ===========================================
test('admin can access individual client show page', function () {
$individual = User::factory()->individual()->create();
$this->actingAs($this->admin)
->get(route('admin.clients.individual.show', $individual))
->assertOk()
->assertSee(__('clients.convert_to_company'));
});
test('admin can convert individual to company with all valid data', function () {
$individual = User::factory()->individual()->create([
'full_name' => 'John Doe',
'national_id' => '123456789',
'email' => 'john@example.com',
]);
$this->actingAs($this->admin);
Volt::test('admin.clients.convert-to-company-modal', ['client' => $individual])
->assertSet('contact_person_name', 'John Doe')
->assertSet('contact_person_id', '123456789')
->set('company_name', 'Doe Corp')
->set('company_cert_number', 'CR-12345')
->call('convertToCompany')
->assertHasNoErrors()
->assertRedirect(route('admin.clients.company.show', $individual));
$individual->refresh();
expect($individual->user_type)->toBe(UserType::Company);
expect($individual->company_name)->toBe('Doe Corp');
expect($individual->company_cert_number)->toBe('CR-12345');
expect($individual->contact_person_name)->toBe('John Doe');
expect($individual->contact_person_id)->toBe('123456789');
expect($individual->national_id)->toBeNull();
expect($individual->email)->toBe('john@example.com');
});
test('form pre-fills contact_person_name with user current name', function () {
$individual = User::factory()->individual()->create([
'full_name' => 'Jane Smith',
]);
$this->actingAs($this->admin);
Volt::test('admin.clients.convert-to-company-modal', ['client' => $individual])
->assertSet('contact_person_name', 'Jane Smith');
});
test('form pre-fills contact_person_id with user national_id', function () {
$individual = User::factory()->individual()->create([
'national_id' => '987654321',
]);
$this->actingAs($this->admin);
Volt::test('admin.clients.convert-to-company-modal', ['client' => $individual])
->assertSet('contact_person_id', '987654321');
});
test('cannot convert to company without required company_name field', function () {
$individual = User::factory()->individual()->create();
$this->actingAs($this->admin);
Volt::test('admin.clients.convert-to-company-modal', ['client' => $individual])
->set('company_name', '')
->set('company_cert_number', 'CR-12345')
->call('convertToCompany')
->assertHasErrors(['company_name' => 'required']);
});
test('cannot convert to company without required company_cert_number field', function () {
$individual = User::factory()->individual()->create();
$this->actingAs($this->admin);
Volt::test('admin.clients.convert-to-company-modal', ['client' => $individual])
->set('company_name', 'Test Corp')
->set('company_cert_number', '')
->call('convertToCompany')
->assertHasErrors(['company_cert_number' => 'required']);
});
test('cannot convert with duplicate company_cert_number', function () {
User::factory()->company()->create([
'company_cert_number' => 'CR-EXISTING',
]);
$individual = User::factory()->individual()->create();
$this->actingAs($this->admin);
Volt::test('admin.clients.convert-to-company-modal', ['client' => $individual])
->set('company_name', 'New Corp')
->set('company_cert_number', 'CR-EXISTING')
->set('contact_person_name', 'Test Person')
->set('contact_person_id', '111222333')
->call('convertToCompany')
->assertHasErrors(['company_cert_number']);
});
test('converted individual has user_type set to company', function () {
$individual = User::factory()->individual()->create();
$this->actingAs($this->admin);
Volt::test('admin.clients.convert-to-company-modal', ['client' => $individual])
->set('company_name', 'Test Corp')
->set('company_cert_number', 'CR-TEST')
->call('convertToCompany')
->assertHasNoErrors();
$individual->refresh();
expect($individual->user_type)->toBe(UserType::Company);
});
test('original email phone password preserved after conversion to company', function () {
$individual = User::factory()->individual()->create([
'email' => 'original@example.com',
'phone' => '+970599000000',
]);
$originalPassword = $individual->password;
$this->actingAs($this->admin);
Volt::test('admin.clients.convert-to-company-modal', ['client' => $individual])
->set('company_name', 'Test Corp')
->set('company_cert_number', 'CR-TEST')
->call('convertToCompany')
->assertHasNoErrors();
$individual->refresh();
expect($individual->email)->toBe('original@example.com');
expect($individual->phone)->toBe('+970599000000');
expect($individual->password)->toBe($originalPassword);
});
test('admin log entry created on individual to company conversion', function () {
$individual = User::factory()->individual()->create();
$this->actingAs($this->admin);
Volt::test('admin.clients.convert-to-company-modal', ['client' => $individual])
->set('company_name', 'Test Corp')
->set('company_cert_number', 'CR-TEST')
->call('convertToCompany')
->assertHasNoErrors();
expect(AdminLog::where('action', 'convert_account')
->where('target_type', 'user')
->where('target_id', $individual->id)
->where('admin_id', $this->admin->id)
->exists())->toBeTrue();
$log = AdminLog::where('action', 'convert_account')->first();
expect($log->old_values['user_type'])->toBe(UserType::Individual->value);
expect($log->new_values['user_type'])->toBe(UserType::Company->value);
});
test('email notification sent after conversion to company', function () {
$individual = User::factory()->individual()->create();
$this->actingAs($this->admin);
Volt::test('admin.clients.convert-to-company-modal', ['client' => $individual])
->set('company_name', 'Test Corp')
->set('company_cert_number', 'CR-TEST')
->call('convertToCompany')
->assertHasNoErrors();
Notification::assertSentTo($individual, AccountTypeChangedNotification::class);
});
// ===========================================
// Company to Individual Conversion Tests
// ===========================================
test('admin can access company client show page', function () {
$company = User::factory()->company()->create();
$this->actingAs($this->admin)
->get(route('admin.clients.company.show', $company))
->assertOk()
->assertSee(__('clients.convert_to_individual'));
});
test('admin can convert company to individual with all valid data', function () {
$company = User::factory()->company()->create([
'company_name' => 'Acme Corp',
'contact_person_name' => 'Jane Smith',
'contact_person_id' => '987654321',
'email' => 'contact@acme.com',
]);
$this->actingAs($this->admin);
Volt::test('admin.clients.convert-to-individual-modal', ['client' => $company])
->assertSet('full_name', 'Jane Smith')
->assertSet('national_id', '987654321')
->call('convertToIndividual')
->assertHasNoErrors()
->assertRedirect(route('admin.clients.individual.show', $company));
$company->refresh();
expect($company->user_type)->toBe(UserType::Individual);
expect($company->full_name)->toBe('Jane Smith');
expect($company->national_id)->toBe('987654321');
expect($company->company_name)->toBeNull();
expect($company->company_cert_number)->toBeNull();
expect($company->contact_person_name)->toBeNull();
expect($company->contact_person_id)->toBeNull();
expect($company->email)->toBe('contact@acme.com');
});
test('form pre-fills name with contact_person_name or company_name', function () {
$company = User::factory()->company()->create([
'contact_person_name' => 'John Contact',
]);
$this->actingAs($this->admin);
Volt::test('admin.clients.convert-to-individual-modal', ['client' => $company])
->assertSet('full_name', 'John Contact');
});
test('form pre-fills national_id with contact_person_id if available', function () {
$company = User::factory()->company()->create([
'contact_person_id' => '555666777',
]);
$this->actingAs($this->admin);
Volt::test('admin.clients.convert-to-individual-modal', ['client' => $company])
->assertSet('national_id', '555666777');
});
test('cannot convert to individual without required name field', function () {
$company = User::factory()->company()->create();
$this->actingAs($this->admin);
Volt::test('admin.clients.convert-to-individual-modal', ['client' => $company])
->set('full_name', '')
->set('national_id', '123456789')
->call('convertToIndividual')
->assertHasErrors(['full_name' => 'required']);
});
test('cannot convert to individual without required national_id field', function () {
$company = User::factory()->company()->create();
$this->actingAs($this->admin);
Volt::test('admin.clients.convert-to-individual-modal', ['client' => $company])
->set('full_name', 'Test User')
->set('national_id', '')
->call('convertToIndividual')
->assertHasErrors(['national_id' => 'required']);
});
test('cannot convert with duplicate national_id', function () {
User::factory()->individual()->create([
'national_id' => 'EXISTING-ID',
]);
$company = User::factory()->company()->create();
$this->actingAs($this->admin);
Volt::test('admin.clients.convert-to-individual-modal', ['client' => $company])
->set('full_name', 'Test User')
->set('national_id', 'EXISTING-ID')
->call('convertToIndividual')
->assertHasErrors(['national_id']);
});
test('converted company has user_type set to individual', function () {
$company = User::factory()->company()->create();
$this->actingAs($this->admin);
Volt::test('admin.clients.convert-to-individual-modal', ['client' => $company])
->set('full_name', 'Test User')
->set('national_id', 'NEW-ID-123')
->call('convertToIndividual')
->assertHasNoErrors();
$company->refresh();
expect($company->user_type)->toBe(UserType::Individual);
});
test('company fields nulled after conversion to individual', function () {
$company = User::factory()->company()->create([
'company_name' => 'Test Corp',
'company_cert_number' => 'CR-123',
'contact_person_name' => 'Contact Person',
'contact_person_id' => '123123123',
]);
$this->actingAs($this->admin);
Volt::test('admin.clients.convert-to-individual-modal', ['client' => $company])
->set('full_name', 'Test User')
->set('national_id', 'NEW-ID-456')
->call('convertToIndividual')
->assertHasNoErrors();
$company->refresh();
expect($company->company_name)->toBeNull();
expect($company->company_cert_number)->toBeNull();
expect($company->contact_person_name)->toBeNull();
expect($company->contact_person_id)->toBeNull();
});
test('original email phone password preserved after conversion to individual', function () {
$company = User::factory()->company()->create([
'email' => 'company@example.com',
'phone' => '+970599111111',
]);
$originalPassword = $company->password;
$this->actingAs($this->admin);
Volt::test('admin.clients.convert-to-individual-modal', ['client' => $company])
->set('full_name', 'Test User')
->set('national_id', 'NEW-ID-789')
->call('convertToIndividual')
->assertHasNoErrors();
$company->refresh();
expect($company->email)->toBe('company@example.com');
expect($company->phone)->toBe('+970599111111');
expect($company->password)->toBe($originalPassword);
});
test('admin log entry created on company to individual conversion', function () {
$company = User::factory()->company()->create();
$this->actingAs($this->admin);
Volt::test('admin.clients.convert-to-individual-modal', ['client' => $company])
->set('full_name', 'Test User')
->set('national_id', 'NEW-ID-999')
->call('convertToIndividual')
->assertHasNoErrors();
expect(AdminLog::where('action', 'convert_account')
->where('target_type', 'user')
->where('target_id', $company->id)
->where('admin_id', $this->admin->id)
->exists())->toBeTrue();
$log = AdminLog::where('action', 'convert_account')->first();
expect($log->old_values['user_type'])->toBe(UserType::Company->value);
expect($log->new_values['user_type'])->toBe(UserType::Individual->value);
});
test('email notification sent after conversion to individual', function () {
$company = User::factory()->company()->create();
$this->actingAs($this->admin);
Volt::test('admin.clients.convert-to-individual-modal', ['client' => $company])
->set('full_name', 'Test User')
->set('national_id', 'NEW-ID-000')
->call('convertToIndividual')
->assertHasNoErrors();
Notification::assertSentTo($company, AccountTypeChangedNotification::class);
});
// ===========================================
// Confirmation Dialog Tests
// ===========================================
test('conversion shows confirmation step before executing', function () {
$individual = User::factory()->individual()->create();
$this->actingAs($this->admin);
Volt::test('admin.clients.convert-to-company-modal', ['client' => $individual])
->set('company_name', 'Test Corp')
->set('company_cert_number', 'CR-CONFIRM')
->call('showConfirmationDialog')
->assertSet('showConfirmation', true)
->assertHasNoErrors();
});
test('can cancel confirmation and go back', function () {
$individual = User::factory()->individual()->create();
$this->actingAs($this->admin);
Volt::test('admin.clients.convert-to-company-modal', ['client' => $individual])
->set('company_name', 'Test Corp')
->set('company_cert_number', 'CR-CANCEL')
->call('showConfirmationDialog')
->assertSet('showConfirmation', true)
->call('cancelConfirmation')
->assertSet('showConfirmation', false);
});