mivita/tests/Feature/RecognitionPageTest.php
Kevin Adametz 7bc551ca1f Anerkennungen: firmenweite Monats-Ranglisten im Salescenter
- Neue Seite Anerkennungen (/user/recognitions, Menue unter News Archiv) fuer
  alle Berater mit aktivem Konto: oben die Anerkennungen des Vormonats in den
  fuenf Kategorien der Monatsmail, Filter zurueck bis Januar 2026; darunter
  Live-Ranglisten (Top 10 je Kategorie) des laufenden Monats, 15 Min. Cache.
- Kategorien: Top-Recruiter (ab 2 Neupartnern), neue Kunden-Abos,
  Kundenabo-Punkte, Kunden-Abos gesamt, Gesamtpunkte (1.000-Punkte-Shop,
  mit Platz 4). Regeln wie TopResultsService/VIP-Statistik, nur firmenweit.
- Firmenkonto (6) und Grosskundin (3) nie aufgefuehrt:
  config mivita.recognition_excluded_user_ids.
- Abgeschlossene Monate sind bis zum 3. des Folgemonats vorlaeufig und werden
  dann eingefroren: neue Tabelle recognition_snapshots, Command
  recognitions:freeze (taeglich 06:15, idempotent, holt offene Monate nach).
- September-Anerkennungen firmenweit geprueft und korrigiert.

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

115 lines
4 KiB
PHP

<?php
use App\Models\RecognitionSnapshot;
use App\Models\UserAccount;
use App\Models\UserSalesVolume;
use App\User;
use Carbon\Carbon;
use Illuminate\Support\Facades\Cache;
use Tests\TestCase;
uses(TestCase::class);
beforeEach(function () {
$this->previousHttpHost = $_SERVER['HTTP_HOST'] ?? null;
$_SERVER['HTTP_HOST'] = config('domains.domains.crm.host');
$this->refreshApplication();
$this->artisan('migrate');
Carbon::setTestNow(Carbon::parse('2026-10-09 10:00:00'));
Cache::flush();
config(['mivita.recognition_excluded_user_ids' => []]);
});
afterEach(function () {
Carbon::setTestNow();
// Host wieder zurücksetzen, sonst booten nachfolgende Tests mit den CRM-Routen.
if ($this->previousHttpHost === null) {
unset($_SERVER['HTTP_HOST']);
} else {
$_SERVER['HTTP_HOST'] = $this->previousHttpHost;
}
});
function recPageUser(string $firstName, string $lastName, array $attributes = []): User
{
$account = UserAccount::forceCreate(['first_name' => $firstName, 'last_name' => $lastName]);
return User::forceCreate(array_merge([
'email' => 'recp-'.uniqid('', true).'@example.com',
'password' => bcrypt('secret'),
'lang' => 'de',
'active' => 1,
'wizard' => 100,
'm_level' => 1,
'payment_account' => now()->addYear(),
'account_id' => $account->id,
], $attributes));
}
function recPageVolume(int $userId, int $points, int $month): void
{
UserSalesVolume::forceCreate([
'user_id' => $userId,
'month' => $month,
'year' => 2026,
'points' => $points,
'status' => 1,
]);
}
it('zeigt aktiven Beratern die Anerkennungen des Vormonats und die Live-Tabelle', function () {
$viewer = recPageUser('Vera', 'Viewer');
$september = recPageUser('Sina', 'September');
$october = recPageUser('Otto', 'Oktober');
recPageVolume($september->id, 5808, 9);
recPageVolume($october->id, 1234, 10);
recPageVolume($viewer->id, 800, 10);
$this->actingAs($viewer)->get(route('user_recognitions'))
->assertOk()
->assertSee('Unsere Erfolge im September 2026')
->assertSee('Vorläufig · wird am 03.10.2026 festgeschrieben', false)
->assertSee('Sina September')
->assertSee('5.808')
->assertSee('Live: So entwickelt sich der Oktober 2026')
->assertSee('Otto Oktober')
->assertSee('1.234')
->assertSee('<tr class="table-info">', false)
->assertSee('href="'.route('user_recognitions').'"', false);
});
it('zeigt eingefrorene Monate als endgültig und wechselt per Filter den Monat', function () {
$viewer = recPageUser('Vera', 'Viewer');
$august = recPageUser('Augusta', 'August');
recPageVolume($august->id, 4321, 8);
$this->artisan('recognitions:freeze', ['--month' => 8, '--year' => 2026])->assertSuccessful();
expect(RecognitionSnapshot::query()->where('month', 8)->exists())->toBeTrue();
$this->actingAs($viewer)->get(route('user_recognitions', ['period' => '2026-08']))
->assertOk()
->assertSee('Unsere Erfolge im August 2026')
->assertSee('Endgültig · festgeschrieben am 09.10.2026', false)
->assertSee('Augusta August')
->assertSee('<option value="2026-08" selected="selected">', false);
});
it('faellt bei einem nicht abgeschlossenen Monat auf den Vormonat zurueck', function () {
$this->actingAs(recPageUser('Vera', 'Viewer'))->get(route('user_recognitions', ['period' => '2026-10']))
->assertOk()
->assertSee('Unsere Erfolge im September 2026');
});
it('lehnt ein ungueltiges Monatsformat ab', function () {
$this->actingAs(recPageUser('Vera', 'Viewer'))->get(route('user_recognitions', ['period' => 'kaputt']))
->assertRedirect()
->assertSessionHasErrors('period');
});
it('sperrt die Seite fuer Berater ohne aktives Konto', function () {
$this->actingAs(recPageUser('Ina', 'Inaktiv', ['payment_account' => now()->subDay()]))
->get(route('user_recognitions'))
->assertRedirect('/home');
});