Completed
Push — master ( 7e59a6...719e85 )
by Dmitry
03:46
created

DomainValidatorTest::validDomainIdnInUrlProvider()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 22
rs 9.2
cc 1
eloc 16
nc 1
nop 0
1
<?php
2
3
namespace kdn\yii2\validators;
4
5
use kdn\yii2\validators\mocks\ModelMock;
6
use stdClass;
7
8
/**
9
 * Class DomainValidatorTest.
10
 * @package kdn\yii2\validators
11
 * @covers kdn\yii2\validators\DomainValidator::init
12
 */
13
class DomainValidatorTest extends TestCase
14
{
15
    /**
16
     * @var DomainValidator
17
     */
18
    protected $validator;
19
20
    /**
21
     * @inheritdoc
22
     */
23
    protected function setUp()
24
    {
25
        parent::setUp();
26
        $this->validator = new DomainValidator(['labelNumberMin' => 1]);
27
    }
28
29
    public static function validDomainProvider()
30
    {
31
        return [
32
            'one domain name label' => ['localhost'],
33
            'two domain name labels' => ['example.com'],
34
            'domain name with trailing dot' => ['example.com.'],
35
            '127 levels, 253 characters and trailing dot' => [
36
                'a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.' .
37
                'a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.' .
38
                'a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.' .
39
                'a.a.a.a.',
40
            ],
41
            'domain name labels with 63 characters' => [
42
                'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.' .
43
                'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.' .
44
                'example.com',
45
            ],
46
            'domain name with various symbols' => ['1.a-B.c2'],
47
            'Punycode, mixed domain name' => ['xn--e1afmkfd.test.xn--80akhbyknj4f'],
48
        ];
49
    }
50
51
    public static function validDomainInUrlProvider()
52
    {
53
        return [
54
            'HTTP, one domain name label' => ['http://localhost'],
55
            'HTTP, two domain name labels' => ['http://example.com/index.html'],
56
            'FTP, domain name with trailing dot' => ['ftp://example.com./img/dir/'],
57
            'HTTPS, 127 levels, 253 characters and trailing dot' => [
58
                'https://a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.' .
59
                'a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.' .
60
                'a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.' .
61
                'a.a.a.a./index.html',
62
            ],
63
            'missing scheme, domain name labels with 63 characters' => [
64
                '//aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.' .
65
                'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.' .
66
                'example.com',
67
            ],
68
            'complex URL, domain name with various symbols' => [
69
                'http://username:[email protected]:9090/path?a=b&c=d#anchor',
70
            ],
71
            'Punycode, FTP, mixed domain name' => ['ftp://xn--e1afmkfd.test.xn--80akhbyknj4f/img/dir/'],
72
        ];
73
    }
74
75
    public static function validDomainIdnProvider()
76
    {
77
        return [
78
            'IDN, one domain name label' => ['пример'],
79
            'IDN, two domain name labels' => ['пример.испытание'],
80
            'IDN, domain name with trailing dot' => ['пример.испытание.'],
81
            'IDN, mixed domain name' => ['пример.test.испытание'],
82
            'IDN, 34 levels, 253 characters (ф. == xn--t1a.) and trailing dot' => [
83
                'ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.s.s.s.',
84
            ],
85
            'IDN, domain name labels with 63 characters' => [
86
                'ффффффффффффффффффффффффффффффффффффффффффффффффффффффффф.' .
87
                'ффффффффффффффффффффффффффффффффффффффффффффффффффффффффф.' .
88
                'испытание'
89
            ],
90
            'IDN, domain name with various symbols' => ['1.a-B.cф2'],
91
            'IDN, hot beverage' => ['☕.us'],
92
            'IDN, full-width characters' => ['日本語。JP'],
93
        ];
94
    }
95
96
    public static function validDomainIdnInUrlProvider()
97
    {
98
        return [
99
            'IDN, HTTP, one domain name label' => ['http://пример'],
100
            'IDN, HTTP, two domain name labels' => ['http://пример.испытание/index.html'],
101
            'IDN, FTP, domain name with trailing dot' => ['ftp://пример.испытание./img/dir/'],
102
            'IDN, FTP, mixed domain name' => ['ftp://пример.test.испытание/img/dir/'],
103
            'IDN, HTTPS, 34 levels, 253 characters (ф. == xn--t1a.) and trailing dot' => [
104
                'https://ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.s.s.s./index.html',
105
            ],
106
            'IDN, missing scheme, domain name labels with 63 characters' => [
107
                '//ффффффффффффффффффффффффффффффффффффффффффффффффффффффффф.' .
108
                'ффффффффффффффффффффффффффффффффффффффффффффффффффффффффф.' .
109
                'испытание'
110
            ],
111
            'IDN, complex URL, domain name with various symbols' => [
112
                'http://username:[email protected]ф2:9090/path?a=ф&c=d#-пример',
113
            ],
114
            'IDN, HTTP, hot beverage' => ['http://☕.us/index.html'],
115
            'IDN, HTTP, full-width characters' => ['http://日本語。JP/index.html'],
116
        ];
117
    }
118
119
    public static function validDomainAllWithoutIdnProvider()
120
    {
121
        return array_merge(
122
            static::validDomainProvider(),
123
            static::validDomainInUrlProvider()
124
        );
125
    }
126
127
    public static function validDomainAllOnlyIdnProvider()
128
    {
129
        return array_merge(
130
            static::validDomainIdnProvider(),
131
            static::validDomainIdnInUrlProvider()
132
        );
133
    }
134
135
    public static function validDomainAllProvider()
136
    {
137
        return array_merge(
138
            static::validDomainProvider(),
139
            static::validDomainInUrlProvider(),
140
            static::validDomainIdnProvider(),
141
            static::validDomainIdnInUrlProvider()
142
        );
143
    }
144
145
    /**
146
     * @param string $value
147
     * @covers       kdn\yii2\validators\DomainValidator::validateValue
148
     * @dataProvider validDomainAllWithoutIdnProvider
149
     * @small
150
     */
151
    public function testValidDomain($value)
152
    {
153
        $this->assertTrue($this->validator->validate($value));
154
    }
155
156
    /**
157
     * @param string $value
158
     * @covers       kdn\yii2\validators\DomainValidator::getDefaultErrorMessages
159
     * @covers       kdn\yii2\validators\DomainValidator::getErrorMessage
160
     * @covers       kdn\yii2\validators\DomainValidator::validateValue
161
     * @dataProvider validDomainAllOnlyIdnProvider
162
     * @small
163
     */
164
    public function testInvalidDomainWithDisabledIdn($value)
165
    {
166
        $this->assertFalse($this->validator->validate($value, $errorMessage));
167
        $this->assertEquals(
168
            'Each label of the input value can consist of only latin letters, numbers and hyphens.',
169
            $errorMessage
170
        );
171
    }
172
173
    /**
174
     * @param string $value
175
     * @covers       kdn\yii2\validators\DomainValidator::validateValue
176
     * @dataProvider validDomainAllProvider
177
     * @small
178
     */
179
    public function testValidDomainWithEnabledIdn($value)
180
    {
181
        if (!function_exists('idn_to_ascii')) {
182
            $this->markTestSkipped('intl extension required.');
183
            return;
184
        }
185
186
        $this->validator->enableIDN = true;
187
        $this->testValidDomain($value);
188
    }
189
190
    /**
191
     * @covers kdn\yii2\validators\DomainValidator::getDefaultErrorMessages
192
     * @covers kdn\yii2\validators\DomainValidator::getErrorMessage
193
     * @covers kdn\yii2\validators\DomainValidator::validateValue
194
     * @medium
195
     */
196
    public function testDns()
197
    {
198
        $validator = $this->validator;
199
        $nonExistingDomain = 'non-existing-subdomain.example.com';
200
        $this->assertTrue($validator->validate($nonExistingDomain));
201
        $validator->checkDNS = true;
202
        $this->assertFalse($validator->validate($nonExistingDomain, $errorMessage));
203
        $this->assertEquals('DNS record corresponding to the input value not found.', $errorMessage);
204
205
        $data = [
206
            'google.com',
207
            'http://username:[email protected]:9090/path?a=b&c=d#anchor',
208
        ];
209
        foreach ($data as $value) {
210
            $this->assertTrue(
211
                $validator->validate($value),
212
                "Failed to validate \"$value\" (checkDNS = true)."
213
            );
214
        }
215
    }
216
217
    /**
218
     * @covers kdn\yii2\validators\DomainValidator::getDefaultErrorMessages
219
     * @covers kdn\yii2\validators\DomainValidator::getErrorMessage
220
     * @covers kdn\yii2\validators\DomainValidator::validateValue
221
     * @medium
222
     */
223
    public function testDnsWithEnabledIdn()
224
    {
225
        if (!function_exists('idn_to_ascii')) {
226
            $this->markTestSkipped('intl extension required.');
227
            return;
228
        }
229
230
        $validator = $this->validator;
231
        $validator->checkDNS = true;
232
        // enabling of IDN should not affect error message
233
        $validator->enableIDN = true;
234
        $this->assertFalse($validator->validate('non-existing-subdomain.example.com', $errorMessage));
235
        $this->assertEquals('DNS record corresponding to the input value not found.', $errorMessage);
236
237
        $data = [
238
            'google.com',
239
            'http://username:[email protected]:9090/path?a=b&c=d#anchor',
240
            'яндекс.рф',
241
            'http://username:password@яндекс.рф:9090/path?a=ф&c=d#-пример',
242
        ];
243
        foreach ($data as $value) {
244
            $this->assertTrue(
245
                $validator->validate($value),
246
                "Failed to validate \"$value\" (checkDNS = true, enableIDN = true)."
247
            );
248
        }
249
    }
250
251
    /**
252
     * @covers kdn\yii2\validators\DomainValidator::getDefaultErrorMessages
253
     * @covers kdn\yii2\validators\DomainValidator::getErrorMessage
254
     * @covers kdn\yii2\validators\DomainValidator::validateValue
255
     * @small
256
     */
257
    public function testUnderscore()
258
    {
259
        $validator = $this->validator;
260
        $validator->allowUnderscore = true;
261
262
        $data = [
263
            'ex_ample.com',
264
            'http://username:password@ex_ample.com:9090/path?a=b&c=d#anchor',
265
        ];
266
        foreach ($data as $value) {
267
            $this->assertTrue(
268
                $validator->validate($value),
269
                "Failed to validate \"$value\" (allowUnderscore = true)."
270
            );
271
        }
272
273
        $this->assertFalse($validator->validate('a_@_a', $errorMessage));
274
        if ($validator->enableIDN) {
275
            $expectedErrorMessage =
276
                'Each label of the input value can consist of only letters, numbers, hyphens and underscores.';
277
        } else {
278
            $expectedErrorMessage =
279
                'Each label of the input value can consist of only latin letters, numbers, hyphens and underscores.';
280
        }
281
        $this->assertEquals($expectedErrorMessage, $errorMessage);
282
    }
283
284
    /**
285
     * @covers kdn\yii2\validators\DomainValidator::getDefaultErrorMessages
286
     * @covers kdn\yii2\validators\DomainValidator::getErrorMessage
287
     * @covers kdn\yii2\validators\DomainValidator::validateValue
288
     * @small
289
     */
290
    public function testUnderscoreWithEnabledIdn()
291
    {
292
        if (!function_exists('idn_to_ascii')) {
293
            $this->markTestSkipped('intl extension required.');
294
            return;
295
        }
296
297
        $this->validator->enableIDN = true;
298
        $this->testUnderscore();
299
    }
300
301
    public static function urlNotAllowedProvider()
302
    {
303
        return array_merge(
304
            static::arrayAddColumn(static::validDomainProvider(), true),
305
            static::arrayAddColumn(static::validDomainInUrlProvider(), false)
306
        );
307
    }
308
309
    /**
310
     * @param string $value
311
     * @param boolean $expectedResult
312
     * @covers       kdn\yii2\validators\DomainValidator::validateValue
313
     * @uses         kdn\yii2\validators\DomainValidator::getDefaultErrorMessages
314
     * @uses         kdn\yii2\validators\DomainValidator::getErrorMessage
315
     * @dataProvider urlNotAllowedProvider
316
     * @small
317
     */
318
    public function testUrlNotAllowed($value, $expectedResult)
319
    {
320
        $validator = $this->validator;
321
        $validator->allowURL = false;
322
        $this->assertEquals($expectedResult, $validator->validate($value));
323
    }
324
325
    public static function urlNotAllowedProviderWithEnabledIdn()
326
    {
327
        return array_merge(
328
            static::urlNotAllowedProvider(),
329
            static::arrayAddColumn(static::validDomainIdnProvider(), true),
330
            static::arrayAddColumn(static::validDomainIdnInUrlProvider(), false)
331
        );
332
    }
333
334
    /**
335
     * @param string $value
336
     * @param boolean $expectedResult
337
     * @covers       kdn\yii2\validators\DomainValidator::validateValue
338
     * @uses         kdn\yii2\validators\DomainValidator::getDefaultErrorMessages
339
     * @uses         kdn\yii2\validators\DomainValidator::getErrorMessage
340
     * @dataProvider urlNotAllowedProviderWithEnabledIdn
341
     * @small
342
     */
343
    public function testUrlNotAllowedWithEnabledIdn($value, $expectedResult)
344
    {
345
        if (!function_exists('idn_to_ascii')) {
346
            $this->markTestSkipped('intl extension required.');
347
            return;
348
        }
349
350
        $this->validator->enableIDN = true;
351
        $this->testUrlNotAllowed($value, $expectedResult);
352
    }
353
354
    /**
355
     * @covers kdn\yii2\validators\DomainValidator::getDefaultErrorMessages
356
     * @covers kdn\yii2\validators\DomainValidator::getErrorMessage
357
     * @covers kdn\yii2\validators\DomainValidator::validateValue
358
     * @small
359
     */
360
    public function testLabelNumberMin()
361
    {
362
        $validator = $this->validator;
363
        $validator->labelNumberMin = 2;
364
        $this->assertFalse($validator->validate('localhost', $errorMessage));
365
        $this->assertEquals('the input value should consist of at least 2 labels separated by dot.', $errorMessage);
366
        $this->assertTrue($validator->validate('example.com'));
367
        $this->assertTrue($validator->validate('test.example.com'));
368
        $validator->labelNumberMin = 3;
369
        $this->assertFalse($validator->validate('example.com', $errorMessage));
370
        $this->assertEquals('the input value should consist of at least 3 labels separated by dots.', $errorMessage);
371
        $this->assertTrue($validator->validate('test.example.com'));
372
    }
373
374
    /**
375
     * @covers kdn\yii2\validators\DomainValidator::getDefaultErrorMessages
376
     * @covers kdn\yii2\validators\DomainValidator::getErrorMessage
377
     * @covers kdn\yii2\validators\DomainValidator::validateValue
378
     * @small
379
     */
380
    public function testLabelNumberMinWithEnabledIdn()
381
    {
382
        if (!function_exists('idn_to_ascii')) {
383
            $this->markTestSkipped('intl extension required.');
384
            return;
385
        }
386
387
        $this->validator->enableIDN = true;
388
        $this->testLabelNumberMin();
389
    }
390
391
    public static function invalidDomainProvider($testName)
392
    {
393
        if ($testName == 'testInvalidDomain') {
394
            $messageInvalidCharacter =
395
                'Each label of the input value can consist of only latin letters, numbers and hyphens.';
396
            $messageLabelStartEnd = 'Each label of the input value should start and end with latin letter or number.' .
397
                ' The rightmost label of the input value should start with latin letter.';
398
        } else {
399
            $messageInvalidCharacter =
400
                'Each label of the input value can consist of only letters, numbers and hyphens.';
401
            $messageLabelStartEnd = 'Each label of the input value should start and end with letter or number.' .
402
                ' The rightmost label of the input value should start with letter.';
403
        }
404
        $messageLabelTooLong = 'Each label of the input value should contain at most 63 characters.';
405
        $messageLabelTooShort = 'Each label of the input value should contain at least 1 character.';
406
        $messageNotString = 'the input value must be a string.';
407
        $messageTooLong = 'the input value should contain at most 253 characters.';
408
        $messageTooShort = 'the input value should contain at least 1 character.';
409
        return [
410
            'null' => [null, $messageNotString],
411
            'boolean' => [true, $messageNotString],
412
            'integer' => [1, $messageNotString],
413
            'float' => [1.2, $messageNotString],
414
            'array' => [[], $messageNotString],
415
            'object' => [new stdClass, $messageNotString],
416
417
            'domain name too long' => [str_repeat('a.', 126) . 'aa', $messageTooLong],
418
419
            'domain name too short' => ['', $messageTooShort],
420
421
            'first domain name label starts with hyphen' => ['-example.com', $messageLabelStartEnd],
422
            'first domain name label ends with hyphen' => ['example-.com', $messageLabelStartEnd],
423
            'last domain name label starts with hyphen' => ['example.-com', $messageLabelStartEnd],
424
            'last domain name label ends with hyphen' => ['example.com-', $messageLabelStartEnd],
425
426
            'IDN, first domain name label starts with hyphen' => ['-пример.испытание', $messageInvalidCharacter],
427
            'IDN, first domain name label ends with hyphen' => ['пример-.испытание', $messageInvalidCharacter],
428
            'IDN, last domain name label starts with hyphen' => ['пример.-испытание', $messageInvalidCharacter],
429
            'IDN, last domain name label ends with hyphen' => ['пример.испытание-', $messageInvalidCharacter],
430
431
            'IDN, HTTP, first domain name label starts with hyphen' => [
432
                'http://-пример.испытание/index.html',
433
                $messageInvalidCharacter,
434
            ],
435
            'IDN, HTTP, first domain name label ends with hyphen' => [
436
                'http://пример-.испытание/index.html',
437
                $messageInvalidCharacter,
438
            ],
439
            'IDN, HTTP, last domain name label starts with hyphen' => [
440
                'http://пример.-испытание/index.html',
441
                $messageInvalidCharacter,
442
            ],
443
            'IDN, HTTP, last domain name label ends with hyphen' => [
444
                'http://пример.испытание-/index.html',
445
                $messageInvalidCharacter,
446
            ],
447
448
            'last domain name label starts with number' => ['example.4om', $messageLabelStartEnd],
449
450
            'domain name label too long' => [str_repeat('a', 64), $messageLabelTooLong],
451
452
            'dot' => ['.', $messageLabelTooShort],
453
            'domain name starts with dot' => ['.example.com', $messageLabelTooShort],
454
            'domain name ends with two dots' => ['example.com..', $messageLabelTooShort],
455
            'domain name contains two dots in a row' => ['example..com', $messageLabelTooShort],
456
457
            'domain name contains underscore' => ['ex_ample.com', $messageInvalidCharacter],
458
            'domain name contains space' => ['ex ample.com', $messageInvalidCharacter],
459
            'domain name contains disallowed character' => ['a⒈com', $messageInvalidCharacter],
460
461
            'IDN, domain name too long' => [
462
                'ффффффффффффффффффффффффффффффффффффффффффффффффффффффффф.' .
463
                'ффффффффффффффффффффффффффффффффффффффффффффффффффффффффф.' .
464
                'ффффффффффффффффффффффффффффффффффффффффффффффффффффффффф.' .
465
                'ффффффффффффффффффффффффффффффффффффффффффффффффффффффффф.',
466
                $messageInvalidCharacter,
467
            ],
468
            'IDN, domain name label too long' => [
469
                'фффффффффффффффффффффффффффффффффффффффффффффффффффффффффs',
470
                $messageInvalidCharacter,
471
            ],
472
        ];
473
    }
474
475
    /**
476
     * @param string $value
477
     * @param string $expectedErrorMessage
478
     * @covers       kdn\yii2\validators\DomainValidator::getDefaultErrorMessages
479
     * @covers       kdn\yii2\validators\DomainValidator::getErrorMessage
480
     * @covers       kdn\yii2\validators\DomainValidator::validateValue
481
     * @dataProvider invalidDomainProvider
482
     * @small
483
     */
484
    public function testInvalidDomain($value, $expectedErrorMessage)
485
    {
486
        $this->assertFalse($this->validator->validate($value, $errorMessage));
487
        $this->assertEquals($expectedErrorMessage, $errorMessage);
488
    }
489
490
    public static function invalidDomainWithEnabledIdnProvider()
491
    {
492
        $messageLabelStartEnd = 'Each label of the input value should start and end with letter or number.' .
493
            ' The rightmost label of the input value should start with letter.';
494
        $messageLabelTooLong = 'Label of the input value is too long.';
495
        $messageTooLong = 'the input value is too long.';
496
        return array_merge(
497
            static::invalidDomainProvider('testInvalidDomainWithEnabledIdn'),
498
            [
499
                /* todo fatal error
500
                'IDN, domain name too long, fatal' => [
501
                    'ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.ф.s.s.s.s',
502
                    $messageTooLong,
503
                ],
504
                //*/
505
                /* todo fatal error
506
                'IDN, domain name too long, fatal' => [
507
                    'ффффффффффффффффффффффффффффффффффффффффффффффффффффффффф.' .
508
                    'ффффффффффффффффффффффффффффффффффффффффффффффффффффффффф.' .
509
                    'ффффффффффффффффффффффффффффффффффффффффффффффффффффффффф.' .
510
                    'фффффффффффффффффффффффффффффффффффффффффффффффффффффффф.',
511
                    $messageTooLong,
512
                ],
513
                //*/
514
515
                'domain name too long' => [str_repeat('a.', 126) . 'aa', $messageTooLong],
516
517
                'IDN, first domain name label starts with hyphen' => ['-пример.испытание', $messageLabelStartEnd],
518
                'IDN, first domain name label ends with hyphen' => ['пример-.испытание', $messageLabelStartEnd],
519
                'IDN, last domain name label starts with hyphen' => ['пример.-испытание', $messageLabelStartEnd],
520
                'IDN, last domain name label ends with hyphen' => ['пример.испытание-', $messageLabelStartEnd],
521
522
                'IDN, HTTP, first domain name label starts with hyphen' => [
523
                    'http://-пример.испытание/index.html',
524
                    $messageLabelStartEnd,
525
                ],
526
                'IDN, HTTP, first domain name label ends with hyphen' => [
527
                    'http://пример-.испытание/index.html',
528
                    $messageLabelStartEnd,
529
                ],
530
                'IDN, HTTP, last domain name label starts with hyphen' => [
531
                    'http://пример.-испытание/index.html',
532
                    $messageLabelStartEnd,
533
                ],
534
                'IDN, HTTP, last domain name label ends with hyphen' => [
535
                    'http://пример.испытание-/index.html',
536
                    $messageLabelStartEnd,
537
                ],
538
539
                'domain name label too long' => [str_repeat('a', 64), $messageLabelTooLong],
540
541
                'IDN, domain name too long' => [
542
                    'ффффффффффффффффффффффффффффффффффффффффффффффффффффффффф.' .
543
                    'ффффффффффффффффффффффффффффффффффффффффффффффффффффффффф.' .
544
                    'ффффффффффффффффффффффффффффффффффффффффффффффффффффффффф.' .
545
                    'ффффффффффффффффффффффффффффффффффффффффффффффффффффффффф.',
546
                    $messageTooLong,
547
                ],
548
                'IDN, domain name label too long' => [
549
                    'фффффффффффффффффффффффффффффффффффффффффффффффффффффффффs',
550
                    $messageLabelTooLong,
551
                ],
552
            ]
553
        );
554
    }
555
556
    /**
557
     * @param string $value
558
     * @param string $expectedErrorMessage
559
     * @covers       kdn\yii2\validators\DomainValidator::getDefaultErrorMessages
560
     * @covers       kdn\yii2\validators\DomainValidator::getErrorMessage
561
     * @covers       kdn\yii2\validators\DomainValidator::validateValue
562
     * @dataProvider invalidDomainWithEnabledIdnProvider
563
     * @small
564
     */
565
    public function testInvalidDomainWithEnabledIdn($value, $expectedErrorMessage)
566
    {
567
        if (!function_exists('idn_to_ascii')) {
568
            $this->markTestSkipped('intl extension required.');
569
            return;
570
        }
571
572
        $this->validator->enableIDN = true;
573
        $this->testInvalidDomain($value, $expectedErrorMessage);
574
    }
575
576
    /**
577
     * @covers kdn\yii2\validators\DomainValidator::getErrorMessage
578
     * @covers kdn\yii2\validators\DomainValidator::validateValue
579
     * @small
580
     */
581
    public function testCustomErrorMessage()
582
    {
583
        $validator = $this->validator;
584
        $messageNotString = 'test';
585
        $validator->messageNotString = $messageNotString;
586
        $this->assertFalse($validator->validate(null, $errorMessage));
587
        $this->assertEquals($messageNotString, $errorMessage);
588
    }
589
590
    /**
591
     * @covers kdn\yii2\validators\DomainValidator::validateValue
592
     * @uses   kdn\yii2\validators\DomainValidator::getDefaultErrorMessages
593
     * @uses   kdn\yii2\validators\DomainValidator::getErrorMessage
594
     * @small
595
     */
596
    public function testValidateAttribute()
597
    {
598
        $model = new ModelMock();
599
        $validator = $this->validator;
600
        $model->domain = 'google.com';
601
        $validator->validateAttribute($model, 'domain');
602
        $this->assertFalse($model->hasErrors('domain'));
603
        $model->domain = '';
604
        $validator->validateAttribute($model, 'domain');
605
        $this->assertTrue($model->hasErrors('domain'));
606
    }
607
608
    /**
609
     * Important: this test should be executed last, because it can remove function "idn_to_ascii".
610
     * @covers kdn\yii2\validators\DomainValidator::init
611
     * @expectedException \yii\base\InvalidConfigException
612
     * @expectedExceptionMessage In order to use IDN validation intl extension must be installed and enabled.
613
     * @small
614
     */
615
    public function testInitIdnIntlException()
616
    {
617
        if (!function_exists('runkit_function_remove') || !ini_get('runkit.internal_override')) {
618
            $this->markTestSkipped('runkit extension required. runkit.internal_override should be set to "On".');
619
            return;
620
        }
621
622
        runkit_function_remove('idn_to_ascii');
623
        new DomainValidator(['enableIDN' => true]);
624
    }
625
626
    /**
627
     * Add column to array.
628
     * @param array $array
629
     * @param mixed $value
630
     * @return array
631
     */
632
    protected static function arrayAddColumn($array, $value)
633
    {
634
        return array_map(
635
            function ($data) use ($value) {
636
                $data[] = $value;
637
                return $data;
638
            },
639
            $array
640
        );
641
    }
642
}
643