Analyse der beiden ~40/160-Zeilen-save()-Methoden (users/create vs edit): sie teilen nur den User-Attribut-Payload und den byte-identischen Firmen-Sync-Loop (Bearbeiten hat zusaetzlich Profil/Kontakte/volle Billing-CRUD). Ein voller UserUpsertService waere Over-Engineering (ueberwiegend Branches) — daher nur der wirklich gemeinsame Persistenz-Kern: User::syncCompaniesWithRoles(array $companyIds, array $roles) baut das Pivot-Payload (fehlende Rolle => 'member') und synct. Beide Formulare nutzen es; im Bearbeiten kommen die linkedCompanyIds nun direkt aus $validated. Test: UserSyncCompaniesTest (Rollen-Zuordnung, member-Default, Detach). 29 User-Tests gruen. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
35 lines
1.2 KiB
PHP
35 lines
1.2 KiB
PHP
<?php
|
|
|
|
use App\Models\Company;
|
|
use App\Models\User;
|
|
|
|
test('syncCompaniesWithRoles attaches companies with their pivot role', function () {
|
|
$user = User::factory()->create();
|
|
$a = Company::factory()->create();
|
|
$b = Company::factory()->create();
|
|
|
|
$user->syncCompaniesWithRoles([$a->id, $b->id], [$a->id => 'owner', $b->id => 'responsible']);
|
|
|
|
expect($user->companies()->pluck('role', 'companies.id')->all())
|
|
->toBe([$a->id => 'owner', $b->id => 'responsible']);
|
|
});
|
|
|
|
test('syncCompaniesWithRoles defaults missing roles to member', function () {
|
|
$user = User::factory()->create();
|
|
$company = Company::factory()->create();
|
|
|
|
$user->syncCompaniesWithRoles([$company->id], []);
|
|
|
|
expect($user->companies()->first()->pivot->role)->toBe('member');
|
|
});
|
|
|
|
test('syncCompaniesWithRoles detaches companies no longer listed', function () {
|
|
$user = User::factory()->create();
|
|
$a = Company::factory()->create();
|
|
$b = Company::factory()->create();
|
|
$user->syncCompaniesWithRoles([$a->id, $b->id], []);
|
|
|
|
$user->syncCompaniesWithRoles([$b->id], [$b->id => 'owner']);
|
|
|
|
expect($user->companies()->pluck('companies.id')->all())->toBe([$b->id]);
|
|
});
|