hasOldInput() correctly. */ private function render(array $data, ?array $oldInput = null): string { Route::get('/__test/checkbox-row', function () use ($data) { return view('blade.form.checkbox-row', $data); }); $call = $this->withoutMiddleware([ CheckForSetup::class, CheckForDebug::class, ]); if ($oldInput !== null) { $call = $call->withSession(['_old_input' => $oldInput]); } return $call->get('/__test/checkbox-row')->assertOk()->getContent(); } private function item(): object { return new class { public bool $enabled = true; public bool $disabled_flag = false; public array $prefs = ['email', 'sms']; public static function rules() { return ['enabled' => 'required|boolean']; } }; } public function test_single_fresh_render_reads_model_value_true() { $html = $this->render([ 'name' => 'enabled', 'label' => 'Enabled', 'item' => $this->item(), ]); $this->assertMatchesRegularExpression('/name="enabled"[^>]*checked/', $html); } public function test_single_fresh_render_reads_model_value_false() { $html = $this->render([ 'name' => 'disabled_flag', 'label' => 'Disabled', 'item' => $this->item(), ]); $this->assertDoesNotMatchRegularExpression('/name="disabled_flag"[^>]*checked/', $html); } public function test_single_redisplay_unchecked_does_not_fall_back_to_model() { $html = $this->render( data: [ 'name' => 'enabled', 'label' => 'Enabled', 'item' => $this->item(), ], oldInput: ['some_other_field' => 'x'], ); $this->assertDoesNotMatchRegularExpression('/name="enabled"[^>]*checked/', $html); } public function test_single_redisplay_checked_shows_checked() { $html = $this->render( data: [ 'name' => 'disabled_flag', 'label' => 'Disabled', 'item' => $this->item(), ], oldInput: ['disabled_flag' => '1'], ); $this->assertMatchesRegularExpression('/name="disabled_flag"[^>]*checked/', $html); } public function test_multi_fresh_render_from_model_array_checks_matching_options() { $html = $this->render([ 'name' => 'prefs', 'label' => 'Notifications', 'options' => ['email' => 'Email', 'sms' => 'SMS', 'push' => 'Push'], 'item' => $this->item(), ]); $this->assertMatchesRegularExpression('/value="email"[^>]*checked/', $html); $this->assertMatchesRegularExpression('/value="sms"[^>]*checked/', $html); $this->assertDoesNotMatchRegularExpression('/value="push"[^>]*checked/', $html); } public function test_multi_fresh_render_with_callable_selected() { $html = $this->render([ 'name' => 'modellist_displays', 'label' => 'Model Columns', 'options' => ['image' => 'Image', 'category' => 'Category'], 'selected' => fn ($v) => $v === 'image', ]); $this->assertMatchesRegularExpression('/value="image"[^>]*checked/', $html); $this->assertDoesNotMatchRegularExpression('/value="category"[^>]*checked/', $html); } public function test_multi_redisplay_reflects_old_selection_not_model() { $html = $this->render( data: [ 'name' => 'prefs', 'label' => 'Notifications', 'options' => ['email' => 'Email', 'sms' => 'SMS', 'push' => 'Push'], 'item' => $this->item(), ], oldInput: ['prefs' => ['sms']], ); $this->assertDoesNotMatchRegularExpression('/value="email"[^>]*checked/', $html); $this->assertMatchesRegularExpression('/value="sms"[^>]*checked/', $html); $this->assertDoesNotMatchRegularExpression('/value="push"[^>]*checked/', $html); } public function test_multi_redisplay_all_unchecked_does_not_fall_back_to_model() { $html = $this->render( data: [ 'name' => 'prefs', 'label' => 'Notifications', 'options' => ['email' => 'Email', 'sms' => 'SMS', 'push' => 'Push'], 'item' => $this->item(), ], oldInput: ['some_other_field' => 'x'], ); $this->assertDoesNotMatchRegularExpression('/value="email"[^>]*checked/', $html); $this->assertDoesNotMatchRegularExpression('/value="sms"[^>]*checked/', $html); $this->assertDoesNotMatchRegularExpression('/value="push"[^>]*checked/', $html); } public function test_no_item_does_not_crash_when_deriving_required() { // Transient forms with no persistent model must not try to dereference // a null $item via checkIfRequired (which does $item::rules()). $html = $this->render([ 'name' => 'consent', 'label' => 'I consent', ]); $this->assertDoesNotMatchRegularExpression('/name="consent"[^>]*required/', $html); } public function test_single_derives_required_from_model_rules() { $html = $this->render([ 'name' => 'enabled', 'label' => 'Enabled', 'item' => $this->item(), ]); $this->assertMatchesRegularExpression('/name="enabled"[^>]*required/', $html); } public function test_single_uses_explicit_required_prop_over_helper() { $html = $this->render([ 'name' => 'disabled_flag', 'label' => 'Disabled', 'item' => $this->item(), 'required' => true, ]); $this->assertMatchesRegularExpression('/name="disabled_flag"[^>]*required/', $html); } public function test_single_section_label_renders_left_column_and_drops_offset() { $html = $this->render([ 'name' => 'saml_enabled', 'label' => 'Enable SAML', 'section_label' => 'SAML Integration', ]); // Section header renders as a non-