MultiSelectTest::testGetGetValue()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 9
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AbterPhp\Framework\Form\Element;
6
7
use AbterPhp\Framework\Constant\Html5;
8
use AbterPhp\Framework\Form\Component\Option;
9
use AbterPhp\Framework\Html\Attribute;
10
use AbterPhp\Framework\Html\Helper\Attributes;
11
use AbterPhp\Framework\TestDouble\Html\Component\StubAttributeFactory;
12
use AbterPhp\Framework\TestDouble\I18n\MockTranslatorFactory;
13
use InvalidArgumentException;
14
use PHPUnit\Framework\TestCase;
15
use stdClass;
16
17
class MultiSelectTest extends TestCase
18
{
19
    public function testToStringIsEmptyByDefault(): void
20
    {
21
        $sut = new MultiSelect('id', 'name');
22
23
        $this->assertStringContainsString('', (string)$sut);
24
    }
25
26
    public function testSetContentThrowsExceptionIfCalledWithNotNull(): void
27
    {
28
        $this->expectException(\LogicException::class);
29
30
        $sut = new MultiSelect('id', 'name');
31
32
        $sut->setContent(12);
33
    }
34
35
    /**
36
     * @return array[]
37
     */
38
    public function renderProvider(): array
39
    {
40
        $attribs = StubAttributeFactory::createAttributes();
41
        $str     = Attributes::toString($attribs);
42
43
        return [
44
            'simple'               => [
45
                'abc',
46
                'bcd',
47
                ['val'],
48
                [],
49
                null,
50
                null,
51
                null,
52
                '<select multiple id="abc" name="bcd"></select>',
53
            ],
54
            'missing translations' => [
55
                'abc',
56
                'bcd',
57
                ['val'],
58
                [],
59
                null,
60
                [],
61
                null,
62
                '<select multiple id="abc" name="bcd"></select>',
63
            ],
64
            'extra attributes'     => [
65
                'abc',
66
                'bcd',
67
                ['val'],
68
                [],
69
                $attribs,
70
                [],
71
                null,
72
                "<select$str multiple id=\"abc\" name=\"bcd\"></select>",
73
            ],
74
            'options'              => [
75
                'abc',
76
                'bcd',
77
                ['val'],
78
                ['bde' => 'BDE', 'cef' => 'CEF'],
79
                $attribs,
80
                [],
81
                null,
82
                "<select$str multiple id=\"abc\" name=\"bcd\"><option value=\"bde\">BDE</option>\n<option value=\"cef\">CEF</option></select>", // phpcs:ignore
83
            ],
84
            'option selected'      => [
85
                'abc',
86
                'bcd',
87
                ['cef'],
88
                ['bde' => 'BDE', 'cef' => 'CEF'],
89
                $attribs,
90
                [],
91
                null,
92
                "<select$str multiple id=\"abc\" name=\"bcd\"><option value=\"bde\">BDE</option>\n<option value=\"cef\" selected>CEF</option></select>", // phpcs:ignore
93
            ],
94
        ];
95
    }
96
97
    /**
98
     * @dataProvider renderProvider
99
     *
100
     * @param string                        $inputId
101
     * @param string                        $name
102
     * @param string[]                      $value
103
     * @param array<string,string>          $options
104
     * @param array<string, Attribute>|null $attributes
105
     * @param string[]|null                 $translations
106
     * @param string|null                   $tag
107
     * @param string                        $expectedResult
108
     */
109
    public function testRender(
110
        string $inputId,
111
        string $name,
112
        array $value,
113
        array $options,
114
        ?array $attributes,
115
        ?array $translations,
116
        ?string $tag,
117
        string $expectedResult
118
    ): void {
119
        $sut = $this->createMultiSelect($inputId, $name, $value, $options, $attributes, $translations, $tag);
120
121
        $actualResult   = (string)$sut;
122
        $repeatedResult = (string)$sut;
123
124
        $this->assertSame($expectedResult, $actualResult);
125
        $this->assertSame($actualResult, $repeatedResult);
126
    }
127
128
    public function testSetValueSetsOptionsSelected(): void
129
    {
130
        $sut = new MultiSelect('id', 'name');
131
132
        $option1 = new Option('1', 'foo', true);
133
        $option2 = new Option('2', 'bar', false);
134
        $option3 = new Option('3', 'baz', false);
135
136
        $sut->add($option1, $option2, $option3);
137
138
        $sut->setValue(['2', '3']);
139
140
        $this->assertStringNotContainsString(Html5::ATTR_SELECTED, (string)$option1);
141
        $this->assertStringContainsString(Html5::ATTR_SELECTED, (string)$option2);
142
        $this->assertStringContainsString(Html5::ATTR_SELECTED, (string)$option3);
143
    }
144
145
    /**
146
     * @return array
147
     */
148
    public function setValueFailureProvider(): array
149
    {
150
        return [
151
            'string'   => [''],
152
            'stdclass' => [new stdClass()],
153
            'int'      => [123],
154
            'bool'     => [false],
155
            'float'    => [123.53],
156
            'integers' => [[1, 3, 4]],
157
        ];
158
    }
159
160
    /**
161
     * @dataProvider setValueFailureProvider
162
     *
163
     * @param mixed $value
164
     */
165
    public function testSetValueThrowsExceptionOnInvalid($value): void
166
    {
167
        $this->expectException(InvalidArgumentException::class);
168
169
        $sut = new MultiSelect('id', 'foo');
170
171
        $sut->setValue($value);
172
    }
173
174
    public function testRemoveAttributeThrowsExceptionWhenTryingToRemoveProtectedAttributes(): void
175
    {
176
        $this->expectException(\RuntimeException::class);
177
178
        $sut = new MultiSelect('id', 'foo');
179
180
        $sut->removeAttribute(Html5::ATTR_NAME);
181
    }
182
183
    public function testGetName(): void
184
    {
185
        $expectedResult = 'foo';
186
187
        $sut = new MultiSelect('id', $expectedResult);
188
189
        $actualResult = $sut->getName();
190
191
        $this->assertEquals($expectedResult, $actualResult);
192
    }
193
194
    public function testGetGetValue(): void
195
    {
196
        $expectedResult = ['bar', 'ba'];
197
198
        $sut = $this->createMultiSelect('id', 'name', $expectedResult, ['foo' => 'Foo', 'bar' => 'Bar', 'ba' => 'Ba']);
199
200
        $actualResult = $sut->getValue();
201
202
        $this->assertEquals($expectedResult, $actualResult);
203
    }
204
205
    /**
206
     * @param string                       $inputId
207
     * @param string                       $name
208
     * @param string[]                     $values
209
     * @param array<string,string>         $options
210
     * @param array<string,Attribute>|null $attributes
211
     * @param string[]|null                $translations
212
     * @param string|null                  $tag
213
     *
214
     * @return MultiSelect
215
     */
216
    protected function createMultiSelect(
217
        string $inputId,
218
        string $name,
219
        array $values,
220
        array $options,
221
        ?array $attributes = null,
222
        ?array $translations = null,
223
        ?string $tag = null
224
    ): MultiSelect {
225
        $translatorMock = MockTranslatorFactory::createSimpleTranslator($this, $translations);
226
227
        $multiSelect = new MultiSelect($inputId, $name, [], $attributes, $tag);
228
229
        foreach ($options as $k => $v) {
230
            $multiSelect->add(new Option($k, $v, in_array($k, $values, true)));
231
        }
232
233
        $multiSelect->setTranslator($translatorMock);
234
235
        return $multiSelect;
236
    }
237
}
238