companies: Links aus Firmennamen normalisieren — API-Eingang und Bestandsbefehl
38 oeffentliche Firmen tragen eine URL im Namen ("Firma - https://..."),
laufend ueber die API. Nicht ablehnen (traefe die Meldung), sondern
normalisieren: URL raus, Rest bleibt Name, URL ins leere Website-Feld;
besteht der Name nur aus der URL, wird der Host zum Namen. Am API-Eingang
vor der Zuordnung; im Bestand per companies:strip-links-from-names mit
Dry-Run, Slugs bleiben.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
87ca9082a9
commit
99ffd012d4
5 changed files with 310 additions and 3 deletions
84
tests/Feature/CompanyNameNormalizerTest.php
Normal file
84
tests/Feature/CompanyNameNormalizerTest.php
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
|
||||
use App\Enums\Portal;
|
||||
use App\Models\ActivityEvent;
|
||||
use App\Models\Company;
|
||||
use App\Models\PressRelease;
|
||||
use App\Models\User;
|
||||
use App\Services\Company\CompanyNameNormalizer;
|
||||
use Database\Seeders\RolesAndPermissionsSeeder;
|
||||
use Laravel\Sanctum\Sanctum;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* Links gehören nicht in Firmennamen (17.09.2026): Normalisierung am
|
||||
* API-Eingang und einmalig im Bestand — nicht ablehnen, sondern die URL ins
|
||||
* Website-Feld ziehen.
|
||||
*/
|
||||
test('urls are pulled out of the name and moved to the website field', function (string $name, string $expectedName, ?string $expectedWebsite) {
|
||||
$result = CompanyNameNormalizer::normalize($name);
|
||||
|
||||
expect($result['name'])->toBe($expectedName)
|
||||
->and($result['website'])->toBe($expectedWebsite);
|
||||
})->with([
|
||||
['Steinreinigung - https://www.bgn.at/steinreinigung', 'Steinreinigung', 'https://www.bgn.at/steinreinigung'],
|
||||
['Nasenkorrektur Wien - https://www.nasen-chirurgie.at/ - Nasen-OP Wien', 'Nasenkorrektur Wien - Nasen-OP Wien', 'https://www.nasen-chirurgie.at/'],
|
||||
['Teledeal Media / www.standortanzeige.de', 'Teledeal Media', 'www.standortanzeige.de'],
|
||||
['ECCO (www.eccowalkathon.de)', 'ECCO', 'www.eccowalkathon.de'],
|
||||
['https://www.ak-autos.de/', 'ak-autos.de', 'https://www.ak-autos.de/'],
|
||||
['www.wunderbare-seifenblasen.de', 'wunderbare-seifenblasen.de', 'www.wunderbare-seifenblasen.de'],
|
||||
['Muster GmbH & Co. KG', 'Muster GmbH & Co. KG', null],
|
||||
['meinshop.de GmbH', 'meinshop.de GmbH', null],
|
||||
]);
|
||||
|
||||
test('an existing website is kept, the removed url only fills an empty field', function () {
|
||||
$result = CompanyNameNormalizer::normalize('Muster - https://spam.example', 'https://muster.example');
|
||||
|
||||
expect($result['name'])->toBe('Muster')
|
||||
->and($result['website'])->toBe('https://muster.example')
|
||||
->and($result['removed'])->toBe(['https://spam.example']);
|
||||
});
|
||||
|
||||
test('the legacy api stores a clean name and records the correction', function () {
|
||||
/** @var TestCase $this */
|
||||
$this->seed(RolesAndPermissionsSeeder::class);
|
||||
config()->set('billing.enforce_booking', false);
|
||||
$user = User::factory()->create(['is_active' => true, 'portal' => Portal::Businessportal24]);
|
||||
$user->forceFill(['registration_type' => 'apiuser'])->save();
|
||||
Sanctum::actingAs($user, ['press-releases:write']);
|
||||
|
||||
$response = $this->postJson('/service/users/me/companies', [
|
||||
'company' => ['name' => 'Steinreinigung - https://www.bgn.at/steinreinigung', 'email' => 'info@bgn.at'],
|
||||
])->assertCreated();
|
||||
|
||||
$company = Company::withoutGlobalScopes()->findOrFail((int) basename((string) $response->headers->get('Location')));
|
||||
|
||||
expect($company->name)->toBe('Steinreinigung')
|
||||
->and($company->website)->toBe('https://www.bgn.at/steinreinigung')
|
||||
->and($company->slug)->toBe('steinreinigung');
|
||||
|
||||
expect(ActivityEvent::query()->where('subject_id', $company->id)->where('description', 'like', '%Link aus dem Namen entfernt%')->exists())->toBeTrue();
|
||||
});
|
||||
|
||||
test('the cleanup command shows a dry run and then rewrites only public companies', function () {
|
||||
/** @var TestCase $this */
|
||||
$public = Company::factory()->businessportal24()->create(['name' => 'Medienprofi - www.medienprofi.org', 'slug' => 'medienprofi-www-medienprofi-org', 'website' => null]);
|
||||
PressRelease::factory()->published()->forPortal(Portal::Businessportal24)->create(['company_id' => $public->id]);
|
||||
$silent = Company::factory()->businessportal24()->create(['name' => 'https://spam.example/', 'website' => null]);
|
||||
|
||||
$this->artisan('companies:strip-links-from-names', ['--dry-run' => true])
|
||||
->expectsOutputToContain('[Dry-Run] 1 Firmennamen würden bereinigt.')
|
||||
->assertSuccessful();
|
||||
|
||||
expect($public->fresh()->name)->toBe('Medienprofi - www.medienprofi.org');
|
||||
|
||||
$this->artisan('companies:strip-links-from-names')
|
||||
->expectsOutputToContain('1 Firmennamen bereinigt.')
|
||||
->assertSuccessful();
|
||||
|
||||
$public->refresh();
|
||||
expect($public->name)->toBe('Medienprofi')
|
||||
->and($public->website)->toBe('www.medienprofi.org')
|
||||
->and($public->slug)->toBe('medienprofi-www-medienprofi-org')
|
||||
->and($silent->fresh()->name)->toBe('https://spam.example/');
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue