Passed
Push — html ( d230bc...4d98c2 )
by Peter
03:13
created

MultiSelectTest::testGetGetValue()   A

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