Passed
Push — master ( aa31ac...8f13cb )
by AJ
02:24
created

ValidationTest::testRequiredWhenEmpty()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 12
nc 2
nop 0
dl 0
loc 18
rs 9.8666
c 0
b 0
f 0
1
<?php
2
/**
3
 *       __  ___      ____  _     ___                           _                    __
4
 *      /  |/  /_  __/ / /_(_)___/ (_)___ ___  ___  ____  _____(_)___  ____   ____ _/ /
5
 *     / /|_/ / / / / / __/ / __  / / __ `__ \/ _ \/ __ \/ ___/ / __ \/ __ \ / __ `/ /
6
 *    / /  / / /_/ / / /_/ / /_/ / / / / / / /  __/ / / (__  ) / /_/ / / / // /_/ / /
7
 *   /_/  /_/\__,_/_/\__/_/\__,_/_/_/ /_/ /_/\___/_/ /_/____/_/\____/_/ /_(_)__,_/_/
8
 *
9
 *  Array Validation Library
10
 *  Copyright (c) Multidimension.al (http://multidimension.al)
11
 *  Github : https://github.com/multidimension-al/array-validation
12
 *
13
 *  Licensed under The MIT License
14
 *  For full copyright and license information, please see the LICENSE file
15
 *  Redistributions of files must retain the above copyright notice.
16
 *
17
 *  @copyright  Copyright © 2017-2019 Multidimension.al (http://multidimension.al)
18
 *  @link       https://github.com/multidimension-al/array-validation Github
19
 *  @license    http://www.opensource.org/licenses/mit-license.php MIT License
20
 */
