toBeTrue(); }); it('config is keyed by task slug (semantic, not by color)', function () { $bank = config('task-questions'); // Should NOT have keys 'primary', 'rose', etc. directly foreach (['primary', 'rose', 'violet', 'green', 'amber'] as $color) { expect(array_key_exists($color, $bank))->toBeFalse("Bank should be slug-keyed, not color-keyed; found '{$color}'"); } // Should have task slugs expect(array_key_exists('math-multiplikation-bis-100', $bank))->toBeTrue(); expect(array_key_exists('deutsch-wortarten-nomen-verben', $bank))->toBeTrue(); }); it('each question has required keys by type', function () { $bank = config('task-questions'); foreach ($bank as $slug => $questions) { foreach ($questions as $i => $q) { $type = $q['type'] ?? 'choice'; expect($q)->toHaveKeys(['question', 'correct', 'lerni_hint', 'lerni_steps'], "Slug {$slug} q{$i} missing common keys"); expect($q['lerni_steps'])->toBeArray()->not->toBeEmpty(); match ($type) { 'choice' => (function () use ($q, $slug, $i) { expect($q)->toHaveKey('options'); expect($q['options'])->toHaveCount(4); expect($q['correct'])->toBeInt()->toBeGreaterThanOrEqual(0)->toBeLessThan(4); })(), 'cloze' => (function () use ($q, $slug, $i) { expect($q['correct'])->toBeString()->not->toBe(''); })(), 'geo-map' => (function () use ($q, $slug, $i) { expect($q)->toHaveKey('regions'); expect($q['regions'])->toBeArray()->not->toBeEmpty(); $keys = array_column($q['regions'], 'key'); expect(in_array($q['correct'], $keys, true)) ->toBeTrue("geo-map {$slug} q{$i}: correct '{$q['correct']}' not in regions[]"); foreach ($q['regions'] as $r) { expect($r)->toHaveKeys(['key', 'label', 'd']); } })(), default => throw new \LogicException("Unknown type '{$type}' in {$slug} q{$i}"), }; } } }); it('each task slug in config/tasks.php has a matching question bank', function () { foreach (config('tasks', []) as $t) { $bank = config("task-questions.{$t['slug']}"); expect($bank)->toBeArray()->not->toBeEmpty("Task slug '{$t['slug']}' has no question bank"); } }); it('different task slugs return different questions', function () { $math = config('task-questions.math-multiplikation-bis-100'); $german = config('task-questions.deutsch-wortarten-nomen-verben'); expect($math[0]['question'])->not->toBe($german[0]['question']); }); it('math-geometrie and math-multiplikation share color but have different questions', function () { $mult = config('task-questions.math-multiplikation-bis-100'); $geom = config('task-questions.math-geometrie-flaechen'); expect($mult[0]['question'])->not->toBe($geom[0]['question']); });