Issues (138)

tests/Rule/AtLeastTest.php (2 issues)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Validator\Tests\Rule;
6
7
use InvalidArgumentException;
8
use Yiisoft\Validator\EmptyCondition\NeverEmpty;
9
use Yiisoft\Validator\Rule\AtLeast;
10
use Yiisoft\Validator\Rule\AtLeastHandler;
11
use Yiisoft\Validator\Tests\Rule\Base\DifferentRuleInHandlerTestTrait;
12
use Yiisoft\Validator\Tests\Rule\Base\RuleTestCase;
13
use Yiisoft\Validator\Tests\Rule\Base\RuleWithOptionsTestTrait;
14
use Yiisoft\Validator\Tests\Rule\Base\SkipOnErrorTestTrait;
15
use Yiisoft\Validator\Tests\Rule\Base\WhenTestTrait;
16
use Yiisoft\Validator\Tests\Support\Data\AtLeastDto;
17
18
final class AtLeastTest extends RuleTestCase
19
{
20
    use DifferentRuleInHandlerTestTrait;
21
    use RuleWithOptionsTestTrait;
22
    use SkipOnErrorTestTrait;
23
    use WhenTestTrait;
24
25
    public function testMinGreaterThanAttributesCount(): void
26
    {
27
        $this->expectException(InvalidArgumentException::class);
28
        $this->expectExceptionMessage('$min must be no greater than amount of $attributes.');
29
        new AtLeast(['attr'], min: 2);
30
    }
31
32
    public function testGetName(): void
33
    {
34
        $rule = new AtLeast(['attr']);
35
        $this->assertSame(AtLeast::class, $rule->getName());
36
    }
37
38
    public function dataOptions(): array
39
    {
40
        return [
41
            [
42
                new AtLeast(['attr1', 'attr2']),
43
                [
44
                    'attributes' => [
45
                        'attr1',
46
                        'attr2',
47
                    ],
48
                    'min' => 1,
49
                    'incorrectInputMessage' => [
50
                        'template' => 'The value must be an array or an object.',
51
                        'parameters' => [],
52
                    ],
53
                    'message' => [
54
                        'template' => 'At least {min, number} {min, plural, one{attribute} other{attributes}} from ' .
55
                            'this list must be filled: {attributes}.',
56
                        'parameters' => ['min' => 1],
57
                    ],
58
                    'skipOnEmpty' => false,
59
                    'skipOnError' => false,
60
                ],
61
            ],
62
            [
63
                new AtLeast(['attr1', 'attr2'], min: 2),
64
                [
65
                    'attributes' => [
66
                        'attr1',
67
                        'attr2',
68
                    ],
69
                    'min' => 2,
70
                    'incorrectInputMessage' => [
71
                        'template' => 'The value must be an array or an object.',
72
                        'parameters' => [],
73
                    ],
74
                    'message' => [
75
                        'template' => 'At least {min, number} {min, plural, one{attribute} other{attributes}} from ' .
76
                            'this list must be filled: {attributes}.',
77
                        'parameters' => ['min' => 2],
78
                    ],
79
                    'skipOnEmpty' => false,
80
                    'skipOnError' => false,
81
                ],
82
            ],
83
            'callable skip on empty' => [
84
                new AtLeast(['attr1', 'attr2'], skipOnEmpty: new NeverEmpty()),
85
                [
86
                    'attributes' => [
87
                        'attr1',
88
                        'attr2',
89
                    ],
90
                    'min' => 1,
91
                    'incorrectInputMessage' => [
92
                        'template' => 'The value must be an array or an object.',
93
                        'parameters' => [],
94
                    ],
95
                    'message' => [
96
                        'template' => 'At least {min, number} {min, plural, one{attribute} other{attributes}} from ' .
97
                            'this list must be filled: {attributes}.',
98
                        'parameters' => ['min' => 1],
99
                    ],
100
                    'skipOnEmpty' => null,
101
                    'skipOnError' => false,
102
                ],
103
            ],
104
        ];
105
    }
106
107
    public function dataValidationPassed(): array
108
    {
109
        return [
110
            [
111
                new class () {
112
                    public $attr1 = 1;
113
                    public $attr2 = null;
114
                },
115
                [new AtLeast(['attr1', 'attr2'])],
116
            ],
117
            [
118
                new class () {
119
                    public $attr1 = null;
120
                    public $attr2 = 1;
121
                },
122
                [new AtLeast(['attr2'])],
123
            ],
124
            [
125
                new class () {
126
                    private int $attr1 = 1;
0 ignored issues
show
The private property $attr1 is not used, and could be removed.
Loading history...
127
                    private $attr2 = null;
0 ignored issues
show
The private property $attr2 is not used, and could be removed.
Loading history...
128
                },
129
                [new AtLeast(['attr1', 'attr2'])],
130
            ],
131
            [
132
                ['attr1' => 1, 'attr2' => null],
133
                [new AtLeast(['attr1', 'attr2'])],
134
            ],
135
            [
136
                ['attr1' => null, 'attr2' => 1],
137
                [new AtLeast(['attr2'])],
138
            ],
139
            [
140
                new class () {
141
                    public $obj;
142
143
                    public function __construct()
144
                    {
145
                        $this->obj = new class () {
146
                            public $attr1 = 1;
147
                            public $attr2 = null;
148
                        };
149
                    }
150
                },
151
                ['obj' => new AtLeast(['attr1', 'attr2'])],
152
            ],
153
            [
154
                new class () {
155
                    public $obj;
156
157
                    public function __construct()
158
                    {
159
                        $this->obj = new class () {
160
                            public $attr1 = null;
161
                            public $attr2 = 1;
162
                        };
163
                    }
164
                },
165
                ['obj' => new AtLeast(['attr2'])],
166
            ],
167
            [
168
                ['obj' => ['attr1' => 1, 'attr2' => null]],
169
                ['obj' => new AtLeast(['attr1', 'attr2'])],
170
            ],
171
            [
172
                ['obj' => ['attr1' => null, 'attr2' => 1]],
173
                ['obj' => new AtLeast(['attr2'])],
174
            ],
175
            'more than "min" attributes are filled' => [
176
                ['attr1' => 1, 'attr2' => 2],
177
                [new AtLeast(['attr1', 'attr2'])],
178
            ],
179
            'min equals amount of attributes' => [
180
                ['attr1' => 1, 'attr2' => 2],
181
                [new AtLeast(['attr1', 'attr2'], min: 2)],
182
            ],
183
            'min equals amount of attributes, 0' => [
184
                [],
185
                [new AtLeast([], min: 0)],
186
            ],
187
            'class attribute' => [
188
                new AtLeastDto(1),
189
            ],
190
        ];
191
    }
192
193
    public function dataValidationFailed(): array
194
    {
195
        $class = new class () {
196
            public $attr1 = 1;
197
            public $attr2 = null;
198
        };
199
        $array = ['attr1' => 1, 'attr2' => null];
200
201
        return [
202
            'incorrect input' => [
203
                1,
204
                [new AtLeast(['attr2'])],
205
                ['' => ['The value must be an array or an object.']],
206
            ],
207
            'custom incorrect input message' => [
208
                1,
209
                [new AtLeast(['attr2'], incorrectInputMessage: 'Custom incorrect input message.')],
210
                ['' => ['Custom incorrect input message.']],
211
            ],
212
            'custom incorrect input message with parameters' => [
213
                1,
214
                [new AtLeast(['attr2'], incorrectInputMessage: 'Attribute - {attribute}, type - {type}.')],
215
                ['' => ['Attribute - , type - int.']],
216
            ],
217
            'custom incorrect input message with parameters, attribute set' => [
218
                ['attribute' => 1],
219
                [
220
                    'attribute' => new AtLeast(
221
                        ['attr2'],
222
                        incorrectInputMessage: 'Attribute - {attribute}, type - {type}.',
223
                    ),
224
                ],
225
                ['attribute' => ['Attribute - attribute, type - int.']],
226
            ],
227
            'object' => [
228
                $class,
229
                [new AtLeast(['attr2'])],
230
                ['' => ['At least 1 attribute from this list must be filled: "attr2".']],
231
            ],
232
            'object, custom min' => [
233
                $class,
234
                [new AtLeast(['attr1', 'attr2'], min: 2)],
235
                ['' => ['At least 2 attributes from this list must be filled: "attr1", "attr2".']],
236
            ],
237
            'array' => [
238
                $array,
239
                [new AtLeast(['attr2'])],
240
                ['' => ['At least 1 attribute from this list must be filled: "attr2".']],
241
            ],
242
            'array, custom min' => [
243
                $array,
244
                [new AtLeast(['attr1', 'attr2'], min: 2)],
245
                ['' => ['At least 2 attributes from this list must be filled: "attr1", "attr2".']],
246
            ],
247
            'custom message' => [
248
                $class,
249
                [new AtLeast(['attr1', 'attr2'], min: 2, message: 'Custom message.')],
250
                ['' => ['Custom message.']],
251
            ],
252
            'custom message with parameters' => [
253
                $class,
254
                [new AtLeast(['attr1', 'attr2'], min: 2, message: 'Attributes - {attributes}, min - {min}.')],
255
                ['' => ['Attributes - "attr1", "attr2", min - 2.']],
256
            ],
257
            'custom message with parameters, attribute set' => [
258
                ['data' => $class],
259
                ['data' => new AtLeast(['attr1', 'attr2'], min: 2, message: 'Attributes - {attributes}, min - {min}.')],
260
                ['data' => ['Attributes - "attr1", "attr2", min - 2.']],
261
            ],
262
            'class attribute, tranlation' => [
263
                new AtLeastDto(),
264
                null,
265
                ['' => ['At least 1 attribute from this list must be filled: "A", "B", "C".']],
266
            ],
267
        ];
268
    }
269
270
    public function testSkipOnError(): void
271
    {
272
        $this->testSkipOnErrorInternal(new AtLeast(['attr']), new AtLeast(['attr'], skipOnError: true));
273
    }
274
275
    public function testWhen(): void
276
    {
277
        $when = static fn (mixed $value): bool => $value !== null;
278
        $this->testWhenInternal(new AtLeast(['attr']), new AtLeast(['attr'], when: $when));
279
    }
280
281
    protected function getDifferentRuleInHandlerItems(): array
282
    {
283
        return [AtLeast::class, AtLeastHandler::class];
284
    }
285
}
286