21
22
namespace Multidimensional\ArrayValidation\Test;
23
24
use Exception;
25
use Multidimensional\ArrayValidation\Validation;
26
use PHPUnit\Framework\TestCase;
27
28
class ValidationTest extends TestCase
29
{
30
31
    public function testEmptyValidation()
32
    {
33
        $this->assertTrue(Validation::validate([], []));
34
    }
35
36
    public function testFailedValidation()
37
    {
38
        try {
39
            $this->assertFalse(Validation::validate('', ''));
0 ignored issues
show
Bug introduced by
'' of type string is incompatible with the type array expected by parameter $array of Multidimensional\ArrayVa...\Validation::validate(). ( Ignorable by Annotation )

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

39
            $this->assertFalse(Validation::validate(/** @scrutinizer ignore-type */ '', ''));
Loading history...
Bug introduced by
'' of type string is incompatible with the type array expected by parameter $rules of Multidimensional\ArrayVa...\Validation::validate(). ( Ignorable by Annotation )

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

39
            $this->assertFalse(Validation::validate('', /** @scrutinizer ignore-type */ ''));
Loading history...
40
        } catch (Exception $e) {
41
            $this->assertEquals('Validation array not found.', $e->getMessage());
42
        }
43
44
        try {
45
            $this->assertFalse(Validation::validate([], ''));
46
        } catch (Exception $e) {
47
            $this->assertEquals('Validation rules array not found.', $e->getMessage());
48
        }
49
50
        try {
51
            $this->assertFalse(Validation::validate('', []));
52
        } catch (Exception $e) {
53
            $this->assertEquals('Validation array not found.', $e->getMessage());
54
        }
55
    }
56
57
    public function testRequiredTrue()
58
    {
59
        $rules = [
60
            'a' => ['type' => 'string', 'required' => true],
61
            'b' => ['type' => 'string']
62
        ];
63
        $array = [
64
            'a' => 'Hello',
65
            'b' => 'World'
66
        ];
67
        $this->assertTrue(Validation::validate($array, $rules));
68
69
        $array = [
70
            'b' => 'Goodbye'
71
        ];
72
73
        try {
74
            $this->assertFalse(Validation::validate($array, $rules));
75
        } catch (Exception $e) {
76
            $this->assertEquals('Required value not found for key: a.', $e->getMessage());
77
        }
78
79
        $rules['a']['required'] = 'true';
80
81
        try {
82
            $this->assertFalse(Validation::validate($array, $rules));
83
        } catch (Exception $e) {
84
            $this->assertEquals('Required value not found for key: a.', $e->getMessage());
85
        }
86
    }
87
88
    public function testValidateValues()
89
    {
90
        $rules = [
91
            'a' => ['type' => 'string', 'values' => ['a', 'b', 'c']]
92
        ];
93
        $array = [
94
            'a' => 'b'
95
        ];
96
        $this->assertTrue(Validation::validate($array, $rules));
97
    }
98
99
    public function testValidateValuesFailure()
100
    {
101
        $rules = [
102
            'a' => ['type' => 'string', 'values' => ['cat', 'dog']]
103
        ];
104
        $array = [
105
            'a' => 'kat'
106
        ];
107
        try {
108
            $this->assertFalse(Validation::validate($array, $rules));
109
        } catch (Exception $e) {
110
            $this->assertEquals('Invalid value "kat" for key: a. Did you mean "cat"?', $e->getMessage());
111
        }
112
    }
113
114
    public function testValidateValuesOnlyOption()
115
    {
116
        $rules = [
117
            'a' => ['type' => 'string', 'values' => 'b']
118
        ];
119
        $array = [
120
            'a' => 'b'
121
        ];
122
        $this->assertTrue(Validation::validate($array, $rules));
123
    }
124
125
    public function testInteger()
126
    {
127
        $rules = [
128
            'a' => ['type' => 'integer'],
129
            'b' => ['type' => 'integer']
130
        ];
131
        $array = [
132
            'a' => 1,
133
            'b' => 2
134
        ];
135
        $this->assertTrue(Validation::validate($array, $rules));
136
        $array = [
137
            'a' => 1,
138
            'b' => 'one'
139
        ];
140
141
        try {
142
            $this->assertFalse(Validation::validate($array, $rules));
143
        } catch (Exception $e) {
144
            $this->assertEquals('Invalid integer "one" for key: b.', $e->getMessage());
145
        }
146
    }
147
148
    public function testDecimal()
149
    {
150
        $rules = [
151
            'a' => ['type' => 'decimal'],
152
            'b' => ['type' => 'decimal']
153
        ];
154
        $array = [
155
            'a' => 1.0,
156
            'b' => 2.1
157
        ];
158
        $this->assertTrue(Validation::validate($array, $rules));
159
        $array = [
160
            'a' => 1.0,
161
            'b' => 'one point 2'
162
        ];
163
164
        try {
165
            $this->assertFalse(Validation::validate($array, $rules));
166
        } catch (Exception $e) {
167
            $this->assertEquals('Invalid decimal "one point 2" for key: b.', $e->getMessage());
168
        }
169
    }
170
171
    public function testRequiredDecimal()
172
    {
173
        $rules = [
174
            'a' => ['type' => 'decimal', 'required' => true]
175
        ];
176
        $array = [
177
            'a' => 0
178
        ];
179
        $this->assertTrue(Validation::validate($array, $rules));
180
    }
181
182
    public function testString()
183
    {
184
        $rules = [
185
            'a' => ['type' => 'string'],
186
            'b' => ['type' => 'string']
187
        ];
188
        $array = [
189
            'a' => 'Yes this is obviously',
190
            'b' => "a string"
191
        ];
192
        $this->assertTrue(Validation::validate($array, $rules));
193
        $array = [
194
            'a' => 1,
195
            'b' => 'one point 2'
196
        ];
197
198
        try {
199
            $this->assertFalse(Validation::validate($array, $rules));
200
        } catch (Exception $e) {
201
            $this->assertEquals('Invalid string "1" for key: a.', $e->getMessage());
202
        }
203
    }
204
205
    public function testBoolean()
206
    {
207
        $rules = [
208
            'a' => ['type' => 'boolean'],
209
            'b' => ['type' => 'boolean']
210
        ];
211
        $array = [
212
            'a' => true,
213
            'b' => false
214
        ];
215
        $this->assertTrue(Validation::validate($array, $rules));
216
217
        $array = [
218
            'a' => 'true',
219
            'b' => 'false'
220
        ];
221
        try {
222
            $this->assertFalse(Validation::validate($array, $rules));
223
        } catch (Exception $e) {
224
            $this->assertEquals('Invalid boolean "true" for key: a.', $e->getMessage());
225
        }
226
227
        $array = [
228
            'a' => 1,
229
            'b' => 'false'
230
        ];
231
232
        try {
233
            $this->assertFalse(Validation::validate($array, $rules));
234
        } catch (Exception $e) {
235
            $this->assertEquals('Invalid boolean "1" for key: a.', $e->getMessage());
236
        }
237
    }
238
239
    public function testValidatePattern()
240
    {
241
        $rules = [
242
            'a' => ['type' => 'string', 'pattern' => '[A-Z]{2}'],
243
            'b' => ['type' => 'datetime', 'pattern' => 'ISO 8601']
244
        ];
245
        $array = [
246
            'a' => 'CA',
247
            'b' => '2014-01-22T14:30:51-06:00'
248
        ];
249
        $this->assertTrue(Validation::validate($array, $rules));
250
251
        $array = [
252
            'a' => 'CAT',
253
        ];
254
255
        try {
256
            $this->assertFalse(Validation::validate($array, $rules));
257
        } catch (Exception $e) {
258
            $this->assertEquals('Invalid value "CAT" does not match pattern "[A-Z]{2}" for key: a.', $e->getMessage());
259
        }
260
261
        $array = [
262
            'b' => '2014-01-22',
263
        ];
264
265
        try {
266
            $this->assertFalse(Validation::validate($array, $rules));
267
        } catch (Exception $e) {
268
            $this->assertEquals('Invalid value "2014-01-22" does not match ISO 8601 pattern for key: b.', $e->getMessage());
269
        }
270
    }
271
272
    public function testFieldNotInRules()
273
    {
274
        $rules = [
275
            'a' => ['type' => 'string']
276
        ];
277
        $array = [
278
            'a' => 'string',
279
            'b' => 'unexpected'
280
        ];
281
282
        try {
283
            $this->assertFalse(Validation::validate($array, $rules));
284
        } catch (Exception $e) {
285
            $this->assertEquals('Unexpected key "b" found in array.', $e->getMessage());
286
        }
287
    }
288
289
    public function testMultidimensionalValidation()
290
    {
291
        $rules = [
292
            'a' => ['type' => 'array',
293
                'fields' => [
294
                    'a' => ['type' => 'string'],
295
                    'b' => ['type' => 'string']
296
                ]
297
            ],
298
            'b' => ['type' => 'string']
299
        ];
300
        $array = [
301
            'a' => [
302
                'a' => 'string',
303
                'b' => 'test'
304
            ],
305
            'b' => 'b'
306
        ];
307
        $this->assertTrue(Validation::validate($array, $rules));
308
309
        $array = [
310
            'b' => [
311
                'a' => 'string',
312
                'b' => 'test'
313
            ]
314
        ];
315
316
        try {
317
            $this->assertFalse(Validation::validate($array, $rules));
318
        } catch (Exception $e) {
319
            $this->assertEquals("Unexpected array found for key: b.", $e->getMessage());
320
        }
321
    }
322
323
    public function testGroupValidation()
324
    {
325
        $rules2 = [
326
            'b' => ['type' => 'string']
327
        ];
328
        $rules = [
329
            'a' => [
330
                'type' => 'group',
331
                'fields' => $rules2
332
            ]
333
        ];
334
        $array = [
335
            'a' => [['b' => 'Hello']]
336
        ];
337
        $this->assertTrue(Validation::validate($array, $rules));
338
        $array = [
339
            'a' => [
340
                ['b' => 'Hello'],
341
                ['b' => 'World'],
342
            ]
343
        ];
344
        $this->assertTrue(Validation::validate($array, $rules));
345
    }
346
347
    public function testRequiredComplex()
348
    {
349
        $rules = [
350
            'a' => ['type' => 'string', 'required' => true],
351
            'b' => ['type' => 'string',
352
                'required' => [
353
                    'a' => 'banana'
354
                ]
355
            ],
356
            'c' => ['type' => 'string',
357
                'required' => [
358
                    [
359
                        'a' => 'banana',
360
                        'b' => 'orange'
361
                    ],
362
                    [
363
                        'a' => 'banana',
364
                        'b' => 'carrot'
365
                    ],
366
                    [
367
                        'a' => 'pickle'
368
                    ],
369
                    [
370
                        'b' => 'banana'
371
                    ]
372
                ]
373
            ],
374
        ];
375
        $array = [
376
            'a' => 'apple'
377
        ];
378
        $this->assertTrue(Validation::validate($array, $rules));
379
380
        $array = [
381
            'a' => 'banana',
382
            'b' => 'orange',
383
            'c' => 'other'
384
        ];
385
        $this->assertTrue(Validation::validate($array, $rules));
386
387
        $array = [
388
            'a' => 'banana',
389
            'c' => 'orange'
390
        ];
391
392
        try {
393
            $this->assertFalse(Validation::validate($array, $rules));
394
        } catch (Exception $e) {
395
            $this->assertEquals('Required value not found for key: b.', $e->getMessage());
396
        }
397
398
        $array = [
399
            'a' => 'banana',
400
            'b' => '',
401
            'c' => 'orange'
402
        ];
403
404
        try {
405
            $this->assertFalse(Validation::validate($array, $rules));
406
        } catch (Exception $e) {
407
            $this->assertEquals('Required value not found for key: b.', $e->getMessage());
408
        }
409
410
        $array = [
411
            'a' => 'banana',
412
            'b' => 'carrot'
413
        ];
414
415
        try {
416
            $this->assertFalse(Validation::validate($array, $rules));
417
        } catch (Exception $e) {
418
            $this->assertEquals('Required value not found for key: c.', $e->getMessage());
419
        }
420
421
422
        $array = [
423
            'a' => 'banana',
424
            'b' => 'carrot',
425
            'c' => ''
426
        ];
427
428
        try {
429
            $this->assertFalse(Validation::validate($array, $rules));
430
        } catch (Exception $e) {
431
            $this->assertEquals('Required value not found for key: c.', $e->getMessage());
432
        }
433
434
        $array = [
435
            'b' => 'banana'
436
        ];
437
438
        try {
439
            $this->assertFalse(Validation::validate($array, $rules));
440
        } catch (Exception $e) {
441
            $this->assertEquals('Required value not found for key: a.', $e->getMessage());
442
        }
443
444
        $array = [
445
            'a' => '',
446
            'b' => 'banana',
447
            'c' => ''
448
        ];
449
450
        try {
451
            $this->assertFalse(Validation::validate($array, $rules));
452
        } catch (Exception $e) {
453
            $this->assertEquals('Required value not found for key: a.', $e->getMessage());
454
        }
455
456
457
        $array = [
458
            'a' => 'carrot',
459
            'b' => 'banana'
460
        ];
461
462
        try {
463
            $this->assertFalse(Validation::validate($array, $rules));
464
        } catch (Exception $e) {
465
            $this->assertEquals('Required value not found for key: c.', $e->getMessage());
466
        }
467
    }
468
469
    public function testRequiredNull()
470
    {
471
        $rules = [
472
            'a' => ['type' => 'string',
473
                'required' => [
474
                    'b' => 'null'
475
                ]
476
            ],
477
            'b' => ['type' => 'string'],
478
            'c' => ['type' => 'string'],
479
        ];
480
        $array = [
481
            'b' => 'not a null value',
482
            'c' => 'no one cares about c'
483
        ];
484
        $this->assertTrue(Validation::validate($array, $rules));
485
486
        $array = [
487
            'c' => 'c is lonely'
488
        ];
489
490
        try {
491
            $this->assertFalse(Validation::validate($array, $rules));
492
        } catch (Exception $e) {
493
            $this->assertEquals('Required value not found for key: a.', $e->getMessage());
494
        }
495
496
        $array = [];
497
498
        try {
499
            $this->assertFalse(Validation::validate($array, $rules));
500
        } catch (Exception $e) {
501
            $this->assertEquals('Required value not found for key: a.', $e->getMessage());
502
        }
503
504
        $rules['a']['required']['b'] = null;
505
506
        try {
507
            $this->assertFalse(Validation::validate($array, $rules));
508
        } catch (Exception $e) {
509
            $this->assertEquals('Required value not found for key: a.', $e->getMessage());
510
        }
511
    }
512
513
    public function testNullValue()
514
    {
515
        $rules = [
516
            'a' => ['type' => 'string']
517
        ];
518
        $array = [
519
            'a' => null
520
        ];
521
        $this->assertTrue(Validation::validate($array, $rules));
522
523
        $array['a'] = 'null';
524
        $this->assertTrue(Validation::validate($array, $rules));
525
    }
526
527
    public function testInvalidRequiredValue()
528
    {
529
        $rules = [
530
            'a' => [
531
                'type' => 'string',
532
                'required' => 'banana'
533
            ]
534
        ];
535
        $array = [
536
            'a' => null
537
        ];
538
539
        try {
540
            $this->assertFalse(Validation::validate($array, $rules));
541
        } catch (Exception $e) {
542
            $this->assertEquals('Required value not found for key: a.', $e->getMessage());
543
        }
544
    }
545
546
    public function testRequiredWhenNull()
547
    {
548
        $rules = [
549
            'a' =>
550
                ['type' => 'string',
551
                    'required' => [
552
                        'b' => null
553
                    ]
554
                ],
555
            'b' => ['type' => 'string'],
556
            'c' => ['type' => 'string']
557
        ];
558
        $array = ['c' => 'Hi'];
559
560
        try {
561
            $this->assertFalse(Validation::validate($array, $rules));
562
        } catch (Exception $e) {
563
            $this->assertEquals('Required value not found for key: a.', $e->getMessage());
564
        }
565
    }
566
567
    public function testRequiredWhenEmpty()
568
    {
569
        $rules = [
570
            'a' =>
571
                ['type' => 'string',
572
                    'required' => [
573
                        'b' => ''
574
                    ]
575
                ],
576
            'b' => ['type' => 'string'],
577
            'c' => ['type' => 'string']
578
        ];
579
        $array = ['c' => 'Hi'];
580
581
        try {
582
            $this->assertFalse(Validation::validate($array, $rules));
583
        } catch (Exception $e) {
584
            $this->assertEquals('Required value not found for key: a.', $e->getMessage());
585
        }
586
    }
587
588
    public function testUnexpectedArray()
589
    {
590
        $rules = [
591
            'a' => [
592
                'type' => 'string'
593
            ]
594
        ];
595
        $array = [
596
            'a' => [
597
                'b' => 'c'
598
            ]
599
        ];
600
        try {
601
            $this->assertFalse(Validation::validate($array, $rules));
602
        } catch (Exception $e) {
603
            $this->assertEquals('Unexpected array found for key: a.', $e->getMessage());
604
        }
605
    }
606
607
    public function testMultiDimensionalArray()
608
    {
609
        $rules = [
610
            'RateV4Response' => [
611
                'type' => 'array',
612
                'fields' => [
613
                    'Package' => [
614
                        'type' => 'group',
615
                        'fields' => [
616
                            '@ID' => [
617
                                'type' => 'string',
618
                                'required' => true
619
                            ],
620
                            'ZipOrigination' => [
621
                                'type' => 'string',
622
                                'required' => true,
623
                                'pattern' => '\d{5}'
624
                            ],
625
                            'ZipDestination' => [
626
                                'type' => 'string',
627
                                'required' => true,
628
                                'pattern' => '\d{5}'
629
                            ],
630
                            'Pounds' => [
631
                                'type' => 'decimal',
632
                                'required' => true,
633
                            ],
634
                            'Ounces' => [
635
                                'type' => 'decimal',
636
                                'required' => true,
637
                            ],
638
                            'FirstClassMailType' => [
639
                                'type' => 'string'
640
                            ],
641
                            'Container' => [
642
                                'type' => 'string',
643
                            ],
644
                            'Size' => [
645
                                'type' => 'string',
646
                                'required' => true,
647
                                'values' => [
648
                                    'REGULAR',
649
                                    'LARGE'
650
                                ]
651
                            ],
652
                            'Width' => [
653
                                'type' => 'decimal'
654
                            ],
655
                            'Length' => [
656
                                'type' => 'decimal'
657
                            ],
658
                            'Height' => [
659
                                'type' => 'decimal'
660
                            ],
661
                            'Girth' => [
662
                                'type' => 'decimal'
663
                            ],
664
                            'Machinable' => [
665
                                'type' => 'boolean'
666
                            ],
667
                            'Zone' => [
668
                                'type' => 'string'
669
                            ],
670
                            'Postage' => [
671
                                'type' => 'group',
672
                                'required' => true,
673
                                'fields' => [
674
                                    '@CLASSID' => [
675
                                        'type' => 'integer'
676
                                    ],
677
                                    'MailService' => [
678
                                        'type' => 'string'
679
                                    ],
680
                                    'Rate' => [
681
                                        'type' => 'decimal'
682
                                    ]
683
                                ]
684
                            ]
685
                        ]
686
                    ]
687
                ]
688
            ]
689
        ];
690
        $array = [
691
            'RateV4Response' => [
692
                'Package' => [
693
                    '@ID' => '123',
694
                    'ZipOrigination' => '20500',
695
                    'ZipDestination' => '90210',
696
                    'Pounds' => 0.0,
697
                    'Ounces' => 32.0,
698
                    'Size' => 'REGULAR',
699
                    'Machinable' => true,
700
                    'Zone' => '8',
701
                    'Postage' => [
702
                        0 => [
703
                            '@CLASSID' => 1,
704
                            'MailService' => 'Priority Mail 2-Day<sup>™</sup>',
705
                            'Rate' => 12.75
706
                        ],
707
                        1 => [
708
                            '@CLASSID' => 22,
709
                            'MailService' => 'Priority Mail 2-Day<sup>™</sup> Large Flat Rate Box',
710
                            'Rate' => 18.85
711
                        ],
712
                        2 => [
713
                            '@CLASSID' => 17,
714
                            'MailService' => 'Priority Mail 2-Day<sup>™</sup> Medium Flat Rate Box',
715
                            'Rate' => 13.60
716
                        ],
717
                        3 => [
718
                            '@CLASSID' => 28,
719
                            'MailService' => 'Priority Mail 2-Day<sup>™</sup> Small Flat Rate Box',
720
                            'Rate' => 7.15
721
                        ]
722
                    ]
723
                ]
724
            ]
725
        ];
726
        $this->assertTrue(Validation::validate($array, $rules));
727
    }
728
729
    public function testMultiMultiMultidimensionalArray()
730
    {
731
        $rules = [
732
            'RateV4Response' => [
733
                'type' => 'array',
734
                'fields' => [
735
                    'Package' => [
736
                        'type' => 'group',
737
                        'fields' => [
738
                            '@ID' => [
739
                                'type' => 'string',
740
                                'required' => true
741
                            ],
742
                            'ZipOrigination' => [
743
                                'type' => 'string',
744
                                'required' => true,
745
                                'pattern' => '\d{5}'
746
                            ],
747
                            'ZipDestination' => [
748
                                'type' => 'string',
749
                                'required' => true,
750
                                'pattern' => '\d{5}'
751
                            ],
752
                            'Pounds' => [
753
                                'type' => 'decimal',
754
                                'required' => true,
755
                            ],
756
                            'Ounces' => [
757
                                'type' => 'decimal',
758
                                'required' => true,
759
                            ],
760
                            'FirstClassMailType' => [
761
                                'type' => 'string'
762
                            ],
763
                            'Container' => [
764
                                'type' => 'string',
765
                            ],
766
                            'Size' => [
767
                                'type' => 'string',
768
                                'required' => true,
769
                                'values' => [
770
                                    'REGULAR',
771
                                    'LARGE'
772
                                ]
773
                            ],
774
                            'Width' => [
775
                                'type' => 'decimal'
776
                            ],
777
                            'Length' => [
778
                                'type' => 'decimal'
779
                            ],
780
                            'Height' => [
781
                                'type' => 'decimal'
782
                            ],
783
                            'Girth' => [
784
                                'type' => 'decimal'
785
                            ],
786
                            'Machinable' => [
787
                                'type' => 'boolean'
788
                            ],
789
                            'Zone' => [
790
                                'type' => 'string'
791
                            ],
792
                            'Postage' => [
793
                                'type' => 'group',
794
                                'required' => true,
795
                                'fields' => [
796
                                    '@CLASSID' => [
797
                                        'type' => 'integer'
798
                                    ],
799
                                    'MailService' => [
800
                                        'type' => 'string'
801
                                    ],
802
                                    'Rate' => [
803
                                        'type' => 'decimal'
804
                                    ]
805
                                ]
806
                            ]
807
                        ]
808
                    ]
809
                ]
810
            ]
811
        ];
812
        $array = [
813
            'RateV4Response' => [
814
                'Package' => [
815
                    0 => [
816
                        '@ID' => '123',
817
                        'ZipOrigination' => '20500',
818
                        'ZipDestination' => '90210',
819
                        'Pounds' => 0.0,
820
                        'Ounces' => 32.0,
821
                        'Size' => 'REGULAR',
822
                        'Machinable' => true,
823
                        'Zone' => '8',
824
                        'Postage' => [
825
                            0 => [
826
                                '@CLASSID' => 1,
827
                                'MailService' => 'Priority Mail 2-Day<sup>™</sup>',
828
                                'Rate' => 12.75
829
                            ],
830
                            1 => [
831
                                '@CLASSID' => 22,
832
                                'MailService' => 'Priority Mail 2-Day<sup>™</sup> Large Flat Rate Box',
833
                                'Rate' => 18.85
834
                            ],
835
                            2 => [
836
                                '@CLASSID' => 17,
837
                                'MailService' => 'Priority Mail 2-Day<sup>™</sup> Medium Flat Rate Box',
838
                                'Rate' => 13.60
839
                            ],
840
                            3 => [
841
                                '@CLASSID' => 28,
842
                                'MailService' => 'Priority Mail 2-Day<sup>™</sup> Small Flat Rate Box',
843
                                'Rate' => 7.15
844
                            ]
845
                        ]
846
                    ]
847
                ]
848
            ]
849
        ];
850
        $this->assertTrue(Validation::validate($array, $rules));
851
    }
852
}
853