lernschiff/tests/Feature/Livewire/TasksRunnerModalTest.php

110 lines
4.2 KiB
PHP

<?php
use App\Livewire\Tasks\Modals\Runner;
use App\Models\License;
use App\Models\Role;
use App\Models\Tenant;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Livewire\Livewire;
use LivewireUI\Modal\ModalComponent;
uses(\Illuminate\Foundation\Testing\RefreshDatabase::class);
beforeEach(function () {
$this->seed(\Database\Seeders\RolesSeeder::class);
$tenant = Tenant::firstOrCreate(['name' => 'Test Schule'], ['type' => 'school', 'active' => true]);
$this->user = User::withoutGlobalScopes()->create([
'name' => 'Runner Tester', 'email' => 'runner@test.example',
'tenant_id' => $tenant->id, 'password' => bcrypt('password'),
]);
$role = Role::where('name', 'child')->first();
DB::table('role_user')->insert(['user_id' => $this->user->id, 'role_id' => $role->id, 'created_at' => now(), 'updated_at' => now()]);
$license = License::withoutGlobalScopes()->create([
'tenant_id' => $tenant->id, 'type' => 'school_flat',
'expires_at' => now()->addYear(), 'active' => true,
]);
DB::table('license_assignments')->insert(['license_id' => $license->id, 'user_id' => $this->user->id, 'created_at' => now(), 'updated_at' => now()]);
$this->task = ['key' => 't1', 'title' => 'Multiplikation bis 100', 'meta' => 'Mathe · 4 Aufgaben', 'icon' => '∑', 'points' => 120];
$this->actingAs($this->user);
});
it('Runner modal class extends ModalComponent', function () {
expect(is_subclass_of(Runner::class, ModalComponent::class))->toBeTrue();
});
it('Runner alias resolves to App\\Livewire\\Tasks\\Modals\\Runner', function () {
$cls = app('livewire.finder')->resolveClassComponentClassName('tasks.modals.runner');
expect($cls)->toBe(Runner::class);
});
it('Runner renders question + 4 options for step 1', function () {
Livewire::test(Runner::class, ['task' => $this->task])
->assertSet('currentStep', 1)
->assertSet('totalSteps', 4)
->assertSet('finished', false)
->assertSee('Multiplikation bis 100')
->assertSeeHtml('data-testid="runner-question"')
->assertSeeHtml('data-testid="runner-option-0"')
->assertSeeHtml('data-testid="runner-option-3"');
});
it('submitAnswer with correct option increments correctAnswers + advances step', function () {
Livewire::test(Runner::class, ['task' => $this->task])
->call('submitAnswer', 2) // step 1 correct = index 2
->assertSet('correctAnswers', 1)
->assertSet('currentStep', 2);
});
it('submitAnswer with wrong option still advances step but no point', function () {
Livewire::test(Runner::class, ['task' => $this->task])
->call('submitAnswer', 0) // step 1 wrong
->assertSet('correctAnswers', 0)
->assertSet('currentStep', 2);
});
it('finishing all steps sets finished=true', function () {
Livewire::test(Runner::class, ['task' => $this->task])
->call('submitAnswer', 2) // step 1
->call('submitAnswer', 1) // step 2
->call('submitAnswer', 1) // step 3
->call('submitAnswer', 2) // step 4 — final
->assertSet('finished', true)
->assertSet('correctAnswers', 4)
->assertSeeHtml('data-testid="runner-finished"');
});
it('restart resets state', function () {
Livewire::test(Runner::class, ['task' => $this->task])
->call('submitAnswer', 2)
->call('submitAnswer', 1)
->call('restart')
->assertSet('currentStep', 1)
->assertSet('correctAnswers', 0)
->assertSet('finished', false);
});
it('Runner does NOT close on click-away (must finish or cancel explicitly)', function () {
expect(Runner::closeModalOnClickAway())->toBeFalse();
});
it('Runner displays progress bar with step indicator', function () {
$html = Livewire::test(Runner::class, ['task' => $this->task])->html();
expect($html)->toContain('Frage 1 / 4');
});
it('Runner shows trophy on success, arrow-path on partial', function () {
// 4/4 correct → trophy (passed)
$html = Livewire::test(Runner::class, ['task' => $this->task])
->call('submitAnswer', 2)
->call('submitAnswer', 1)
->call('submitAnswer', 1)
->call('submitAnswer', 2)
->html();
expect($html)->toContain('Super gemacht!');
});