mivita/tests/Feature/UserShopServiceTest.php
Kevin 083d643220 Standard-Shop fuer jeden Berater: Kundenbestellung ohne Shop crashte nicht mehr
Berater ohne UserShop liefen bei Kundenbestellungen (abo-ot-customer) in
"Attempt to read property id on null". Shops werden jetzt bei Freischaltung
und bei Bedarf automatisch angelegt (Name aus Vor-/Nachname, bei Belegung
-2, -3, ...). Nachtrag fuer Bestandsberater: php artisan user:ensure-shops.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 08:13:29 +00:00

137 lines
4.8 KiB
PHP

<?php
/**
* Jeder Berater bekommt einen Standard-Shop, damit Kundenbestellungen (payment 6)
* nicht mehr an "$user->shop->id on null" scheitern.
*/
use App\Models\UserAccount;
use App\Models\UserShop;
use App\Services\UserShopService;
use App\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
uses(TestCase::class, RefreshDatabase::class);
function makeShopUser(string $firstName = 'Melanie', string $lastName = 'Rauch', array $attributes = []): User
{
$account = UserAccount::create([
'salutation' => 'Frau',
'first_name' => $firstName,
'last_name' => $lastName,
'address' => 'Musterstr. 1',
'zipcode' => '12345',
'city' => 'Musterstadt',
'phone' => '123456',
'same_as_billing' => 1,
'language' => 'de',
]);
return User::forceCreate(array_merge([
'email' => 'shop-'.uniqid('', true).'@example.com',
'password' => bcrypt('secret'),
'lang' => 'de',
'account_id' => $account->id,
'active' => 1,
], $attributes));
}
it('legt einen aktiven Standard-Shop aus dem Namen an', function () {
$user = makeShopUser('Jürgen', 'Müller');
$shop = UserShopService::ensureForUser($user);
expect($shop->name)->toBe('juergen-mueller')
->and($shop->slug)->toBe('juergen-mueller')
->and((bool) $shop->active)->toBeTrue()
->and($shop->active_date)->not->toBeNull()
->and($user->shop->id)->toBe($shop->id);
});
it('gibt einen vorhandenen Shop unverändert zurück', function () {
$user = makeShopUser();
$existing = UserShop::create(['user_id' => $user->id, 'name' => 'meinshop', 'active' => true]);
expect(UserShopService::ensureForUser($user)->id)->toBe($existing->id)
->and(UserShop::where('user_id', $user->id)->count())->toBe(1);
});
it('hängt bei belegtem Namen eine fortlaufende Nummer an', function () {
$first = UserShopService::ensureForUser(makeShopUser());
$second = UserShopService::ensureForUser(makeShopUser());
$third = UserShopService::ensureForUser(makeShopUser());
expect($first->name)->toBe('melanie-rauch')
->and($second->name)->toBe('melanie-rauch-2')
->and($third->name)->toBe('melanie-rauch-3');
});
it('kürzt lange Namen vor der Nummer an der Wortgrenze', function () {
$other = makeShopUser('Katrin', 'Gutknecht-Stoll');
UserShop::create(['user_id' => $other->id, 'name' => 'katrin-gutknecht', 'active' => true]);
$name = UserShopService::ensureForUser(makeShopUser('Katrin', 'Gutknecht-Stoll'))->name;
expect($name)->toBe('katrin-gutknecht-2')
->and(strlen($name))->toBeLessThanOrEqual(20);
});
it('berücksichtigt reservierte Namen im Dry-Run', function () {
expect(UserShopService::generateDefaultName(makeShopUser(), ['melanie-rauch']))->toBe('melanie-rauch-2');
});
it('berücksichtigt auch gelöschte Shops als belegt', function () {
$other = makeShopUser();
UserShop::create(['user_id' => $other->id, 'name' => 'melanie-rauch', 'active' => true])->delete();
$user = makeShopUser();
expect(UserShopService::ensureForUser($user)->name)->toBe('melanie-rauch-2');
});
it('kürzt lange Namen auf 20 Zeichen', function () {
$user = makeShopUser('Maximiliane-Theresa', 'Schmidt-Oberhausen');
$name = UserShopService::ensureForUser($user)->name;
expect(strlen($name))->toBeLessThanOrEqual(20)
->and($name)->toBe('maximiliane-theresa');
});
it('kürzt an der Wortgrenze statt mitten im Nachnamen', function () {
$user = makeShopUser('Theresia', 'Schifferegger');
expect(UserShopService::ensureForUser($user)->name)->toBe('theresia');
});
it('fällt bei zu kurzem Namen auf berater zurück', function () {
UserShopService::ensureForUser(makeShopUser('A', ''));
expect(UserShopService::ensureForUser(makeShopUser('B', ''))->name)->toBe('berater-2');
});
it('nutzt berater ohne Account', function () {
$user = User::forceCreate([
'email' => 'no-account-'.uniqid('', true).'@example.com',
'password' => bcrypt('secret'),
'lang' => 'de',
]);
expect(UserShopService::ensureForUser($user)->name)->toBe('berater');
});
it('legt per Command nur für aktive Berater ohne Shop Shops an', function () {
$withoutShop = makeShopUser('Anna', 'Beispiel');
$withShop = makeShopUser('Bernd', 'Beispiel');
UserShop::create(['user_id' => $withShop->id, 'name' => 'bernd-shop', 'active' => true]);
$inactive = makeShopUser('Carla', 'Beispiel', ['active' => 0]);
$this->artisan('user:ensure-shops', ['--dry-run' => true])->assertSuccessful();
expect(UserShop::count())->toBe(1);
$this->artisan('user:ensure-shops')->assertSuccessful();
expect($withoutShop->fresh()->shop->name)->toBe('anna-beispiel')
->and($withShop->fresh()->shop->name)->toBe('bernd-shop')
->and($inactive->fresh()->shop)->toBeNull();
});