This commit is contained in:
2026-07-21 23:39:19 +02:00
commit b33b217bdb
217 changed files with 32076 additions and 0 deletions

View File

@@ -0,0 +1,185 @@
<?php
use App\Ldap\LldapUser;
use App\Livewire\Admin\Panel;
use App\Livewire\Operator\TicketShow;
use App\Models\Team;
use App\Models\User;
use App\Models\UserField;
use App\Services\TicketService;
use Illuminate\Support\Str;
use LdapRecord\Laravel\Testing\DirectoryEmulator;
use Livewire\Livewire;
afterEach(function () {
DirectoryEmulator::tearDown();
});
test('admin can create, edit and delete a user field', function () {
$admin = adminUser();
Livewire::actingAs($admin)->test(Panel::class)
->call('setTab', 'user-fields')
->call('openUserFieldForm')
->set('userFieldForm.label', 'Numer telefonu')
->set('userFieldForm.type', 'text')
->set('userFieldForm.ldapAttribute', 'mobile')
->call('submitUserField')
->assertOk();
$field = UserField::query()->where('label', 'Numer telefonu')->firstOrFail();
expect($field->ldap_attribute)->toBe('mobile');
Livewire::actingAs($admin)->test(Panel::class)
->call('editUserField', $field->id)
->assertSet('userFieldForm.label', 'Numer telefonu')
->set('userFieldForm.label', 'Telefon komórkowy')
->call('submitUserField')
->assertOk();
expect($field->fresh()->label)->toBe('Telefon komórkowy');
Livewire::actingAs($admin)->test(Panel::class)
->call('removeUserField', $field->id)
->assertSet('pendingDeleteType', 'user-field')
->call('confirmPendingDelete')
->assertOk();
expect(UserField::query()->find($field->id))->toBeNull();
});
test('user field values only show up and save when editing a user, never when inviting one', function () {
$admin = adminUser();
$op = operatorUser('phonefield@example.com');
$field = UserField::query()->create(['label' => 'Numer telefonu', 'type' => 'text', 'sort_order' => 1]);
Livewire::actingAs($admin)->test(Panel::class)
->call('setTab', 'users')
->call('openUserForm')
->assertSet('userForm.fieldValues', []);
Livewire::actingAs($admin)->test(Panel::class)
->call('editUser', $op->id)
->set("userForm.fieldValues.{$field->id}", '+48 111 222 333')
->call('submitUser')
->assertOk();
expect($op->fresh()->custom_field_values)->toBe([(string) $field->id => '+48 111 222 333']);
});
test('the ldap sync button pulls attribute values for existing users into their user fields', function () {
$fake = DirectoryEmulator::setup();
$admin = adminUser();
$op = operatorUser('anna.sync@firma.pl');
$field = UserField::query()->create(['label' => 'Dział', 'type' => 'text', 'ldap_attribute' => 'departmentNumber', 'sort_order' => 1]);
LldapUser::create([
'uid' => 'anna.sync',
'cn' => 'Anna Sync',
'mail' => 'anna.sync@firma.pl',
'departmentnumber' => 'IT-42',
'entryuuid' => (string) Str::uuid(),
]);
Livewire::actingAs($admin)->test(Panel::class)
->call('setTab', 'users')
->call('syncUsersWithLdap')
->assertOk();
expect($op->fresh()->custom_field_values)->toBe([(string) $field->id => 'IT-42']);
});
test('a first-time guest ticket from a known ldap e-mail auto-provisions the account and fills its ldap-backed fields', function () {
$fake = DirectoryEmulator::setup();
$field = UserField::query()->create(['label' => 'Dział', 'type' => 'text', 'ldap_attribute' => 'departmentnumber', 'sort_order' => 1]);
LldapUser::create([
'uid' => 'nowy.klient',
'cn' => 'Nowy Klient',
'mail' => 'nowy.klient@firma.pl',
'departmentnumber' => 'HR-7',
'entryuuid' => (string) Str::uuid(),
]);
expect(User::query()->where('email', 'nowy.klient@firma.pl')->exists())->toBeFalse();
$ticket = app(TicketService::class)->create([
'email' => 'nowy.klient@firma.pl',
'subject' => 'Test',
'body' => 'Treść zgłoszenia',
], null);
$user = User::query()->where('email', 'nowy.klient@firma.pl')->first();
expect($user)->not->toBeNull()
->and($user->name)->toBe('Nowy Klient')
->and($user->roles)->toBe(['client'])
->and($user->custom_field_values)->toBe([(string) $field->id => 'HR-7'])
->and($ticket->customer_id)->toBe($user->id);
});
test('a guest ticket from an e-mail unknown to ldap stays anonymous, as before', function () {
DirectoryEmulator::setup();
$ticket = app(TicketService::class)->create([
'email' => 'ktos@nieznany.pl',
'subject' => 'Test',
'body' => 'Treść zgłoszenia',
], null);
expect($ticket->customer_id)->toBeNull()
->and(User::query()->where('email', 'ktos@nieznany.pl')->exists())->toBeFalse();
});
test('the operator ticket view shows the reporting customer\'s user field values', function () {
seedStatusesAndPriorities();
$operator = operatorUser('op-view@example.com');
$client = User::query()->create(['name' => 'Reporter Kowalski', 'email' => 'reporter@example.com', 'roles' => ['client']]);
$field = UserField::query()->create(['label' => 'Dział', 'type' => 'text', 'sort_order' => 1]);
$client->update(['custom_field_values' => [$field->id => 'Księgowość']]);
$ticket = makeTicket(['customer_id' => $client->id, 'email' => $client->email, 'name' => $client->name]);
Livewire::actingAs($operator)->test(TicketShow::class, ['ticket' => $ticket])
->assertSee('Dział')
->assertSee('Księgowość');
});
test('the operator ticket view does not blow up for a reporter with no field values set', function () {
seedStatusesAndPriorities();
$operator = operatorUser('op-view2@example.com');
UserField::query()->create(['label' => 'Dział', 'type' => 'text', 'sort_order' => 1]);
$ticket = makeTicket();
Livewire::actingAs($operator)->test(TicketShow::class, ['ticket' => $ticket])
->assertOk();
});
test('the admin "Zobacz" button shows every detail about a user, including their field values', function () {
$admin = adminUser();
$op = operatorUser('zobacz@example.com');
$team = Team::query()->create(['name' => 'Infrastruktura']);
$op->teams()->attach($team->id);
$field = UserField::query()->create(['label' => 'Dział', 'type' => 'text', 'sort_order' => 1]);
$op->update(['custom_field_values' => [$field->id => 'IT-42']]);
Livewire::actingAs($admin)->test(Panel::class)
->call('setTab', 'users')
->call('viewUser', $op->id)
->assertSee('zobacz@example.com')
->assertSee('Infrastruktura')
->assertSee('Dział')
->assertSee('IT-42')
->call('editUser', $op->id)
->assertSet('viewingUserId', null)
->assertSet('userForm.id', $op->id);
});