Completed
Push — master ( 17ecb7...725fdf )
by Alexander
15:14
created

testValidationWithTimeAndOutputTimeZone()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 54
Code Lines 49

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 49
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 54
cc 1
rs 9.1127

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
namespace Yiisoft\Validator\Tests\Rule;
3
4
use IntlDateFormatter;
5
use PHPUnit\Framework\TestCase;
6
use Yiisoft\Validator\Rule\Date;
7
8
/**
9
 * @group validators
10
 */
11
class DateTest extends TestCase
12
{
13
    protected function setUp()
14
    {
15
        parent::setUp();
16
17
        IntlTestHelper::setIntlStatus($this);
0 ignored issues
show
Bug introduced by
The type Yiisoft\Validator\Tests\Rule\IntlTestHelper was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
19
        $this->mockApplication([
0 ignored issues
show
Bug introduced by
The method mockApplication() does not exist on Yiisoft\Validator\Tests\Rule\DateTest. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

19
        $this->/** @scrutinizer ignore-call */ 
20
               mockApplication([

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
20
            'timeZone' => 'UTC',
21
            'locale' => 'ru-RU',
22
        ]);
23
    }
24
25
    protected function tearDown()
26
    {
27
        parent::tearDown();
28
        IntlTestHelper::resetIntlStatus();
29
    }
30
31
    public function testEnsureMessageIsSet()
32
    {
33
        $val = new Date();
34
        $this->assertTrue($val->message !== null && strlen($val->message) > 1);
0 ignored issues
show
Bug introduced by
The property message is declared private in Yiisoft\Validator\Rule\Date and cannot be accessed from this context.
Loading history...
35
    }
36
37
    /**
38
     * @dataProvider provideTimezones
39
     * @param string $timezone
40
     */
41
    public function testIntlvalidate($timezone)
42
    {
43
        date_default_timezone_set($timezone);
44
        $this->testvalidate($timezone);
45
46
        $this->mockApplication(['locale' => 'en-GB'], null, [
47
            'formatter' => [
48
                '__class' => \yii\i18n\Formatter::class,
0 ignored issues
show
Bug introduced by
The type yii\i18n\Formatter was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
49
                'dateFormat' => 'short',
50
            ],
51
        ]);
52
        $f = $this->container->get('formatter');
0 ignored issues
show
Bug Best Practice introduced by
The property container does not exist on Yiisoft\Validator\Tests\Rule\DateTest. Did you maybe forget to declare it?
Loading history...
Unused Code introduced by
The assignment to $f is dead and can be removed.
Loading history...
53
        $val = new Date();
54
        $this->assertTrue($val->validate('31/5/2017'));
55
        $this->assertFalse($val->validate('5/31/2017'));
56
        $val = new Date(['format' => 'short', 'locale' => 'en-GB']);
0 ignored issues
show
Unused Code introduced by
The call to Yiisoft\Validator\Rule\Date::__construct() has too many arguments starting with array('format' => 'short', 'locale' => 'en-GB'). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

56
        $val = /** @scrutinizer ignore-call */ new Date(['format' => 'short', 'locale' => 'en-GB']);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
57
        $this->assertTrue($val->validate('31/5/2017'));
58
        $this->assertFalse($val->validate('5/31/2017'));
59
60
        $this->mockApplication(['locale' => 'de-DE'], null, [
61
            'formatter' => [
62
                '__class' => \yii\i18n\Formatter::class,
63
                'dateFormat' => 'short',
64
            ],
65
        ]);
66
        $val = new Date();
67
        $this->assertTrue($val->validate('31.5.2017'));
68
        $this->assertFalse($val->validate('5.31.2017'));
69
        $val = new Date(['format' => 'short', 'locale' => 'de-DE']);
70
        $this->assertTrue($val->validate('31.5.2017'));
71
        $this->assertFalse($val->validate('5.31.2017'));
72
    }
73
74
    /**
75
     * @dataProvider provideTimezones
76
     * @param string $timezone
77
     */
78
    public function testvalidate($timezone)
79
    {
80
        date_default_timezone_set($timezone);
81
82
        // test PHP format
83
        $val = new Date(['format' => 'php:Y-m-d']);
0 ignored issues
show
Unused Code introduced by
The call to Yiisoft\Validator\Rule\Date::__construct() has too many arguments starting with array('format' => 'php:Y-m-d'). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

83
        $val = /** @scrutinizer ignore-call */ new Date(['format' => 'php:Y-m-d']);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
84
        $this->assertFalse($val->validate('3232-32-32'));
85
        $this->assertTrue($val->validate('2013-09-13'));
86
        $this->assertFalse($val->validate('31.7.2013'));
87
        $this->assertFalse($val->validate('31-7-2013'));
88
        $this->assertFalse($val->validate('20121212'));
89
        $this->assertFalse($val->validate('asdasdfasfd'));
90
        $this->assertFalse($val->validate('2012-12-12foo'));
91
        $this->assertFalse($val->validate(''));
92
        $this->assertFalse($val->validate(time()));
93
        $val->format = 'php:U';
94
        $this->assertTrue($val->validate(time()));
95
        $val->format = 'php:d.m.Y';
96
        $this->assertTrue($val->validate('31.7.2013'));
97
        $val->format = 'php:Y-m-!d H:i:s';
98
        $this->assertTrue($val->validate('2009-02-15 15:16:17'));
99
100
        // test ICU format
101
        $val = new Date(['format' => 'yyyy-MM-dd']);
102
        $this->assertFalse($val->validate('3232-32-32'));
103
        $this->assertTrue($val->validate('2013-09-13'));
104
        $this->assertFalse($val->validate('31.7.2013'));
105
        $this->assertFalse($val->validate('31-7-2013'));
106
        $this->assertFalse($val->validate('20121212'));
107
        $this->assertFalse($val->validate('asdasdfasfd'));
108
        $this->assertFalse($val->validate('2012-12-12foo'));
109
        $this->assertFalse($val->validate(''));
110
        $this->assertFalse($val->validate(time()));
111
        $val->format = 'dd.MM.yyyy';
112
        $this->assertTrue($val->validate('31.7.2013'));
113
        $val->format = 'yyyy-MM-dd HH:mm:ss';
114
        $this->assertTrue($val->validate('2009-02-15 15:16:17'));
115
    }
116
117
    /**
118
     * @dataProvider provideTimezones
119
     * @param string $timezone
120
     */
121
    public function testIntlValidateAttributePHPFormat($timezone)
122
    {
123
        $this->testValidateAttributePHPFormat($timezone);
124
    }
125
126
    /**
127
     * @dataProvider provideTimezones
128
     * @param string $timezone
129
     */
130
    public function testValidateAttributePHPFormat($timezone)
131
    {
132
        date_default_timezone_set($timezone);
133
134
        // error-array-add
135
        $val = new Date(['format' => 'php:Y-m-d']);
0 ignored issues
show
Unused Code introduced by
The call to Yiisoft\Validator\Rule\Date::__construct() has too many arguments starting with array('format' => 'php:Y-m-d'). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

135
        $val = /** @scrutinizer ignore-call */ new Date(['format' => 'php:Y-m-d']);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
136
        $model = new FakedValidationModel();
0 ignored issues
show
Bug introduced by
The type Yiisoft\Validator\Tests\Rule\FakedValidationModel was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
137
        $model->attr_date = '2013-09-13';
138
        $val->validateAttribute($model, 'attr_date');
0 ignored issues
show
Bug introduced by
The method validateAttribute() does not exist on Yiisoft\Validator\Rule\Date. Did you maybe mean validate()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

138
        $val->/** @scrutinizer ignore-call */ 
139
              validateAttribute($model, 'attr_date');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
139
        $this->assertFalse($model->hasErrors('attr_date'));
140
        $model = new FakedValidationModel();
141
        $model->attr_date = '1375293913';
142
        $val->validateAttribute($model, 'attr_date');
143
        $this->assertTrue($model->hasErrors('attr_date'));
144
        //// timestamp attribute
145
        $val = new Date(['format' => 'php:Y-m-d', 'timestampAttribute' => 'attr_timestamp']);
146
        $model = new FakedValidationModel();
147
        $model->attr_date = '2013-09-13';
148
        $model->attr_timestamp = true;
149
        $val->validateAttribute($model, 'attr_date');
150
        $this->assertFalse($model->hasErrors('attr_date'));
151
        $this->assertFalse($model->hasErrors('attr_timestamp'));
152
        $this->assertEquals(
153
            1379030400, // 2013-09-13 00:00:00
154
            $model->attr_timestamp
155
        );
156
        // array value
157
        $val = new Date(['format' => 'php:Y-m-d']);
158
        $model = FakedValidationModel::createWithAttributes(['attr_date' => ['2013-09-13']]);
159
        $val->validateAttribute($model, 'attr_date');
160
        $this->assertTrue($model->hasErrors('attr_date'));
161
    }
162
163
    /**
164
     * @dataProvider provideTimezones
165
     * @param string $timezone
166
     */
167
    public function testIntlValidateAttributeICUFormat($timezone)
168
    {
169
        $this->testValidateAttributeICUFormat($timezone);
170
    }
171
172
    /**
173
     * @dataProvider provideTimezones
174
     * @param string $timezone
175
     */
176
    public function testValidateAttributeICUFormat($timezone)
177
    {
178
        date_default_timezone_set($timezone);
179
180
        // error-array-add
181
        $val = new Date(['format' => 'yyyy-MM-dd']);
0 ignored issues
show
Unused Code introduced by
The call to Yiisoft\Validator\Rule\Date::__construct() has too many arguments starting with array('format' => 'yyyy-MM-dd'). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

181
        $val = /** @scrutinizer ignore-call */ new Date(['format' => 'yyyy-MM-dd']);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
182
        $model = new FakedValidationModel();
183
        $model->attr_date = '2013-09-13';
184
        $val->validateAttribute($model, 'attr_date');
185
        $this->assertFalse($model->hasErrors('attr_date'));
186
        $model = new FakedValidationModel();
187
        $model->attr_date = '1375293913';
188
        $val->validateAttribute($model, 'attr_date');
189
        $this->assertTrue($model->hasErrors('attr_date'));
190
        //// timestamp attribute
191
        $val = new Date(['format' => 'yyyy-MM-dd', 'timestampAttribute' => 'attr_timestamp']);
192
        $model = new FakedValidationModel();
193
        $model->attr_date = '2013-09-13';
194
        $model->attr_timestamp = true;
195
        $val->validateAttribute($model, 'attr_date');
196
        $this->assertFalse($model->hasErrors('attr_date'));
197
        $this->assertFalse($model->hasErrors('attr_timestamp'));
198
        $this->assertSame(
199
            1379030400, // 2013-09-13 00:00:00
200
            $model->attr_timestamp
201
        );
202
        // array value
203
        $val = new Date(['format' => 'yyyy-MM-dd']);
204
        $model = FakedValidationModel::createWithAttributes(['attr_date' => ['2013-09-13']]);
205
        $val->validateAttribute($model, 'attr_date');
206
        $this->assertTrue($model->hasErrors('attr_date'));
207
        // invalid format
208
        $val = new Date(['format' => 'yyyy-MM-dd']);
209
        $model = FakedValidationModel::createWithAttributes(['attr_date' => '2012-12-12foo']);
210
        $val->validateAttribute($model, 'attr_date');
211
        $this->assertTrue($model->hasErrors('attr_date'));
212
    }
213
214
    public function testIntlMultibyteString()
215
    {
216
        $val = new Date(['format' => 'dd MMM yyyy', 'locale' => 'de_DE']);
0 ignored issues
show
Unused Code introduced by
The call to Yiisoft\Validator\Rule\Date::__construct() has too many arguments starting with array('format' => 'dd MM...', 'locale' => 'de_DE'). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

216
        $val = /** @scrutinizer ignore-call */ new Date(['format' => 'dd MMM yyyy', 'locale' => 'de_DE']);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
217
        $model = FakedValidationModel::createWithAttributes(['attr_date' => '12 Mai 2014']);
218
        $val->validateAttribute($model, 'attr_date');
219
        $this->assertFalse($model->hasErrors('attr_date'));
220
221
        $val = new Date(['format' => 'dd MMM yyyy', 'locale' => 'ru_RU']);
222
        $model = FakedValidationModel::createWithAttributes(['attr_date' => '12 мая 2014']);
223
        $val->validateAttribute($model, 'attr_date');
224
        $this->assertFalse($model->hasErrors('attr_date'));
225
    }
226
227
    public function provideTimezones()
228
    {
229
        return [
230
            ['UTC'],
231
            ['Europe/Berlin'],
232
            ['America/Jamaica'],
233
        ];
234
    }
235
236
    public function timestampFormatProvider()
237
    {
238
        $return = [];
239
        foreach ($this->provideTimezones() as $appTz) {
240
            foreach ($this->provideTimezones() as $tz) {
241
                $return[] = ['yyyy-MM-dd', '2013-09-13', '2013-09-13', $tz[0], $appTz[0]];
242
                // regardless of timezone, a simple date input should always result in 00:00:00 time
243
                $return[] = ['yyyy-MM-dd HH:mm:ss', '2013-09-13', '2013-09-13 00:00:00', $tz[0], $appTz[0]];
244
                $return[] = ['php:Y-m-d', '2013-09-13', '2013-09-13', $tz[0], $appTz[0]];
245
                $return[] = ['php:Y-m-d H:i:s', '2013-09-13', '2013-09-13 00:00:00', $tz[0], $appTz[0]];
246
                $return[] = ['php:U', '2013-09-13', '1379030400', $tz[0], $appTz[0]];
247
                $return[] = [null, '2013-09-13', 1379030400, $tz[0], $appTz[0]];
248
            }
249
        }
250
251
        return $return;
252
    }
253
254
    /**
255
     * @dataProvider timestampFormatProvider
256
     * @param string|null $format
257
     * @param string $date
258
     * @param string|int $expectedDate
259
     * @param string $timezone
260
     * @param string $appTimezone
261
     */
262
    public function testIntlTimestampAttributeFormat($format, $date, $expectedDate, $timezone, $appTimezone)
263
    {
264
        $this->testTimestampAttributeFormat($format, $date, $expectedDate, $timezone, $appTimezone);
265
    }
266
267
    /**
268
     * @dataProvider timestampFormatProvider
269
     * @param string|null $format
270
     * @param string $date
271
     * @param string|int $expectedDate
272
     * @param string $timezone
273
     * @param string $appTimezone
274
     */
275
    public function testTimestampAttributeFormat($format, $date, $expectedDate, $timezone, $appTimezone)
276
    {
277
        date_default_timezone_set($timezone);
278
279
        $val = new Date(['format' => 'yyyy-MM-dd', 'timestampAttribute' => 'attr_timestamp', 'timestampAttributeFormat' => $format, 'timeZone' => $appTimezone]);
0 ignored issues
show
Unused Code introduced by
The call to Yiisoft\Validator\Rule\Date::__construct() has too many arguments starting with array('format' => 'yyyy-...eZone' => $appTimezone). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

279
        $val = /** @scrutinizer ignore-call */ new Date(['format' => 'yyyy-MM-dd', 'timestampAttribute' => 'attr_timestamp', 'timestampAttributeFormat' => $format, 'timeZone' => $appTimezone]);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
280
        $model = new FakedValidationModel();
281
        $model->attr_date = $date;
282
        $model->attr_timestamp = true;
283
        $val->validateAttribute($model, 'attr_date');
284
        $this->assertFalse($model->hasErrors('attr_date'));
285
        $this->assertFalse($model->hasErrors('attr_timestamp'));
286
        $this->assertSame($expectedDate, $model->attr_timestamp);
287
    }
288
289
    /**
290
     * @dataProvider provideTimezones
291
     * @param string $timezone
292
     */
293
    public function testIntlValidationWithTime($timezone)
294
    {
295
        // prepare data for specific ICU version, see https://github.com/yiisoft/yii2/issues/15140
296
        switch (true) {
297
            case (version_compare(INTL_ICU_VERSION, '57.1', '>=')):
298
            case (INTL_ICU_VERSION === '55.1'):
299
                $enGB_dateTime_valid = '31/05/2017, 12:30';
300
                $enGB_dateTime_invalid = '05/31/2017, 12:30';
301
                $deDE_dateTime_valid = '31.05.2017, 12:30';
302
                $deDE_dateTime_invalid = '05.31.2017, 12:30';
303
                break;
304
            default:
305
                $enGB_dateTime_valid = '31/5/2017 12:30';
306
                $enGB_dateTime_invalid = '5/31/2017 12:30';
307
                $deDE_dateTime_valid = '31.5.2017 12:30';
308
                $deDE_dateTime_invalid = '5.31.2017 12:30';
309
        }
310
311
        $this->testValidationWithTime($timezone);
312
313
        $this->mockApplication(['locale' => 'en-GB'], null, [
314
            'formatter' => [
315
                '__class' => \yii\i18n\Formatter::class,
316
                'dateFormat' => 'long',
317
                'datetimeFormat' => 'short', // this is the format to be used by the validator by default
318
            ],
319
        ]);
320
        $val = new Date(['type' => Date::TYPE_DATETIME]);
0 ignored issues
show
Unused Code introduced by
The call to Yiisoft\Validator\Rule\Date::__construct() has too many arguments starting with array('type' => Yiisoft\...le\Date::TYPE_DATETIME). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

320
        $val = /** @scrutinizer ignore-call */ new Date(['type' => Date::TYPE_DATETIME]);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
321
        $this->assertTrue($val->validate($enGB_dateTime_valid));
322
        $this->assertFalse($val->validate($enGB_dateTime_invalid));
323
        $val = new Date(['format' => 'short', 'locale' => 'en-GB', 'type' => Date::TYPE_DATETIME]);
324
        $this->assertTrue($val->validate($enGB_dateTime_valid));
325
        $this->assertFalse($val->validate($enGB_dateTime_invalid));
326
327
        $this->mockApplication(['locale' => 'de-DE'], null, [
328
            'formatter' => [
329
                '__class' => \yii\i18n\Formatter::class,
330
                'dateFormat' => 'long',
331
                'datetimeFormat' => 'short', // this is the format to be used by the validator by default
332
            ],
333
        ]);
334
        $val = new Date(['type' => Date::TYPE_DATETIME]);
335
        $this->assertTrue($val->validate($deDE_dateTime_valid));
336
        $this->assertFalse($val->validate($deDE_dateTime_invalid));
337
        $val = new Date(['format' => 'short', 'locale' => 'de-DE', 'type' => Date::TYPE_DATETIME]);
338
        $this->assertTrue($val->validate($deDE_dateTime_valid));
339
        $this->assertFalse($val->validate($deDE_dateTime_invalid));
340
    }
341
342
    /**
343
     * @dataProvider provideTimezones
344
     * @param string $timezone
345
     */
346
    public function testValidationWithTime($timezone)
347
    {
348
        date_default_timezone_set($timezone);
349
350
        $val = new Date(['format' => 'yyyy-MM-dd HH:mm:ss', 'timestampAttribute' => 'attr_timestamp', 'timeZone' => 'UTC']);
0 ignored issues
show
Unused Code introduced by
The call to Yiisoft\Validator\Rule\Date::__construct() has too many arguments starting with array('format' => 'yyyy-...', 'timeZone' => 'UTC'). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

350
        $val = /** @scrutinizer ignore-call */ new Date(['format' => 'yyyy-MM-dd HH:mm:ss', 'timestampAttribute' => 'attr_timestamp', 'timeZone' => 'UTC']);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
351
        $model = new FakedValidationModel();
352
        $model->attr_date = '2013-09-13 14:23:15';
353
        $model->attr_timestamp = true;
354
        $val->validateAttribute($model, 'attr_date');
355
        $this->assertFalse($model->hasErrors('attr_date'));
356
        $this->assertFalse($model->hasErrors('attr_timestamp'));
357
        $this->assertSame(1379082195, $model->attr_timestamp);
358
359
        $val = new Date(['format' => 'yyyy-MM-dd HH:mm:ss', 'timestampAttribute' => 'attr_timestamp', 'timeZone' => 'Europe/Berlin']);
360
        $model = new FakedValidationModel();
361
        $model->attr_date = '2013-09-13 16:23:15';
362
        $model->attr_timestamp = true;
363
        $val->validateAttribute($model, 'attr_date');
364
        $this->assertFalse($model->hasErrors('attr_date'));
365
        $this->assertFalse($model->hasErrors('attr_timestamp'));
366
        $this->assertSame(1379082195, $model->attr_timestamp);
367
368
        $val = new Date(['format' => 'yyyy-MM-dd HH:mm:ss', 'timestampAttribute' => 'attr_timestamp', 'timestampAttributeFormat' => 'yyyy-MM-dd HH:mm:ss', 'timeZone' => 'UTC']);
369
        $model = new FakedValidationModel();
370
        $model->attr_date = '2013-09-13 14:23:15';
371
        $model->attr_timestamp = true;
372
        $val->validateAttribute($model, 'attr_date');
373
        $this->assertFalse($model->hasErrors('attr_date'));
374
        $this->assertFalse($model->hasErrors('attr_timestamp'));
375
        $this->assertSame('2013-09-13 14:23:15', $model->attr_timestamp);
376
377
        $val = new Date(['format' => 'yyyy-MM-dd HH:mm:ss', 'timestampAttribute' => 'attr_timestamp', 'timestampAttributeFormat' => 'yyyy-MM-dd HH:mm:ss', 'timeZone' => 'Europe/Berlin']);
378
        $model = new FakedValidationModel();
379
        $model->attr_date = '2013-09-13 16:23:15';
380
        $model->attr_timestamp = true;
381
        $val->validateAttribute($model, 'attr_date');
382
        $this->assertFalse($model->hasErrors('attr_date'));
383
        $this->assertFalse($model->hasErrors('attr_timestamp'));
384
        $this->assertSame('2013-09-13 14:23:15', $model->attr_timestamp);
385
386
        $val = new Date(['format' => 'yyyy-MM-dd HH:mm:ss', 'timestampAttribute' => 'attr_timestamp', 'timestampAttributeFormat' => 'php:Y-m-d H:i:s', 'timeZone' => 'UTC']);
387
        $model = new FakedValidationModel();
388
        $model->attr_date = '2013-09-13 14:23:15';
389
        $model->attr_timestamp = true;
390
        $val->validateAttribute($model, 'attr_date');
391
        $this->assertFalse($model->hasErrors('attr_date'));
392
        $this->assertFalse($model->hasErrors('attr_timestamp'));
393
        $this->assertSame('2013-09-13 14:23:15', $model->attr_timestamp);
394
395
        $val = new Date(['format' => 'yyyy-MM-dd HH:mm:ss', 'timestampAttribute' => 'attr_timestamp', 'timestampAttributeFormat' => 'php:Y-m-d H:i:s', 'timeZone' => 'Europe/Berlin']);
396
        $model = new FakedValidationModel();
397
        $model->attr_date = '2013-09-13 16:23:15';
398
        $model->attr_timestamp = true;
399
        $val->validateAttribute($model, 'attr_date');
400
        $this->assertFalse($model->hasErrors('attr_date'));
401
        $this->assertFalse($model->hasErrors('attr_timestamp'));
402
        $this->assertSame('2013-09-13 14:23:15', $model->attr_timestamp);
403
    }
404
405
    /**
406
     * @dataProvider provideTimezones
407
     * @param string $timezone
408
     */
409
    public function testIntlValidationWithTimeAndOutputTimeZone($timezone)
410
    {
411
        $this->testValidationWithTime($timezone);
412
    }
413
414
    /**
415
     * @dataProvider provideTimezones
416
     * @param string $timezone
417
     */
418
    public function testValidationWithTimeAndOutputTimeZone($timezone)
419
    {
420
        date_default_timezone_set($timezone);
421
422
        $val = new Date(['format' => 'yyyy-MM-dd HH:mm:ss', 'timestampAttribute' => 'attr_timestamp', 'timestampAttributeFormat' => 'yyyy-MM-dd HH:mm:ss', 'timestampAttributeTimeZone' => 'Europe/Berlin', 'timeZone' => 'UTC']);
0 ignored issues
show
Unused Code introduced by
The call to Yiisoft\Validator\Rule\Date::__construct() has too many arguments starting with array('format' => 'yyyy-...', 'timeZone' => 'UTC'). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

422
        $val = /** @scrutinizer ignore-call */ new Date(['format' => 'yyyy-MM-dd HH:mm:ss', 'timestampAttribute' => 'attr_timestamp', 'timestampAttributeFormat' => 'yyyy-MM-dd HH:mm:ss', 'timestampAttributeTimeZone' => 'Europe/Berlin', 'timeZone' => 'UTC']);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
423
        $model = new FakedValidationModel();
424
        $model->attr_date = '2013-09-13 14:23:15';
425
        $model->attr_timestamp = true;
426
        $val->validateAttribute($model, 'attr_date');
427
        $this->assertFalse($model->hasErrors('attr_date'));
428
        $this->assertFalse($model->hasErrors('attr_timestamp'));
429
        $this->assertSame('2013-09-13 16:23:15', $model->attr_timestamp);
430
        $val = new Date(['format' => 'php:Y-m-d H:i:s', 'timestampAttribute' => 'attr_timestamp', 'timestampAttributeFormat' => 'yyyy-MM-dd HH:mm:ss', 'timestampAttributeTimeZone' => 'Europe/Berlin', 'timeZone' => 'UTC']);
431
        $model = new FakedValidationModel();
432
        $model->attr_date = '2013-09-13 14:23:15';
433
        $model->attr_timestamp = true;
434
        $val->validateAttribute($model, 'attr_date');
435
        $this->assertFalse($model->hasErrors('attr_date'));
436
        $this->assertFalse($model->hasErrors('attr_timestamp'));
437
        $this->assertSame('2013-09-13 16:23:15', $model->attr_timestamp);
438
439
        $val = new Date(['format' => 'yyyy-MM-dd HH:mm:ss', 'timestampAttribute' => 'attr_timestamp', 'timestampAttributeFormat' => 'yyyy-MM-dd HH:mm:ss', 'timestampAttributeTimeZone' => 'Europe/Berlin', 'timeZone' => 'Europe/Berlin']);
440
        $model = new FakedValidationModel();
441
        $model->attr_date = '2013-09-13 16:23:15';
442
        $model->attr_timestamp = true;
443
        $val->validateAttribute($model, 'attr_date');
444
        $this->assertFalse($model->hasErrors('attr_date'));
445
        $this->assertFalse($model->hasErrors('attr_timestamp'));
446
        $this->assertSame('2013-09-13 16:23:15', $model->attr_timestamp);
447
        $val = new Date(['format' => 'php:Y-m-d H:i:s', 'timestampAttribute' => 'attr_timestamp', 'timestampAttributeFormat' => 'yyyy-MM-dd HH:mm:ss', 'timestampAttributeTimeZone' => 'Europe/Berlin', 'timeZone' => 'Europe/Berlin']);
448
        $model = new FakedValidationModel();
449
        $model->attr_date = '2013-09-13 16:23:15';
450
        $model->attr_timestamp = true;
451
        $val->validateAttribute($model, 'attr_date');
452
        $this->assertFalse($model->hasErrors('attr_date'));
453
        $this->assertFalse($model->hasErrors('attr_timestamp'));
454
        $this->assertSame('2013-09-13 16:23:15', $model->attr_timestamp);
455
456
        $val = new Date(['format' => 'yyyy-MM-dd HH:mm:ss', 'timestampAttribute' => 'attr_timestamp', 'timestampAttributeFormat' => 'yyyy-MM-dd HH:mm:ss', 'timestampAttributeTimeZone' => 'America/New_York', 'timeZone' => 'Europe/Berlin']);
457
        $model = new FakedValidationModel();
458
        $model->attr_date = '2013-09-13 16:23:15';
459
        $model->attr_timestamp = true;
460
        $val->validateAttribute($model, 'attr_date');
461
        $this->assertFalse($model->hasErrors('attr_date'));
462
        $this->assertFalse($model->hasErrors('attr_timestamp'));
463
        $this->assertSame('2013-09-13 10:23:15', $model->attr_timestamp);
464
        $val = new Date(['format' => 'php:Y-m-d H:i:s', 'timestampAttribute' => 'attr_timestamp', 'timestampAttributeFormat' => 'yyyy-MM-dd HH:mm:ss', 'timestampAttributeTimeZone' => 'America/New_York', 'timeZone' => 'Europe/Berlin']);
465
        $model = new FakedValidationModel();
466
        $model->attr_date = '2013-09-13 16:23:15';
467
        $model->attr_timestamp = true;
468
        $val->validateAttribute($model, 'attr_date');
469
        $this->assertFalse($model->hasErrors('attr_date'));
470
        $this->assertFalse($model->hasErrors('attr_timestamp'));
471
        $this->assertSame('2013-09-13 10:23:15', $model->attr_timestamp);
472
    }
473
474
    public function testIntlValidateRange()
475
    {
476
        $this->testvalidateRange();
477
    }
478
479
    public function testvalidateRange()
480
    {
481
        if (PHP_INT_SIZE == 8) { // this passes only on 64bit systems
482
            // intl parser allows 14 for yyyy pattern, see the following for more details:
483
            // https://github.com/yiisoft/yii2/blob/a003a8fb487dfa60c0f88ecfacf18a7407ced18b/framework/validators/DateValidator.php#L51-L57
484
            $date = '14-09-13';
485
            $val = new Date(['format' => 'yyyy-MM-dd']);
0 ignored issues
show
Unused Code introduced by
The call to Yiisoft\Validator\Rule\Date::__construct() has too many arguments starting with array('format' => 'yyyy-MM-dd'). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

485
            $val = /** @scrutinizer ignore-call */ new Date(['format' => 'yyyy-MM-dd']);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
486
            $this->assertTrue($val->validate($date), "$date is valid");
487
488
            $min = '1900-01-01';
489
            $beforeMin = '1899-12-31';
490
        } else {
491
            $min = '1920-01-01';
492
            $beforeMin = '1919-12-31';
493
        }
494
495
        $val = new Date(['format' => 'yyyy-MM-dd', 'min' => $min]);
496
        $date = '1958-01-12';
497
        $this->assertTrue($val->validate($date), "$date is valid");
498
499
        $val = new Date(['format' => 'yyyy-MM-dd', 'max' => '2000-01-01']);
500
        $date = '2014-09-13';
501
        $this->assertFalse($val->validate($date), "$date is too big");
502
        $date = '1958-01-12';
503
        $this->assertTrue($val->validate($date), "$date is valid");
504
505
        $val = new Date(['format' => 'yyyy-MM-dd', 'min' => $min, 'max' => '2000-01-01']);
506
        $this->assertTrue($val->validate('1999-12-31'), 'max -1 day is valid');
507
        $this->assertTrue($val->validate('2000-01-01'), 'max is inside range');
508
        $this->assertTrue($val->validate($min), 'min is inside range');
509
        $this->assertFalse($val->validate($beforeMin), 'min -1 day is invalid');
510
        $this->assertFalse($val->validate('2000-01-02'), 'max +1 day is invalid');
511
    }
512
513
    private function validateModelAttribute($validator, $date, $expected, $message = '')
514
    {
515
        $model = new FakedValidationModel();
516
        $model->attr_date = $date;
517
        $validator->validateAttribute($model, 'attr_date');
518
        if (!$expected) {
519
            $this->assertTrue($model->hasErrors('attr_date'), $message);
520
        } else {
521
            $this->assertFalse($model->hasErrors('attr_date'), $message);
522
        }
523
    }
524
525
    public function testIntlValidateAttributeRange()
526
    {
527
        $this->testValidateAttributeRange();
528
    }
529
530
    public function testValidateAttributeRange()
531
    {
532
        if (PHP_INT_SIZE == 8) { // this passes only on 64bit systems
533
            // intl parser allows 14 for yyyy pattern, see the following for more details:
534
            // https://github.com/yiisoft/yii2/blob/a003a8fb487dfa60c0f88ecfacf18a7407ced18b/framework/validators/DateValidator.php#L51-L57
535
            $val = new Date(['format' => 'yyyy-MM-dd']);
0 ignored issues
show
Unused Code introduced by
The call to Yiisoft\Validator\Rule\Date::__construct() has too many arguments starting with array('format' => 'yyyy-MM-dd'). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

535
            $val = /** @scrutinizer ignore-call */ new Date(['format' => 'yyyy-MM-dd']);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
536
            $date = '14-09-13';
537
            $this->validateModelAttribute($val, $date, true, "$date is valid");
538
539
            $min = '1900-01-01';
540
            $beforeMin = '1899-12-31';
541
        } else {
542
            $min = '1920-01-01';
543
            $beforeMin = '1919-12-31';
544
        }
545
546
        $val = new Date(['format' => 'yyyy-MM-dd', 'min' => $min]);
547
        $date = '1958-01-12';
548
        $this->validateModelAttribute($val, $date, true, "$date is valid");
549
550
        $val = new Date(['format' => 'yyyy-MM-dd', 'max' => '2000-01-01']);
551
        $date = '2014-09-13';
552
        $this->validateModelAttribute($val, $date, false, "$date is too big");
553
        $date = '1958-01-12';
554
        $this->validateModelAttribute($val, $date, true, "$date is valid");
555
556
        $val = new Date(['format' => 'yyyy-MM-dd', 'min' => $min, 'max' => '2000-01-01']);
557
        $this->validateModelAttribute($val, '1999-12-31', true, 'max -1 day is valid');
558
        $this->validateModelAttribute($val, '2000-01-01', true, 'max is inside range');
559
        $this->validateModelAttribute($val, $min, true, 'min is inside range');
560
        $this->validateModelAttribute($val, $beforeMin, false, 'min -1 day is invalid');
561
        $this->validateModelAttribute($val, '2000-01-02', false, 'max +1 day is invalid');
562
    }
563
564
    public function testIntlvalidateRangeOld()
565
    {
566
        if ($this->checkOldIcuBug()) {
567
            $this->markTestSkipped('ICU is too old.');
568
        }
569
        $date = '14-09-13';
570
        $val = new Date(['format' => 'yyyy-MM-dd', 'min' => '1920-01-01']);
0 ignored issues
show
Unused Code introduced by
The call to Yiisoft\Validator\Rule\Date::__construct() has too many arguments starting with array('format' => 'yyyy-... 'min' => '1920-01-01'). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

570
        $val = /** @scrutinizer ignore-call */ new Date(['format' => 'yyyy-MM-dd', 'min' => '1920-01-01']);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
571
        $this->assertFalse($val->validate($date), "$date is too small");
572
    }
573
574
    public function testIntlValidateAttributeRangeOld()
575
    {
576
        if ($this->checkOldIcuBug()) {
577
            $this->markTestSkipped('ICU is too old.');
578
        }
579
        $date = '14-09-13';
580
        $val = new Date(['format' => 'yyyy-MM-dd', 'min' => '1920-01-01']);
0 ignored issues
show
Unused Code introduced by
The call to Yiisoft\Validator\Rule\Date::__construct() has too many arguments starting with array('format' => 'yyyy-... 'min' => '1920-01-01'). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

580
        $val = /** @scrutinizer ignore-call */ new Date(['format' => 'yyyy-MM-dd', 'min' => '1920-01-01']);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
581
        $this->validateModelAttribute($val, $date, false, "$date is too small");
582
    }
583
584
    /**
585
     * Returns true if the version of ICU is old and has a bug that makes it
586
     * impossible to parse two digit years properly.
587
     * @see http://bugs.icu-project.org/trac/ticket/9836
588
     * @return bool
589
     */
590
    private function checkOldIcuBug()
591
    {
592
        $date = '14';
593
        $formatter = new IntlDateFormatter('en-US', IntlDateFormatter::NONE, IntlDateFormatter::NONE, null, null, 'yyyy');
594
        $parsePos = 0;
595
        $parsedDate = @$formatter->parse($date, $parsePos);
596
597
        if (is_int($parsedDate) && $parsedDate > 0) {
598
            return true;
599
        }
600
601
        return false;
602
    }
603
604
    /**
605
     * @depends testValidateAttributePHPFormat
606
     */
607
    public function testTimestampAttributeSkipValidation()
608
    {
609
        // timestamp as integer
610
        $val = new Date(['format' => 'php:Y/m/d', 'timestampAttribute' => 'attr_date']);
0 ignored issues
show
Unused Code introduced by
The call to Yiisoft\Validator\Rule\Date::__construct() has too many arguments starting with array('format' => 'php:Y...ribute' => 'attr_date'). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

610
        $val = /** @scrutinizer ignore-call */ new Date(['format' => 'php:Y/m/d', 'timestampAttribute' => 'attr_date']);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
611
        $model = new FakedValidationModel();
612
        $model->attr_date = 1379030400;
613
        $val->validateAttribute($model, 'attr_date');
614
        $this->assertFalse($model->hasErrors('attr_date'));
615
616
        $val = new Date(['format' => 'php:Y/m/d', 'timestampAttribute' => 'attr_date']);
617
        $model = new FakedValidationModel();
618
        $model->attr_date = 'invalid';
619
        $val->validateAttribute($model, 'attr_date');
620
        $this->assertTrue($model->hasErrors('attr_date'));
621
622
        // timestamp as formatted date
623
        $val = new Date(['format' => 'php:Y/m/d', 'timestampAttribute' => 'attr_date', 'timestampAttributeFormat' => 'php:Y-m-d']);
624
        $model = new FakedValidationModel();
625
        $model->attr_date = '2013-09-13';
626
        $val->validateAttribute($model, 'attr_date');
627
        $this->assertFalse($model->hasErrors('attr_date'));
628
629
        $val = new Date(['format' => 'php:Y/m/d', 'timestampAttribute' => 'attr_date', 'timestampAttributeFormat' => 'php:Y-m-d']);
630
        $model = new FakedValidationModel();
631
        $model->attr_date = '2013-09-2013';
632
        $val->validateAttribute($model, 'attr_date');
633
        $this->assertTrue($model->hasErrors('attr_date'));
634
    }
635
636
    /**
637
     * @depends testValidateAttributePHPFormat
638
     */
639
    public function testTimestampAttributeOnEmpty()
640
    {
641
        $validator = new Date([
0 ignored issues
show
Unused Code introduced by
The call to Yiisoft\Validator\Rule\Date::__construct() has too many arguments starting with array('format' => 'php:Y...'skipOnEmpty' => false). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

641
        $validator = /** @scrutinizer ignore-call */ new Date([

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
642
            'format' => 'php:Y/m/d',
643
            'timestampAttribute' => 'attr_date',
644
            'skipOnEmpty' => false,
645
        ]);
646
        $model = new FakedValidationModel();
647
        $model->attr_date = '';
648
        $validator->validateAttribute($model, 'attr_date');
649
        $this->assertFalse($model->hasErrors('attr_date'));
650
        $this->assertNull($model->attr_date);
651
652
        $validator = new Date([
653
            'format' => 'php:Y/m/d',
654
            'timestampAttribute' => 'attr_timestamp',
655
            'skipOnEmpty' => false,
656
        ]);
657
        $model = new FakedValidationModel();
658
        $model->attr_date = '';
659
        $model->attr_timestamp = 1379030400;
660
        $validator->validateAttribute($model, 'attr_date');
661
        $this->assertFalse($model->hasErrors('attr_date'));
662
        $this->assertNull($model->attr_timestamp);
663
    }
664
665
    /**
666
     * Tests that DateValidator with format `php:U` does not truncate timestamp to date.
667
     * @see https://github.com/yiisoft/yii2/issues/15628
668
     */
669
    public function testIssue15628()
670
    {
671
        $validator = new Date(['format' => 'php:U' , 'type' => Date::TYPE_DATETIME, 'timestampAttribute' => 'attr_date']);
0 ignored issues
show
Unused Code introduced by
The call to Yiisoft\Validator\Rule\Date::__construct() has too many arguments starting with array('format' => 'php:U...ribute' => 'attr_date'). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

671
        $validator = /** @scrutinizer ignore-call */ new Date(['format' => 'php:U' , 'type' => Date::TYPE_DATETIME, 'timestampAttribute' => 'attr_date']);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
672
        $model = new FakedValidationModel();
673
        $value = 1518023610;
674
        $model->attr_date = $value;
675
676
        $validator->validateAttribute($model, 'attr_date');
677
678
        $this->assertEquals($value, $model->attr_date);
679
    }
680
}
681