companies: Kurzfelder des Profils ohne Links, Adressen und Spam (NoPromotionalText)
Firmenname, Adresse und Pressekontakt erscheinen oeffentlich bzw. in Mails, wurden aber nicht geprueft — nur die Beschreibung lief durch die Rot-Ebene. Neue deterministische Regel: keine Links, keine E-Mail- Adressen, keine Zeichen-/Emoji-Ketten, kein Blacklist-Treffer; nackte Domains ohne Pfad bleiben erlaubt (Marke). Adresse zusaetzlich durch die Rot-Ebene wie die Beschreibung. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4fd1db7825
commit
87ca9082a9
5 changed files with 246 additions and 7 deletions
118
tests/Feature/NoPromotionalTextTest.php
Normal file
118
tests/Feature/NoPromotionalTextTest.php
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Company;
|
||||
use App\Models\Contact;
|
||||
use App\Models\User;
|
||||
use App\Rules\NoPromotionalText;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Livewire\Volt\Volt as LivewireVolt;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* Öffentliche Kurzfelder des Newsrooms (Firmenname, Adresse, Pressekontakt)
|
||||
* sind keine Werbefläche — deterministische Regel, ohne KI (17.09.2026).
|
||||
*/
|
||||
function promotionalReason(string $value): ?string
|
||||
{
|
||||
$validator = Validator::make(['field' => $value], ['field' => ['nullable', 'string', app(NoPromotionalText::class)]]);
|
||||
|
||||
return $validator->fails() ? $validator->errors()->first('field') : null;
|
||||
}
|
||||
|
||||
beforeEach(function (): void {
|
||||
config()->set('blacklist.words', ['spam-keyword', 'casino royale']);
|
||||
config()->set('scoring.classification.provider', 'deterministic');
|
||||
});
|
||||
|
||||
test('ordinary company names, addresses and roles pass', function (string $value) {
|
||||
expect(promotionalReason($value))->toBeNull();
|
||||
})->with([
|
||||
'Muster GmbH & Co. KG',
|
||||
'meinshop.de GmbH',
|
||||
'Hörwelt Basel e.V.',
|
||||
'Musterstraße 12, 12345 Musterstadt',
|
||||
'Leiterin Unternehmenskommunikation',
|
||||
'Pressesprecher (Region Süd) – erreichbar Mo–Fr!',
|
||||
'SAP SE',
|
||||
'',
|
||||
]);
|
||||
|
||||
test('links, addresses, noise and blacklist hits are rejected with a specific reason', function (string $value, string $expected) {
|
||||
expect(promotionalReason($value))->toContain($expected);
|
||||
})->with([
|
||||
['Casino Bonus https://spam.example/bonus', 'Links'],
|
||||
['Gewinne jetzt www.spam.example', 'Links'],
|
||||
['Angebote auf spam.example/deal', 'Links'],
|
||||
['Bestellen unter kontakt@spam.example', 'E-Mail-Adressen'],
|
||||
['JETZT KAUFEN!!!', 'Sonderzeichen'],
|
||||
['Gratis 🎰🎰🎰 Bonus', 'Sonderzeichen'],
|
||||
['Ein spam-keyword Anbieter', 'unzulässigen Begriff'],
|
||||
['Willkommen im Casino Royale', 'unzulässigen Begriff'],
|
||||
]);
|
||||
|
||||
function newsroomEditor(TestCase $test): Company
|
||||
{
|
||||
$customer = User::factory()->create(['is_active' => true]);
|
||||
$company = Company::factory()->businessportal24()->create(['name' => 'Muster GmbH', 'slug' => 'muster-gmbh', 'boilerplate' => null, 'address' => null]);
|
||||
$customer->companies()->attach($company->id, ['role' => 'responsible']);
|
||||
$test->actingAs($customer);
|
||||
|
||||
return $company;
|
||||
}
|
||||
|
||||
test('a company name or address with a link is not saved', function () {
|
||||
/** @var TestCase $this */
|
||||
$company = newsroomEditor($this);
|
||||
|
||||
LivewireVolt::test('customer.press-kits.show', ['id' => $company->id])
|
||||
->call('startEditCompany')
|
||||
->set('companyName', 'Muster GmbH – https://spam.example')
|
||||
->set('companyAddress', "Musterstraße 1\nwww.spam.example")
|
||||
->call('saveCompany')
|
||||
->assertHasErrors(['companyName', 'companyAddress']);
|
||||
|
||||
expect($company->fresh()->name)->toBe('Muster GmbH')
|
||||
->and($company->fresh()->address)->toBeNull();
|
||||
});
|
||||
|
||||
test('an address that hits the red level of the release check is not saved', function () {
|
||||
/** @var TestCase $this */
|
||||
$company = newsroomEditor($this);
|
||||
|
||||
LivewireVolt::test('customer.press-kits.show', ['id' => $company->id])
|
||||
->call('startEditCompany')
|
||||
->set('companyAddress', 'Musterstraße 1, spam-keyword Musterstadt')
|
||||
->call('saveCompany')
|
||||
->assertHasErrors(['companyAddress']);
|
||||
|
||||
expect($company->fresh()->address)->toBeNull();
|
||||
});
|
||||
|
||||
test('a press contact with a link in the role is not saved', function () {
|
||||
/** @var TestCase $this */
|
||||
$company = newsroomEditor($this);
|
||||
|
||||
LivewireVolt::test('customer.press-kits.show', ['id' => $company->id])
|
||||
->call('startCreateContact')
|
||||
->set('contactLastName', 'Muster')
|
||||
->set('contactResponsibility', 'Pressesprecher – Angebote unter https://spam.example')
|
||||
->set('contactEmail', 'presse@muster.example')
|
||||
->call('saveContact')
|
||||
->assertHasErrors(['contactResponsibility']);
|
||||
|
||||
expect(Contact::query()->where('company_id', $company->id)->count())->toBe(0);
|
||||
});
|
||||
|
||||
test('creating a company with a promotional name is refused', function () {
|
||||
/** @var TestCase $this */
|
||||
$customer = User::factory()->create(['is_active' => true]);
|
||||
$this->actingAs($customer);
|
||||
|
||||
LivewireVolt::test('customer.press-kits.create')
|
||||
->set('name', 'Casino Royale Bonus')
|
||||
->set('portal', 'businessportal24')
|
||||
->call('save')
|
||||
->assertHasErrors(['name']);
|
||||
|
||||
expect(Company::query()->where('name', 'Casino Royale Bonus')->exists())->toBeFalse();
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue