109 lines
3.7 KiB
PHP
109 lines
3.7 KiB
PHP
<?php
|
|
|
|
use App\Livewire\Tasks\Index as TasksIndex;
|
|
use App\Models\License;
|
|
use App\Models\Role;
|
|
use App\Models\Tenant;
|
|
use App\Models\User;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Livewire\Livewire;
|
|
|
|
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' => 'Start Tester',
|
|
'email' => 'start@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->actingAs($this->user);
|
|
});
|
|
|
|
it('Start button has data-testid + wire:click="startTask(...)"', function () {
|
|
$html = Livewire::test(TasksIndex::class)->html();
|
|
expect($html)->toContain('data-testid="task-start-btn"');
|
|
expect($html)->toContain("wire:click=\"startTask('t1')\"");
|
|
});
|
|
|
|
it('Repeat button has wire:click="repeatTask(...)" for done tasks', function () {
|
|
$html = Livewire::test(TasksIndex::class)->call('setFilter', 'done')->html();
|
|
expect($html)->toContain('data-testid="task-repeat-btn"');
|
|
expect($html)->toContain('repeatTask(');
|
|
});
|
|
|
|
it('startTask action runs and adds key to startedKeys', function () {
|
|
Livewire::test(TasksIndex::class)
|
|
->assertSet('startedKeys', [])
|
|
->call('startTask', 't1')
|
|
->assertSet('startedKeys', ['t1']);
|
|
});
|
|
|
|
it('startTask emits browser-side Livewire.dispatch via $this->js() targeting RUNNER modal (not detail)', function () {
|
|
$tester = Livewire::test(TasksIndex::class)->call('startTask', 't1');
|
|
|
|
$effects = $tester->effects ?? [];
|
|
$scripts = $effects['xjs'] ?? $effects['js'] ?? [];
|
|
$allScripts = implode("\n", is_array($scripts) ? array_map(fn($s) => is_array($s) ? json_encode($s) : (string) $s, $scripts) : [(string) $scripts]);
|
|
|
|
expect($allScripts)->toContain("Livewire.dispatch('openModal'");
|
|
// Start button opens RUNNER, not detail
|
|
expect($allScripts)->toContain('tasks.modals.runner');
|
|
expect($allScripts)->not->toContain('tasks.modals.detail');
|
|
expect($allScripts)->toContain('t1');
|
|
});
|
|
|
|
it('Detail (info) button still opens tasks.modals.detail — separate from Start', function () {
|
|
$html = Livewire::test(TasksIndex::class)->html();
|
|
// Info-button is client-side wire:click="$dispatch('openModal', ...detail...)"
|
|
expect($html)->toContain('data-testid="task-detail-btn"');
|
|
expect($html)->toContain('tasks.modals.detail');
|
|
});
|
|
|
|
it('startTask ignores unknown task keys', function () {
|
|
Livewire::test(TasksIndex::class)
|
|
->call('startTask', 'non-existent')
|
|
->assertSet('startedKeys', []);
|
|
});
|
|
|
|
it('repeatTask works for done tasks', function () {
|
|
Livewire::test(TasksIndex::class)
|
|
->call('repeatTask', 't6')
|
|
->assertSet('startedKeys', ['t6']);
|
|
});
|
|
|
|
it('multiple startTask calls do not duplicate startedKeys', function () {
|
|
Livewire::test(TasksIndex::class)
|
|
->call('startTask', 't1')
|
|
->call('startTask', 't1')
|
|
->call('startTask', 't1')
|
|
->assertSet('startedKeys', ['t1']);
|
|
});
|