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>
137 lines
4.8 KiB
PHP
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();
|
|
});
|