ids = $ids;
}
public function save(): void
{
$this->validate([
'ids' => 'required|array',
'ids.*' => 'integer|in:1,2,3',
], [
'ids.required' => 'Pick at least one server.',
'ids.*.in' => 'Unknown server selected.',
]);
}
public function render(): string
{
return <<<'BLADE'
BLADE;
}
};
}
test('multiple listbox shows the placeholder when nothing is selected', function (mixed $ids) {
Livewire::test(multipleListboxTestComponent(), ['ids' => $ids])
->assertSeeHtml('aria-multiselectable="true"')
->assertSeeHtml('x-text="current">Pick servers');
})->with([[[]], [['group']]]);
test('multiple listbox joins up to two selected labels in the trigger', function () {
// Ids that arrive as strings must match integer option values.
Livewire::test(multipleListboxTestComponent(), ['ids' => ['2', 1]])
->assertSeeHtml('x-text="current">Alpha, Beta');
});
test('multiple listbox shows a count when more than two options are selected', function () {
Livewire::test(multipleListboxTestComponent(), ['ids' => [1, 2, 3]])
->assertSeeHtml('x-text="current">3 selected');
});
test('client-side multiple listbox treats a non-array value as empty', function () {
$html = Blade::render(<<<'BLADE'
BLADE);
expect($html)
->toContain('x-text="current">No tags')
->toMatch('/value:\\s*\\[\\]\\s*,/');
});
test('single listbox output has no multiple-selection attributes', function () {
$html = Blade::render(<<<'BLADE'
BLADE);
expect($html)
->not->toContain('aria-multiselectable')
->not->toContain('get selected()')
->toContain('x-text="current">')
->toMatch("/value:\\s*'a'\\s*,/");
});
test('searchable listbox renders a search field with its placeholders', function () {
$html = Blade::render(<<<'BLADE'
BLADE);
expect($html)
->toContain('type="search"')
->toContain('placeholder="Search servers"')
->toContain('No matching server');
});
test('searchable listbox with allowCustom offers the typed value as an option', function () {
$html = Blade::render(<<<'BLADE'
BLADE);
expect($html)
->toContain('x-if="customOption"')
->toContain('!customOption');
});
test('listbox without allowCustom offers no custom option', function () {
$html = Blade::render(<<<'BLADE'
BLADE);
expect($html)->not->toContain('x-if="customOption"');
});
test('listbox without searchable renders no search field', function () {
$html = Blade::render(<<<'BLADE'
BLADE);
expect($html)->not->toContain('type="search"');
});
test('multiple listbox shows the array validation error', function () {
Livewire::test(multipleListboxTestComponent())
->call('save')
->assertHasErrors(['ids' => 'required'])
->assertSee('Pick at least one server.');
});
test('multiple listbox shows item validation errors', function () {
Livewire::test(multipleListboxTestComponent(), ['ids' => [1, 9]])
->call('save')
->assertHasErrors(['ids.1' => 'in'])
->assertSee('Unknown server selected.');
});
test('multiple listbox shows no error when the selection is valid', function () {
Livewire::test(multipleListboxTestComponent(), ['ids' => [1, 2]])
->call('save')
->assertHasNoErrors()
->assertDontSee('Pick at least one server.')
->assertDontSee('Unknown server selected.');
});