Passed
Push — master ( c3b892...f5f636 )
by William
10:54 queued 11s
created

InsertEditTest   C

Complexity

Total Complexity 51

Size/Duplication

Total Lines 3181
Duplicated Lines 0 %

Importance

Changes 9
Bugs 0 Features 0
Metric Value
eloc 1843
dl 0
loc 3181
rs 6.72
c 9
b 0
f 0
wmc 51

51 Methods

Rating   Name   Duplication   Size   Complexity  
A testGetWhereClauseArray() 0 33 1
A testAnalyzeWhereClause() 0 62 1
A tearDown() 0 7 1
A testGetFormParametersForInsertForm() 0 30 1
A testShowEmptyResultMessageOrSetUniqueCondition() 0 63 1
A setUp() 0 35 1
A testSetSessionForEditNext() 0 39 1
B testGetEnumAndTimestampColumns() 0 111 1
A testGetContinueInsertionForm() 0 50 1
A testTransformEditedValues() 0 31 1
A testGetLinkForRelationalDisplayField() 0 32 1
A testGetParamsForUpdateOrInsert() 0 36 1
A testBuildSqlQuery() 0 21 1
A testGetColumnTitle() 0 40 1
A testGetSpecialCharsAndBackupFieldForInsertingMode() 0 53 1
B testGetHtmlForInsertEditRowBasedOnColumnPrivileges() 0 135 1
B testGetHtmlForInsertEditFormColumn() 0 181 1
A testAnalyzeTableColumnsArray() 0 72 1
A testShowTypeOrFunction() 0 67 1
A testLoadFirstRow() 0 33 1
B testGetCurrentValueForDifferentTypes() 0 233 1
A testGetTableColumns() 0 26 1
A testGetCommentsMap() 0 43 1
A testGetUrlParameters() 0 14 1
A testGetColumnSize() 0 38 1
A dataProviderConfigValueInsertRows() 0 31 1
A testGetNullifyCodeForNullColumn() 0 67 1
A testIsWhereClauseNumeric() 0 9 1
A testIsInsertRow() 0 41 1
B testGetSpecialCharsAndBackupFieldForExistingRow() 0 195 1
A testGetDisplayValueForForeignTableColumn() 0 37 1
A testExecuteSqlQuery() 0 16 1
A testIsColumn() 0 58 1
A testGetWarningMessages() 0 39 1
A testGetQueryValuesForInsertAndUpdateInMultipleEdit() 0 106 1
A testVerifyWhetherValueCanBeTruncatedAndAppendExtraData() 0 63 1
B testGetHTMLinput() 0 80 1
A testGetTextarea() 0 36 1
A testGetColumnSetValueAndSelectSize() 0 58 1
A testGetColumnEnumValues() 0 31 1
B testGetValueColumnForOtherDatatypes() 0 142 1
A testGetHtmlForIgnoreOption() 0 14 1
A testGetGotoInclude() 0 32 1
A testExecuteSqlQueryWithTryQuery() 0 16 1
A testGetHtmlForInsertEditRow() 0 70 1
A testDetermineInsertOrEdit() 0 68 1
A testGetCurrentValueAsAnArrayForMultipleEdit() 0 85 1
A testUrlParamsInEditMode() 0 17 1
A testGetHeadAndFootOfInsertRowTable() 0 27 1
A testGetErrorUrl() 0 12 1
A testGetMaxUploadSize() 0 42 1

How to fix   Complexity   

Complex Class

Complex classes like InsertEditTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use InsertEditTest, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
namespace PhpMyAdmin\Tests;
6
7
use PhpMyAdmin\Core;
8
use PhpMyAdmin\DatabaseInterface;
9
use PhpMyAdmin\FieldMetadata;
10
use PhpMyAdmin\Header;
11
use PhpMyAdmin\InsertEdit;
12
use PhpMyAdmin\Response;
13
use PhpMyAdmin\Scripts;
14
use PhpMyAdmin\Table;
15
use PhpMyAdmin\Url;
16
use ReflectionProperty;
17
use stdClass;
18
19
use function hash;
20
use function md5;
21
use function sprintf;
22
23
use const MYSQLI_PRI_KEY_FLAG;
24
use const MYSQLI_TYPE_DECIMAL;
25
use const MYSQLI_TYPE_TIMESTAMP;
26
use const MYSQLI_TYPE_TINY;
27
28
/**
29
 * @group medium
30
 */
31
class InsertEditTest extends AbstractTestCase
32
{
33
    /** @var InsertEdit */
34
    private $insertEdit;
35
36
    /**
37
     * Setup for test cases
38
     */
39
    protected function setUp(): void
40
    {
41
        parent::setUp();
42
        parent::setLanguage();
43
        parent::setGlobalConfig();
44
        parent::loadDefaultConfig();
45
        parent::setTheme();
46
        $GLOBALS['server'] = 1;
47
        $GLOBALS['PMA_PHP_SELF'] = 'index.php';
48
        $GLOBALS['cfg']['ServerDefault'] = 1;
49
        $GLOBALS['text_dir'] = 'ltr';
50
        $GLOBALS['db'] = 'db';
51
        $GLOBALS['table'] = 'table';
52
        $GLOBALS['cfg']['LimitChars'] = 50;
53
        $GLOBALS['cfg']['LongtextDoubleTextarea'] = false;
54
        $GLOBALS['cfg']['ShowFieldTypesInDataEditView'] = true;
55
        $GLOBALS['cfg']['ShowFunctionFields'] = true;
56
        $GLOBALS['cfg']['ProtectBinary'] = 'blob';
57
        $GLOBALS['cfg']['MaxSizeForInputField'] = 10;
58
        $GLOBALS['cfg']['MinSizeForInputField'] = 2;
59
        $GLOBALS['cfg']['TextareaRows'] = 5;
60
        $GLOBALS['cfg']['TextareaCols'] = 4;
61
        $GLOBALS['cfg']['CharTextareaRows'] = 5;
62
        $GLOBALS['cfg']['CharTextareaCols'] = 6;
63
        $GLOBALS['cfg']['AllowThirdPartyFraming'] = false;
64
        $GLOBALS['cfg']['SendErrorReports'] = 'ask';
65
        $GLOBALS['cfg']['DefaultTabDatabase'] = 'structure';
66
        $GLOBALS['cfg']['ShowDatabasesNavigationAsTree'] = true;
67
        $GLOBALS['cfg']['DefaultTabTable'] = 'browse';
68
        $GLOBALS['cfg']['NavigationTreeDefaultTabTable'] = 'structure';
69
        $GLOBALS['cfg']['NavigationTreeDefaultTabTable2'] = '';
70
        $GLOBALS['cfg']['Confirm'] = true;
71
        $GLOBALS['cfg']['LoginCookieValidity'] = 1440;
72
        $GLOBALS['cfg']['enable_drag_drop_import'] = true;
73
        $this->insertEdit = new InsertEdit($GLOBALS['dbi']);
74
    }
75
76
    /**
77
     * Teardown all objects
78
     */
79
    protected function tearDown(): void
80
    {
81
        parent::tearDown();
82
        $response = new ReflectionProperty(Response::class, 'instance');
83
        $response->setAccessible(true);
84
        $response->setValue(null);
85
        $response->setAccessible(false);
86
    }
87
88
    /**
89
     * Test for getFormParametersForInsertForm
90
     */
91
    public function testGetFormParametersForInsertForm(): void
92
    {
93
        $where_clause = [
94
            'foo' => 'bar ',
95
            '1' => ' test',
96
        ];
97
        $_POST['clause_is_unique'] = false;
98
        $_POST['sql_query'] = 'SELECT a';
99
        $GLOBALS['goto'] = 'index.php';
100
101
        $result = $this->insertEdit->getFormParametersForInsertForm(
102
            'dbname',
103
            'tablename',
104
            [],
105
            $where_clause,
106
            'localhost'
107
        );
108
109
        $this->assertEquals(
110
            [
111
                'db'        => 'dbname',
112
                'table'     => 'tablename',
113
                'goto'      => 'index.php',
114
                'err_url'   => 'localhost',
115
                'sql_query' => 'SELECT a',
116
                'where_clause[foo]' => 'bar',
117
                'where_clause[1]' => 'test',
118
                'clause_is_unique' => false,
119
            ],
120
            $result
121
        );
122
    }
123
124
    /**
125
     * Test for getWhereClauseArray
126
     */
127
    public function testGetWhereClauseArray(): void
128
    {
129
        $this->assertEquals(
130
            [],
131
            $this->callFunction(
132
                $this->insertEdit,
133
                InsertEdit::class,
134
                'getWhereClauseArray',
135
                [null]
136
            )
137
        );
138
139
        $this->assertEquals(
140
            [
141
                1,
142
                2,
143
                3,
144
            ],
145
            $this->callFunction(
146
                $this->insertEdit,
147
                InsertEdit::class,
148
                'getWhereClauseArray',
149
                [[1, 2, 3]]
150
            )
151
        );
152
153
        $this->assertEquals(
154
            ['clause'],
155
            $this->callFunction(
156
                $this->insertEdit,
157
                InsertEdit::class,
158
                'getWhereClauseArray',
159
                ['clause']
160
            )
161
        );
162
    }
163
164
    /**
165
     * Test for analyzeWhereClauses
166
     */
167
    public function testAnalyzeWhereClause(): void
168
    {
169
        $clauses = [
170
            'a=1',
171
            'b="fo\o"',
172
        ];
173
174
        $dbi = $this->getMockBuilder(DatabaseInterface::class)
175
            ->disableOriginalConstructor()
176
            ->getMock();
177
178
        $dbi->expects($this->exactly(2))
179
            ->method('query')
180
            ->willReturnOnConsecutiveCalls(
181
                'result1',
182
                'result2'
183
            );
184
185
        $dbi->expects($this->exactly(2))
186
            ->method('fetchAssoc')
187
            ->willReturnOnConsecutiveCalls(
188
                ['assoc1'],
189
                ['assoc2']
190
            );
191
192
        $dbi->expects($this->exactly(2))
193
            ->method('getFieldsMeta')
194
            ->willReturnOnConsecutiveCalls(
195
                [],
196
                []
197
            );
198
199
        $GLOBALS['dbi'] = $dbi;
200
        $this->insertEdit = new InsertEdit($GLOBALS['dbi']);
201
        $result = $this->callFunction(
202
            $this->insertEdit,
203
            InsertEdit::class,
204
            'analyzeWhereClauses',
205
            [
206
                $clauses,
207
                'table',
208
                'db',
209
            ]
210
        );
211
212
        $this->assertEquals(
213
            [
214
                [
215
                    'a=1',
216
                    'b="fo\\\\o"',
217
                ],
218
                [
219
                    'result1',
220
                    'result2',
221
                ],
222
                [
223
                    ['assoc1'],
224
                    ['assoc2'],
225
                ],
226
                '',
227
            ],
228
            $result
229
        );
230
    }
231
232
    /**
233
     * Test for showEmptyResultMessageOrSetUniqueCondition
234
     */
235
    public function testShowEmptyResultMessageOrSetUniqueCondition(): void
236
    {
237
        $temp = new stdClass();
238
        $temp->orgname = 'orgname';
239
        $temp->table = 'table';
240
        $meta_arr = [new FieldMetadata(MYSQLI_TYPE_DECIMAL, MYSQLI_PRI_KEY_FLAG, $temp)];
241
242
        $dbi = $this->getMockBuilder(DatabaseInterface::class)
243
            ->disableOriginalConstructor()
244
            ->getMock();
245
246
        $dbi->expects($this->once())
247
            ->method('getFieldsMeta')
248
            ->with('result1')
249
            ->will($this->returnValue($meta_arr));
250
251
        $GLOBALS['dbi'] = $dbi;
252
        $this->insertEdit = new InsertEdit($GLOBALS['dbi']);
253
254
        $result = $this->callFunction(
255
            $this->insertEdit,
256
            InsertEdit::class,
257
            'showEmptyResultMessageOrSetUniqueCondition',
258
            [
259
                ['1' => ['1' => 1]],
260
                1,
261
                [],
262
                'SELECT',
263
                ['1' => 'result1'],
264
            ]
265
        );
266
267
        $this->assertTrue($result);
268
269
        // case 2
270
        $GLOBALS['cfg']['ShowSQL'] = false;
271
272
        $responseMock = $this->getMockBuilder(Response::class)
273
            ->disableOriginalConstructor()
274
            ->onlyMethods(['addHtml'])
275
            ->getMock();
276
277
        $restoreInstance = Response::getInstance();
278
        $response = new ReflectionProperty(Response::class, 'instance');
279
        $response->setAccessible(true);
280
        $response->setValue($responseMock);
281
282
        $result = $this->callFunction(
283
            $this->insertEdit,
284
            InsertEdit::class,
285
            'showEmptyResultMessageOrSetUniqueCondition',
286
            [
287
                [false],
288
                0,
289
                ['1'],
290
                'SELECT',
291
                ['1' => 'result1'],
292
            ]
293
        );
294
295
        $response->setValue($restoreInstance);
296
297
        $this->assertFalse($result);
298
    }
299
300
    public function dataProviderConfigValueInsertRows(): array
301
    {
302
        return [
303
            [
304
                2,
305
                [
306
                    false,
307
                    false,
308
                ],
309
            ],
310
            [
311
                '2',
312
                [
313
                    false,
314
                    false,
315
                ],
316
            ],
317
            [
318
                3,
319
                [
320
                    false,
321
                    false,
322
                    false,
323
                ],
324
            ],
325
            [
326
                '3',
327
                [
328
                    false,
329
                    false,
330
                    false,
331
                ],
332
            ],
333
        ];
334
    }
335
336
    /**
337
     * Test for loadFirstRow
338
     *
339
     * @param string|int $configValue
340
     *
341
     * @dataProvider dataProviderConfigValueInsertRows
342
     */
343
    public function testLoadFirstRow($configValue, array $rowsValue): void
344
    {
345
        $GLOBALS['cfg']['InsertRows'] = $configValue;
346
347
        $dbi = $this->getMockBuilder(DatabaseInterface::class)
348
            ->disableOriginalConstructor()
349
            ->getMock();
350
351
        $dbi->expects($this->once())
352
            ->method('query')
353
            ->with(
354
                'SELECT * FROM `db`.`table` LIMIT 1;',
355
                DatabaseInterface::CONNECT_USER,
356
                DatabaseInterface::QUERY_STORE
357
            )
358
            ->will($this->returnValue('result1'));
359
360
        $GLOBALS['dbi'] = $dbi;
361
        $this->insertEdit = new InsertEdit($GLOBALS['dbi']);
362
363
        $result = $this->callFunction(
364
            $this->insertEdit,
365
            InsertEdit::class,
366
            'loadFirstRow',
367
            ['table', 'db']
368
        );
369
370
        $this->assertEquals(
371
            [
372
                'result1',
373
                $rowsValue,
374
            ],
375
            $result
376
        );
377
    }
378
379
    /**
380
     * Test for urlParamsInEditMode
381
     */
382
    public function testUrlParamsInEditMode(): void
383
    {
384
        $where_clause_array = [
385
            'foo=1',
386
            'bar=2',
387
        ];
388
        $_POST['sql_query'] = 'SELECT 1';
389
390
        $result = $this->insertEdit->urlParamsInEditMode([1], $where_clause_array);
391
392
        $this->assertEquals(
393
            [
394
                '0' => 1,
395
                'where_clause' => 'bar=2',
396
                'sql_query' => 'SELECT 1',
397
            ],
398
            $result
399
        );
400
    }
401
402
    /**
403
     * Test for showTypeOrFunction
404
     */
405
    public function testShowTypeOrFunction(): void
406
    {
407
        $GLOBALS['cfg']['ShowFieldTypesInDataEditView'] = true;
408
        $GLOBALS['cfg']['ServerDefault'] = 1;
409
        $url_params = ['ShowFunctionFields' => 2];
410
411
        $result = $this->insertEdit->showTypeOrFunction('function', $url_params, false);
412
413
        $this->assertStringContainsString(
414
            'index.php?route=/table/change',
415
            $result
416
        );
417
        $this->assertStringContainsString(
418
            'ShowFunctionFields=1&ShowFieldTypesInDataEditView=1&goto=index.php%3Froute%3D%2Fsql',
419
            $result
420
        );
421
        $this->assertStringContainsString(
422
            'Function',
423
            $result
424
        );
425
426
        // case 2
427
        $result = $this->insertEdit->showTypeOrFunction('function', $url_params, true);
428
429
        $this->assertStringContainsString(
430
            'index.php?route=/table/change',
431
            $result
432
        );
433
        $this->assertStringContainsString(
434
            'ShowFunctionFields=0&ShowFieldTypesInDataEditView=1&goto=index.php%3Froute%3D%2Fsql',
435
            $result
436
        );
437
        $this->assertStringContainsString(
438
            'Function',
439
            $result
440
        );
441
442
        // case 3
443
        $result = $this->insertEdit->showTypeOrFunction('type', $url_params, false);
444
445
        $this->assertStringContainsString(
446
            'index.php?route=/table/change',
447
            $result
448
        );
449
        $this->assertStringContainsString(
450
            'ShowFunctionFields=1&ShowFieldTypesInDataEditView=1&goto=index.php%3Froute%3D%2Fsql',
451
            $result
452
        );
453
        $this->assertStringContainsString(
454
            'Type',
455
            $result
456
        );
457
458
        // case 4
459
        $result = $this->insertEdit->showTypeOrFunction('type', $url_params, true);
460
461
        $this->assertStringContainsString(
462
            'index.php?route=/table/change',
463
            $result
464
        );
465
        $this->assertStringContainsString(
466
            'ShowFunctionFields=1&ShowFieldTypesInDataEditView=0&goto=index.php%3Froute%3D%2Fsql',
467
            $result
468
        );
469
        $this->assertStringContainsString(
470
            'Type',
471
            $result
472
        );
473
    }
474
475
    /**
476
     * Test for analyzeTableColumnsArray
477
     */
478
    public function testAnalyzeTableColumnsArray(): void
479
    {
480
        $column = [
481
            'Field' => '1<2',
482
            'Field_md5' => 'pswd',
483
            'Type' => 'float(10, 1)',
484
        ];
485
486
        $result = $this->callFunction(
487
            $this->insertEdit,
488
            InsertEdit::class,
489
            'analyzeTableColumnsArray',
490
            [
491
                $column,
492
                [],
493
                false,
494
            ]
495
        );
496
497
        $this->assertEquals(
498
            $result['Field_html'],
499
            '1&lt;2'
500
        );
501
502
        $this->assertEquals(
503
            $result['Field_md5'],
504
            '4342210df36bf2ff2c4e2a997a6d4089'
505
        );
506
507
        $this->assertEquals(
508
            $result['True_Type'],
509
            'float'
510
        );
511
512
        $this->assertEquals(
513
            $result['len'],
514
            100
515
        );
516
517
        $this->assertEquals(
518
            $result['Field_title'],
519
            '1&lt;2'
520
        );
521
522
        $this->assertEquals(
523
            $result['is_binary'],
524
            false
525
        );
526
527
        $this->assertEquals(
528
            $result['is_blob'],
529
            false
530
        );
531
532
        $this->assertEquals(
533
            $result['is_char'],
534
            false
535
        );
536
537
        $this->assertEquals(
538
            $result['pma_type'],
539
            'float(10, 1)'
540
        );
541
542
        $this->assertEquals(
543
            $result['wrap'],
544
            ' text-nowrap'
545
        );
546
547
        $this->assertEquals(
548
            $result['Field'],
549
            '1<2'
550
        );
551
    }
552
553
    /**
554
     * Test for getColumnTitle
555
     */
556
    public function testGetColumnTitle(): void
557
    {
558
        $column = [];
559
        $column['Field'] = 'f1<';
560
        $column['Field_html'] = 'f1&lt;';
561
562
        $this->assertEquals(
563
            $this->callFunction(
564
                $this->insertEdit,
565
                InsertEdit::class,
566
                'getColumnTitle',
567
                [
568
                    $column,
569
                    [],
570
                ]
571
            ),
572
            'f1&lt;'
573
        );
574
575
        $comments = [];
576
        $comments['f1<'] = 'comment>';
577
578
        $result = $this->callFunction(
579
            $this->insertEdit,
580
            InsertEdit::class,
581
            'getColumnTitle',
582
            [
583
                $column,
584
                $comments,
585
            ]
586
        );
587
588
        $this->assertStringContainsString(
589
            'title="comment&gt;"',
590
            $result
591
        );
592
593
        $this->assertStringContainsString(
594
            'f1&lt;',
595
            $result
596
        );
597
    }
598
599
    /**
600
     * Test for isColumn
601
     */
602
    public function testIsColumn(): void
603
    {
604
        $column = [];
605
        $types = [
606
            'binary',
607
            'varbinary',
608
        ];
609
610
        $column['Type'] = 'binaryfoo';
611
        $this->assertTrue($this->insertEdit->isColumn($column, $types));
612
613
        $column['Type'] = 'Binaryfoo';
614
        $this->assertTrue($this->insertEdit->isColumn($column, $types));
615
616
        $column['Type'] = 'varbinaryfoo';
617
        $this->assertTrue($this->insertEdit->isColumn($column, $types));
618
619
        $column['Type'] = 'barbinaryfoo';
620
        $this->assertFalse($this->insertEdit->isColumn($column, $types));
621
622
        $types = [
623
            'char',
624
            'varchar',
625
        ];
626
627
        $column['Type'] = 'char(10)';
628
        $this->assertTrue($this->insertEdit->isColumn($column, $types));
629
630
        $column['Type'] = 'VarChar(20)';
631
        $this->assertTrue($this->insertEdit->isColumn($column, $types));
632
633
        $column['Type'] = 'foochar';
634
        $this->assertFalse($this->insertEdit->isColumn($column, $types));
635
636
        $types = [
637
            'blob',
638
            'tinyblob',
639
            'mediumblob',
640
            'longblob',
641
        ];
642
643
        $column['Type'] = 'blob';
644
        $this->assertTrue($this->insertEdit->isColumn($column, $types));
645
646
        $column['Type'] = 'bloB';
647
        $this->assertTrue($this->insertEdit->isColumn($column, $types));
648
649
        $column['Type'] = 'mediumBloB';
650
        $this->assertTrue($this->insertEdit->isColumn($column, $types));
651
652
        $column['Type'] = 'tinyblobabc';
653
        $this->assertTrue($this->insertEdit->isColumn($column, $types));
654
655
        $column['Type'] = 'longblob';
656
        $this->assertTrue($this->insertEdit->isColumn($column, $types));
657
658
        $column['Type'] = 'foolongblobbar';
659
        $this->assertFalse($this->insertEdit->isColumn($column, $types));
660
    }
661
662
    /**
663
     * Test for getEnumSetAndTimestampColumns
664
     */
665
    public function testGetEnumAndTimestampColumns(): void
666
    {
667
        $column = [];
668
        $column['True_Type'] = 'set';
669
        $this->assertEquals(
670
            [
671
                'set',
672
                '',
673
                false,
674
            ],
675
            $this->callFunction(
676
                $this->insertEdit,
677
                InsertEdit::class,
678
                'getEnumSetAndTimestampColumns',
679
                [
680
                    $column,
681
                    false,
682
                ]
683
            )
684
        );
685
686
        $column['True_Type'] = 'enum';
687
        $this->assertEquals(
688
            [
689
                'enum',
690
                '',
691
                false,
692
            ],
693
            $this->callFunction(
694
                $this->insertEdit,
695
                InsertEdit::class,
696
                'getEnumSetAndTimestampColumns',
697
                [
698
                    $column,
699
                    false,
700
                ]
701
            )
702
        );
703
704
        $column['True_Type'] = 'timestamp';
705
        $column['Type'] = 'date';
706
        $this->assertEquals(
707
            [
708
                'date',
709
                ' text-nowrap',
710
                true,
711
            ],
712
            $this->callFunction(
713
                $this->insertEdit,
714
                InsertEdit::class,
715
                'getEnumSetAndTimestampColumns',
716
                [
717
                    $column,
718
                    false,
719
                ]
720
            )
721
        );
722
723
        $column['True_Type'] = 'timestamp';
724
        $column['Type'] = 'date';
725
        $this->assertEquals(
726
            [
727
                'date',
728
                ' text-nowrap',
729
                false,
730
            ],
731
            $this->callFunction(
732
                $this->insertEdit,
733
                InsertEdit::class,
734
                'getEnumSetAndTimestampColumns',
735
                [
736
                    $column,
737
                    true,
738
                ]
739
            )
740
        );
741
742
        $column['True_Type'] = 'SET';
743
        $column['Type'] = 'num';
744
        $this->assertEquals(
745
            [
746
                'num',
747
                ' text-nowrap',
748
                false,
749
            ],
750
            $this->callFunction(
751
                $this->insertEdit,
752
                InsertEdit::class,
753
                'getEnumSetAndTimestampColumns',
754
                [
755
                    $column,
756
                    false,
757
                ]
758
            )
759
        );
760
761
        $column['True_Type'] = '';
762
        $column['Type'] = 'num';
763
        $this->assertEquals(
764
            [
765
                'num',
766
                ' text-nowrap',
767
                false,
768
            ],
769
            $this->callFunction(
770
                $this->insertEdit,
771
                InsertEdit::class,
772
                'getEnumSetAndTimestampColumns',
773
                [
774
                    $column,
775
                    false,
776
                ]
777
            )
778
        );
779
    }
780
781
    /**
782
     * Test for getNullifyCodeForNullColumn
783
     */
784
    public function testGetNullifyCodeForNullColumn(): void
785
    {
786
        $column = $foreignData = [];
787
        $foreigners = [
788
            'foreign_keys_data' => [],
789
        ];
790
        $column['Field'] = 'f';
791
        $column['True_Type'] = 'enum';
792
        $column['Type'] = 'ababababababababababa';
793
        $this->assertEquals(
794
            '1',
795
            $this->callFunction(
796
                $this->insertEdit,
797
                InsertEdit::class,
798
                'getNullifyCodeForNullColumn',
799
                [
800
                    $column,
801
                    $foreigners,
802
                    [],
803
                ]
804
            )
805
        );
806
807
        $column['True_Type'] = 'enum';
808
        $column['Type'] = 'abababababababababab';
809
        $this->assertEquals(
810
            '2',
811
            $this->callFunction(
812
                $this->insertEdit,
813
                InsertEdit::class,
814
                'getNullifyCodeForNullColumn',
815
                [
816
                    $column,
817
                    $foreigners,
818
                    [],
819
                ]
820
            )
821
        );
822
823
        $column['True_Type'] = 'set';
824
        $this->assertEquals(
825
            '3',
826
            $this->callFunction(
827
                $this->insertEdit,
828
                InsertEdit::class,
829
                'getNullifyCodeForNullColumn',
830
                [
831
                    $column,
832
                    $foreigners,
833
                    [],
834
                ]
835
            )
836
        );
837
838
        $column['True_Type'] = '';
839
        $foreigners['f'] = true;
840
        $foreignData['foreign_link'] = '';
841
        $this->assertEquals(
842
            '4',
843
            $this->callFunction(
844
                $this->insertEdit,
845
                InsertEdit::class,
846
                'getNullifyCodeForNullColumn',
847
                [
848
                    $column,
849
                    $foreigners,
850
                    $foreignData,
851
                ]
852
            )
853
        );
854
    }
855
856
    /**
857
     * Test for getTextarea
858
     */
859
    public function testGetTextarea(): void
860
    {
861
        $GLOBALS['cfg']['TextareaRows'] = 20;
862
        $GLOBALS['cfg']['TextareaCols'] = 10;
863
        $GLOBALS['cfg']['CharTextareaRows'] = 7;
864
        $GLOBALS['cfg']['CharTextareaCols'] = 1;
865
        $GLOBALS['cfg']['LimitChars'] = 20;
866
867
        $column = [];
868
        $column['is_char'] = true;
869
        $column['Type'] = 'char(10)';
870
        $column['True_Type'] = 'char';
871
        $result = $this->callFunction(
872
            $this->insertEdit,
873
            InsertEdit::class,
874
            'getTextarea',
875
            [
876
                $column,
877
                'a',
878
                'b',
879
                '',
880
                2,
881
                0,
882
                1,
883
                'abc/',
884
                'foobar',
885
                'CHAR',
886
                false,
887
            ]
888
        );
889
890
        $this->assertStringContainsString(
891
            '<textarea name="fieldsb" class="char charField" '
892
            . 'data-maxlength="10" rows="7" cols="1" dir="abc/" '
893
            . 'id="field_1_3" tabindex="2" data-type="CHAR">',
894
            $result
895
        );
896
    }
897
898
    /**
899
     * Test for getColumnEnumValues
900
     */
901
    public function testGetColumnEnumValues(): void
902
    {
903
        $extracted_columnspec = $column = [];
904
        $extracted_columnspec['enum_set_values'] = [
905
            '<abc>',
906
            '"foo"',
907
        ];
908
909
        $column['values'] = 'abc';
910
911
        $result = $this->callFunction(
912
            $this->insertEdit,
913
            InsertEdit::class,
914
            'getColumnEnumValues',
915
            [
916
                $column,
917
                $extracted_columnspec,
918
            ]
919
        );
920
        $this->assertEquals(
921
            [
922
                [
923
                    'plain' => '<abc>',
924
                    'html' => '&lt;abc&gt;',
925
                ],
926
                [
927
                    'plain' => '"foo"',
928
                    'html' => '&quot;foo&quot;',
929
                ],
930
            ],
931
            $result
932
        );
933
    }
934
935
    /**
936
     * Test for getColumnSetValueAndSelectSize
937
     */
938
    public function testGetColumnSetValueAndSelectSize(): void
939
    {
940
        $extracted_columnspec = $column = [];
941
        $extracted_columnspec['enum_set_values'] = [
942
            'a',
943
            '<',
944
        ];
945
        $result = $this->callFunction(
946
            $this->insertEdit,
947
            InsertEdit::class,
948
            'getColumnSetValueAndSelectSize',
949
            [
950
                [],
951
                $extracted_columnspec,
952
            ]
953
        );
954
955
        $this->assertEquals(
956
            [
957
                [
958
                    [
959
                        'plain' => 'a',
960
                        'html' => 'a',
961
                    ],
962
                    [
963
                        'plain' => '<',
964
                        'html' => '&lt;',
965
                    ],
966
                ],
967
                2,
968
            ],
969
            $result
970
        );
971
972
        $column['values'] = [
973
            1,
974
            2,
975
        ];
976
        $column['select_size'] = 3;
977
        $result = $this->callFunction(
978
            $this->insertEdit,
979
            InsertEdit::class,
980
            'getColumnSetValueAndSelectSize',
981
            [
982
                $column,
983
                $extracted_columnspec,
984
            ]
985
        );
986
987
        $this->assertEquals(
988
            [
989
                [
990
                    1,
991
                    2,
992
                ],
993
                3,
994
            ],
995
            $result
996
        );
997
    }
998
999
    /**
1000
     * Test for getHtmlInput
1001
     */
1002
    public function testGetHTMLinput(): void
1003
    {
1004
        $GLOBALS['cfg']['ShowFunctionFields'] = true;
1005
        $column = [];
1006
        $column['pma_type'] = 'date';
1007
        $column['True_Type'] = 'date';
1008
        $result = $this->callFunction(
1009
            $this->insertEdit,
1010
            InsertEdit::class,
1011
            'getHtmlInput',
1012
            [
1013
                $column,
1014
                'a',
1015
                'b',
1016
                30,
1017
                'c',
1018
                23,
1019
                2,
1020
                0,
1021
                'DATE',
1022
                false,
1023
            ]
1024
        );
1025
1026
        $this->assertEquals(
1027
            '<input type="text" name="fieldsa" value="b" size="30" data-type="DATE"'
1028
            . ' class="textfield datefield" c tabindex="25" id="field_0_3">',
1029
            $result
1030
        );
1031
1032
        // case 2 datetime
1033
        $column['pma_type'] = 'datetime';
1034
        $column['True_Type'] = 'datetime';
1035
        $result = $this->callFunction(
1036
            $this->insertEdit,
1037
            InsertEdit::class,
1038
            'getHtmlInput',
1039
            [
1040
                $column,
1041
                'a',
1042
                'b',
1043
                30,
1044
                'c',
1045
                23,
1046
                2,
1047
                0,
1048
                'DATE',
1049
                false,
1050
            ]
1051
        );
1052
        $this->assertEquals(
1053
            '<input type="text" name="fieldsa" value="b" size="30" data-type="DATE"'
1054
            . ' class="textfield datetimefield" c tabindex="25" id="field_0_3">',
1055
            $result
1056
        );
1057
1058
        // case 3 timestamp
1059
        $column['pma_type'] = 'timestamp';
1060
        $column['True_Type'] = 'timestamp';
1061
        $result = $this->callFunction(
1062
            $this->insertEdit,
1063
            InsertEdit::class,
1064
            'getHtmlInput',
1065
            [
1066
                $column,
1067
                'a',
1068
                'b',
1069
                30,
1070
                'c',
1071
                23,
1072
                2,
1073
                0,
1074
                'DATE',
1075
                false,
1076
            ]
1077
        );
1078
        $this->assertEquals(
1079
            '<input type="text" name="fieldsa" value="b" size="30" data-type="DATE"'
1080
            . ' class="textfield datetimefield" c tabindex="25" id="field_0_3">',
1081
            $result
1082
        );
1083
    }
1084
1085
    /**
1086
     * Test for getMaxUploadSize
1087
     */
1088
    public function testGetMaxUploadSize(): void
1089
    {
1090
        $GLOBALS['max_upload_size'] = 257;
1091
        $column = [];
1092
        $column['pma_type'] = 'tinyblob';
1093
        $result = $this->callFunction(
1094
            $this->insertEdit,
1095
            InsertEdit::class,
1096
            'getMaxUploadSize',
1097
            [
1098
                $column,
1099
                256,
1100
            ]
1101
        );
1102
1103
        $this->assertEquals(
1104
            [
1105
                "(Max: 256B)\n",
1106
                256,
1107
            ],
1108
            $result
1109
        );
1110
1111
        // case 2
1112
        $GLOBALS['max_upload_size'] = 250;
1113
        $column['pma_type'] = 'tinyblob';
1114
        $result = $this->callFunction(
1115
            $this->insertEdit,
1116
            InsertEdit::class,
1117
            'getMaxUploadSize',
1118
            [
1119
                $column,
1120
                20,
1121
            ]
1122
        );
1123
1124
        $this->assertEquals(
1125
            [
1126
                "(Max: 250B)\n",
1127
                250,
1128
            ],
1129
            $result
1130
        );
1131
    }
1132
1133
    /**
1134
     * Test for getValueColumnForOtherDatatypes
1135
     */
1136
    public function testGetValueColumnForOtherDatatypes(): void
1137
    {
1138
        $column = [];
1139
        $column['len'] = 20;
1140
        $column['is_char'] = true;
1141
        $column['Type'] = 'char(25)';
1142
        $column['True_Type'] = 'char';
1143
        $GLOBALS['cfg']['CharEditing'] = '';
1144
        $GLOBALS['cfg']['MaxSizeForInputField'] = 30;
1145
        $GLOBALS['cfg']['MinSizeForInputField'] = 10;
1146
        $GLOBALS['cfg']['TextareaRows'] = 20;
1147
        $GLOBALS['cfg']['TextareaCols'] = 10;
1148
        $GLOBALS['cfg']['CharTextareaRows'] = 7;
1149
        $GLOBALS['cfg']['CharTextareaCols'] = 1;
1150
        $GLOBALS['cfg']['LimitChars'] = 50;
1151
        $GLOBALS['cfg']['ShowFunctionFields'] = true;
1152
1153
        $extracted_columnspec = [];
1154
        $extracted_columnspec['spec_in_brackets'] = 25;
1155
        $result = $this->callFunction(
1156
            $this->insertEdit,
1157
            InsertEdit::class,
1158
            'getValueColumnForOtherDatatypes',
1159
            [
1160
                $column,
1161
                'defchar',
1162
                'a',
1163
                'b',
1164
                'c',
1165
                22,
1166
                '&lt;',
1167
                12,
1168
                1,
1169
                '/',
1170
                '&lt;',
1171
                "foo\nbar",
1172
                $extracted_columnspec,
1173
                false,
1174
            ]
1175
        );
1176
1177
        $this->assertEquals(
1178
            "a\n\na\n"
1179
            . '<textarea name="fieldsb" class="char charField" '
1180
            . 'data-maxlength="25" rows="7" cols="1" dir="/" '
1181
            . 'id="field_1_3" c tabindex="34" data-type="CHAR">'
1182
            . '&lt;</textarea>',
1183
            $result
1184
        );
1185
1186
        // case 2: (else)
1187
        $column['is_char'] = false;
1188
        $column['Extra'] = 'auto_increment';
1189
        $column['pma_type'] = 'timestamp';
1190
        $column['True_Type'] = 'timestamp';
1191
        $result = $this->callFunction(
1192
            $this->insertEdit,
1193
            InsertEdit::class,
1194
            'getValueColumnForOtherDatatypes',
1195
            [
1196
                $column,
1197
                'defchar',
1198
                'a',
1199
                'b',
1200
                'c',
1201
                22,
1202
                '&lt;',
1203
                12,
1204
                1,
1205
                '/',
1206
                '&lt;',
1207
                "foo\nbar",
1208
                $extracted_columnspec,
1209
                false,
1210
            ]
1211
        );
1212
1213
        $this->assertEquals(
1214
            "a\n"
1215
            . '<input type="text" name="fieldsb" value="&lt;" size="20" data-type="'
1216
            . 'DATE" class="textfield datetimefield" c tabindex="34" id="field_1_3"'
1217
            . '><input type="hidden" name="auto_incrementb" value="1">'
1218
            . '<input type="hidden" name="fields_typeb" value="timestamp">',
1219
            $result
1220
        );
1221
1222
        // case 3: (else -> datetime)
1223
        $column['pma_type'] = 'datetime';
1224
        $result = $this->callFunction(
1225
            $this->insertEdit,
1226
            InsertEdit::class,
1227
            'getValueColumnForOtherDatatypes',
1228
            [
1229
                $column,
1230
                'defchar',
1231
                'a',
1232
                'b',
1233
                'c',
1234
                22,
1235
                '&lt;',
1236
                12,
1237
                1,
1238
                '/',
1239
                '&lt;',
1240
                "foo\nbar",
1241
                $extracted_columnspec,
1242
                false,
1243
            ]
1244
        );
1245
1246
        $this->assertStringContainsString(
1247
            '<input type="hidden" name="fields_typeb" value="datetime">',
1248
            $result
1249
        );
1250
1251
        // case 4: (else -> date)
1252
        $column['pma_type'] = 'date';
1253
        $result = $this->callFunction(
1254
            $this->insertEdit,
1255
            InsertEdit::class,
1256
            'getValueColumnForOtherDatatypes',
1257
            [
1258
                $column,
1259
                'defchar',
1260
                'a',
1261
                'b',
1262
                'c',
1263
                22,
1264
                '&lt;',
1265
                12,
1266
                1,
1267
                '/',
1268
                '&lt;',
1269
                "foo\nbar",
1270
                $extracted_columnspec,
1271
                false,
1272
            ]
1273
        );
1274
1275
        $this->assertStringContainsString(
1276
            '<input type="hidden" name="fields_typeb" value="date">',
1277
            $result
1278
        );
1279
    }
1280
1281
    /**
1282
     * Test for getColumnSize
1283
     */
1284
    public function testGetColumnSize(): void
1285
    {
1286
        $column = $extracted_columnspec = [];
1287
        $column['is_char'] = true;
1288
        $extracted_columnspec['spec_in_brackets'] = 45;
1289
        $GLOBALS['cfg']['MinSizeForInputField'] = 30;
1290
        $GLOBALS['cfg']['MaxSizeForInputField'] = 40;
1291
1292
        $this->assertEquals(
1293
            40,
1294
            $this->callFunction(
1295
                $this->insertEdit,
1296
                InsertEdit::class,
1297
                'getColumnSize',
1298
                [
1299
                    $column,
1300
                    $extracted_columnspec,
1301
                ]
1302
            )
1303
        );
1304
1305
        $this->assertEquals(
1306
            'textarea',
1307
            $GLOBALS['cfg']['CharEditing']
1308
        );
1309
1310
        // case 2
1311
        $column['is_char'] = false;
1312
        $column['len'] = 20;
1313
        $this->assertEquals(
1314
            30,
1315
            $this->callFunction(
1316
                $this->insertEdit,
1317
                InsertEdit::class,
1318
                'getColumnSize',
1319
                [
1320
                    $column,
1321
                    $extracted_columnspec,
1322
                ]
1323
            )
1324
        );
1325
    }
1326
1327
    /**
1328
     * Test for getContinueInsertionForm
1329
     */
1330
    public function testGetContinueInsertionForm(): void
1331
    {
1332
        $where_clause_array = ['a<b'];
1333
        $GLOBALS['cfg']['InsertRows'] = 1;
1334
        $GLOBALS['cfg']['ServerDefault'] = 1;
1335
        $GLOBALS['goto'] = 'index.php';
1336
        $_POST['where_clause'] = true;
1337
        $_POST['sql_query'] = 'SELECT 1';
1338
1339
        $result = $this->insertEdit->getContinueInsertionForm(
1340
            'tbl',
1341
            'db',
1342
            $where_clause_array,
1343
            'localhost'
1344
        );
1345
1346
        $this->assertStringContainsString(
1347
            '<form id="continueForm" method="post" action="' . Url::getFromRoute('/table/replace')
1348
            . '" name="continueForm">',
1349
            $result
1350
        );
1351
1352
        $this->assertStringContainsString(
1353
            '<input type="hidden" name="db" value="db">',
1354
            $result
1355
        );
1356
1357
        $this->assertStringContainsString(
1358
            '<input type="hidden" name="table" value="tbl">',
1359
            $result
1360
        );
1361
1362
        $this->assertStringContainsString(
1363
            '<input type="hidden" name="goto" value="index.php">',
1364
            $result
1365
        );
1366
1367
        $this->assertStringContainsString(
1368
            '<input type="hidden" name="err_url" value="localhost">',
1369
            $result
1370
        );
1371
1372
        $this->assertStringContainsString(
1373
            '<input type="hidden" name="sql_query" value="SELECT 1">',
1374
            $result
1375
        );
1376
1377
        $this->assertStringContainsString(
1378
            '<input type="hidden" name="where_clause[0]" value="a&lt;b">',
1379
            $result
1380
        );
1381
    }
1382
1383
    public function testIsWhereClauseNumeric(): void
1384
    {
1385
        $this->assertFalse(InsertEdit::isWhereClauseNumeric(null));
1386
        $this->assertFalse(InsertEdit::isWhereClauseNumeric(''));
1387
        $this->assertFalse(InsertEdit::isWhereClauseNumeric([]));
1388
        $this->assertTrue(InsertEdit::isWhereClauseNumeric('`actor`.`actor_id` = 1'));
1389
        $this->assertTrue(InsertEdit::isWhereClauseNumeric(['`actor`.`actor_id` = 1']));
1390
        $this->assertFalse(InsertEdit::isWhereClauseNumeric('`actor`.`first_name` = \'value\''));
1391
        $this->assertFalse(InsertEdit::isWhereClauseNumeric(['`actor`.`first_name` = \'value\'']));
1392
    }
1393
1394
    /**
1395
     * Test for getHeadAndFootOfInsertRowTable
1396
     */
1397
    public function testGetHeadAndFootOfInsertRowTable(): void
1398
    {
1399
        $GLOBALS['cfg']['ShowFieldTypesInDataEditView'] = true;
1400
        $GLOBALS['cfg']['ShowFunctionFields'] = true;
1401
        $GLOBALS['cfg']['ServerDefault'] = 1;
1402
        $url_params = ['ShowFunctionFields' => 2];
1403
1404
        $result = $this->callFunction(
1405
            $this->insertEdit,
1406
            InsertEdit::class,
1407
            'getHeadAndFootOfInsertRowTable',
1408
            [$url_params]
1409
        );
1410
1411
        $this->assertStringContainsString(
1412
            'index.php?route=/table/change',
1413
            $result
1414
        );
1415
1416
        $this->assertStringContainsString(
1417
            'ShowFunctionFields=1&ShowFieldTypesInDataEditView=0',
1418
            $result
1419
        );
1420
1421
        $this->assertStringContainsString(
1422
            'ShowFunctionFields=0&ShowFieldTypesInDataEditView=1',
1423
            $result
1424
        );
1425
    }
1426
1427
    /**
1428
     * Test for getSpecialCharsAndBackupFieldForExistingRow
1429
     */
1430
    public function testGetSpecialCharsAndBackupFieldForExistingRow(): void
1431
    {
1432
        $column = $current_row = $extracted_columnspec = [];
1433
        $column['Field'] = 'f';
1434
        $current_row['f'] = null;
1435
        $_POST['default_action'] = 'insert';
1436
        $column['Key'] = 'PRI';
1437
        $column['Extra'] = 'fooauto_increment';
1438
1439
        $result = $this->callFunction(
1440
            $this->insertEdit,
1441
            InsertEdit::class,
1442
            'getSpecialCharsAndBackupFieldForExistingRow',
1443
            [
1444
                $current_row,
1445
                $column,
1446
                [],
1447
                false,
1448
                [],
1449
                'a',
1450
                false,
1451
            ]
1452
        );
1453
1454
        $this->assertEquals(
1455
            [
1456
                true,
1457
                null,
1458
                null,
1459
                null,
1460
                '<input type="hidden" name="fields_preva" value="">',
1461
            ],
1462
            $result
1463
        );
1464
1465
        // Case 2 (bit)
1466
        unset($_POST['default_action']);
1467
1468
        $current_row['f'] = '123';
1469
        $extracted_columnspec['spec_in_brackets'] = 20;
1470
        $column['True_Type'] = 'bit';
1471
1472
        $result = $this->callFunction(
1473
            $this->insertEdit,
1474
            InsertEdit::class,
1475
            'getSpecialCharsAndBackupFieldForExistingRow',
1476
            [
1477
                $current_row,
1478
                $column,
1479
                $extracted_columnspec,
1480
                false,
1481
                [],
1482
                'a',
1483
                false,
1484
            ]
1485
        );
1486
1487
        $this->assertEquals(
1488
            [
1489
                false,
1490
                '',
1491
                '00000000000001111011',
1492
                null,
1493
                '<input type="hidden" name="fields_preva" value="123">',
1494
            ],
1495
            $result
1496
        );
1497
1498
        $current_row['f'] = 'abcd';
1499
        $result = $this->callFunction(
1500
            $this->insertEdit,
1501
            InsertEdit::class,
1502
            'getSpecialCharsAndBackupFieldForExistingRow',
1503
            [
1504
                $current_row,
1505
                $column,
1506
                $extracted_columnspec,
1507
                false,
1508
                [],
1509
                'a',
1510
                true,
1511
            ]
1512
        );
1513
1514
        $this->assertEquals(
1515
            [
1516
                false,
1517
                '',
1518
                'abcd',
1519
                null,
1520
                '<input type="hidden" name="fields_preva" value="abcd">',
1521
            ],
1522
            $result
1523
        );
1524
1525
        // Case 3 (bit)
1526
        $dbi = $this->getMockBuilder(DatabaseInterface::class)
1527
            ->disableOriginalConstructor()
1528
            ->getMock();
1529
1530
        $GLOBALS['dbi'] = $dbi;
1531
        $this->insertEdit = new InsertEdit($GLOBALS['dbi']);
1532
1533
        $current_row['f'] = '123';
1534
        $extracted_columnspec['spec_in_brackets'] = 20;
1535
        $column['True_Type'] = 'int';
1536
1537
        $result = $this->callFunction(
1538
            $this->insertEdit,
1539
            InsertEdit::class,
1540
            'getSpecialCharsAndBackupFieldForExistingRow',
1541
            [
1542
                $current_row,
1543
                $column,
1544
                $extracted_columnspec,
1545
                false,
1546
                ['int'],
1547
                'a',
1548
                false,
1549
            ]
1550
        );
1551
1552
        $this->assertEquals(
1553
            [
1554
                false,
1555
                '',
1556
                "'',",
1557
                null,
1558
                '<input type="hidden" name="fields_preva" value="\'\',">',
1559
            ],
1560
            $result
1561
        );
1562
1563
        // Case 4 (else)
1564
        $column['is_binary'] = false;
1565
        $column['is_blob'] = true;
1566
        $GLOBALS['cfg']['ProtectBinary'] = false;
1567
        $current_row['f'] = '11001';
1568
        $extracted_columnspec['spec_in_brackets'] = 20;
1569
        $column['True_Type'] = 'char';
1570
        $GLOBALS['cfg']['ShowFunctionFields'] = true;
1571
1572
        $result = $this->callFunction(
1573
            $this->insertEdit,
1574
            InsertEdit::class,
1575
            'getSpecialCharsAndBackupFieldForExistingRow',
1576
            [
1577
                $current_row,
1578
                $column,
1579
                $extracted_columnspec,
1580
                false,
1581
                ['int'],
1582
                'a',
1583
                false,
1584
            ]
1585
        );
1586
1587
        $this->assertEquals(
1588
            [
1589
                false,
1590
                '3131303031',
1591
                '3131303031',
1592
                '3131303031',
1593
                '<input type="hidden" name="fields_preva" value="3131303031">',
1594
            ],
1595
            $result
1596
        );
1597
1598
        // Case 5
1599
        $current_row['f'] = "11001\x00";
1600
1601
        $result = $this->callFunction(
1602
            $this->insertEdit,
1603
            InsertEdit::class,
1604
            'getSpecialCharsAndBackupFieldForExistingRow',
1605
            [
1606
                $current_row,
1607
                $column,
1608
                $extracted_columnspec,
1609
                false,
1610
                ['int'],
1611
                'a',
1612
                false,
1613
            ]
1614
        );
1615
1616
        $this->assertEquals(
1617
            [
1618
                false,
1619
                '313130303100',
1620
                '313130303100',
1621
                '313130303100',
1622
                '<input type="hidden" name="fields_preva" value="313130303100">',
1623
            ],
1624
            $result
1625
        );
1626
    }
1627
1628
    /**
1629
     * Test for getSpecialCharsAndBackupFieldForInsertingMode
1630
     */
1631
    public function testGetSpecialCharsAndBackupFieldForInsertingMode(): void
1632
    {
1633
        $column = [];
1634
        $column['True_Type'] = 'bit';
1635
        $column['Default'] = 'b\'101\'';
1636
        $column['is_binary'] = true;
1637
        $GLOBALS['cfg']['ProtectBinary'] = false;
1638
        $GLOBALS['cfg']['ShowFunctionFields'] = true;
1639
1640
        $result = $this->callFunction(
1641
            $this->insertEdit,
1642
            InsertEdit::class,
1643
            'getSpecialCharsAndBackupFieldForInsertingMode',
1644
            [
1645
                $column,
1646
                false,
1647
            ]
1648
        );
1649
1650
        $this->assertEquals(
1651
            [
1652
                false,
1653
                'b\'101\'',
1654
                '101',
1655
                '',
1656
                '101',
1657
            ],
1658
            $result
1659
        );
1660
1661
        // case 2
1662
        unset($column['Default']);
1663
        $column['True_Type'] = 'char';
1664
1665
        $result = $this->callFunction(
1666
            $this->insertEdit,
1667
            InsertEdit::class,
1668
            'getSpecialCharsAndBackupFieldForInsertingMode',
1669
            [
1670
                $column,
1671
                false,
1672
            ]
1673
        );
1674
1675
        $this->assertEquals(
1676
            [
1677
                true,
1678
                '',
1679
                '',
1680
                '',
1681
                '',
1682
            ],
1683
            $result
1684
        );
1685
    }
1686
1687
    /**
1688
     * Test for getParamsForUpdateOrInsert
1689
     */
1690
    public function testGetParamsForUpdateOrInsert(): void
1691
    {
1692
        $_POST['where_clause'] = 'LIMIT 1';
1693
        $_POST['submit_type'] = 'showinsert';
1694
1695
        $result = $this->insertEdit->getParamsForUpdateOrInsert();
1696
1697
        $this->assertEquals(
1698
            [
1699
                ['LIMIT 1'],
1700
                true,
1701
                true,
1702
                false,
1703
            ],
1704
            $result
1705
        );
1706
1707
        // case 2 (else)
1708
        unset($_POST['where_clause']);
1709
        $_POST['fields']['multi_edit'] = [
1710
            'a' => 'b',
1711
            'c' => 'd',
1712
        ];
1713
        $result = $this->insertEdit->getParamsForUpdateOrInsert();
1714
1715
        $this->assertEquals(
1716
            [
1717
                [
1718
                    'a',
1719
                    'c',
1720
                ],
1721
                false,
1722
                true,
1723
                false,
1724
            ],
1725
            $result
1726
        );
1727
    }
1728
1729
    /**
1730
     * Test for isInsertRow
1731
     */
1732
    public function testIsInsertRow(): void
1733
    {
1734
        $_POST['insert_rows'] = 5;
1735
        $GLOBALS['cfg']['InsertRows'] = 2;
1736
1737
        $scriptsMock = $this->getMockBuilder(Scripts::class)
1738
            ->disableOriginalConstructor()
1739
            ->onlyMethods(['addFile'])
1740
            ->getMock();
1741
1742
        $scriptsMock->expects($this->exactly(2))
1743
            ->method('addFile');
1744
1745
        $headerMock = $this->getMockBuilder(Header::class)
1746
            ->disableOriginalConstructor()
1747
            ->onlyMethods(['getScripts'])
1748
            ->getMock();
1749
1750
        $headerMock->expects($this->once())
1751
            ->method('getScripts')
1752
            ->will($this->returnValue($scriptsMock));
1753
1754
        $responseMock = $this->getMockBuilder(Response::class)
1755
            ->disableOriginalConstructor()
1756
            ->onlyMethods(['getHeader'])
1757
            ->getMock();
1758
1759
        $responseMock->expects($this->once())
1760
            ->method('getHeader')
1761
            ->will($this->returnValue($headerMock));
1762
1763
        $restoreInstance = Response::getInstance();
1764
        $response = new ReflectionProperty(Response::class, 'instance');
1765
        $response->setAccessible(true);
1766
        $response->setValue($responseMock);
1767
1768
        $this->insertEdit->isInsertRow();
1769
1770
        $response->setValue($restoreInstance);
1771
1772
        $this->assertEquals(5, $GLOBALS['cfg']['InsertRows']);
1773
    }
1774
1775
    /**
1776
     * Test for setSessionForEditNext
1777
     */
1778
    public function testSetSessionForEditNext(): void
1779
    {
1780
        $temp = new stdClass();
1781
        $temp->orgname = 'orgname';
1782
        $temp->table = 'table';
1783
        $temp->orgtable = 'table';
1784
        $meta_arr = [new FieldMetadata(MYSQLI_TYPE_DECIMAL, MYSQLI_PRI_KEY_FLAG, $temp)];
1785
1786
        $row = ['1' => 1];
1787
        $res = 'foobar';
1788
1789
        $dbi = $this->getMockBuilder(DatabaseInterface::class)
1790
            ->disableOriginalConstructor()
1791
            ->getMock();
1792
1793
        $dbi->expects($this->once())
1794
            ->method('query')
1795
            ->with('SELECT * FROM `db`.`table` WHERE `a` > 2 LIMIT 1;')
1796
            ->will($this->returnValue($res));
1797
1798
        $dbi->expects($this->once())
1799
            ->method('fetchRow')
1800
            ->with($res)
1801
            ->will($this->returnValue($row));
1802
1803
        $dbi->expects($this->once())
1804
            ->method('getFieldsMeta')
1805
            ->with($res)
1806
            ->will($this->returnValue($meta_arr));
1807
1808
        $GLOBALS['dbi'] = $dbi;
1809
        $GLOBALS['db'] = 'db';
1810
        $GLOBALS['table'] = 'table';
1811
        $this->insertEdit = new InsertEdit($GLOBALS['dbi']);
1812
        $this->insertEdit->setSessionForEditNext('`a` = 2');
1813
1814
        $this->assertEquals(
1815
            'CONCAT(`table`.`orgname`) IS NULL',
1816
            $_SESSION['edit_next']
1817
        );
1818
    }
1819
1820
    /**
1821
     * Test for getGotoInclude
1822
     */
1823
    public function testGetGotoInclude(): void
1824
    {
1825
        $GLOBALS['goto'] = '123.php';
1826
        $GLOBALS['table'] = '';
1827
1828
        $this->assertEquals(
1829
            '/database/sql',
1830
            $this->insertEdit->getGotoInclude('index')
1831
        );
1832
1833
        $GLOBALS['table'] = 'tbl';
1834
        $this->assertEquals(
1835
            '/table/sql',
1836
            $this->insertEdit->getGotoInclude('index')
1837
        );
1838
1839
        $GLOBALS['goto'] = 'index.php?route=/database/sql';
1840
1841
        $this->assertEquals(
1842
            '/database/sql',
1843
            $this->insertEdit->getGotoInclude('index')
1844
        );
1845
1846
        $this->assertEquals(
1847
            '',
1848
            $GLOBALS['table']
1849
        );
1850
1851
        $_POST['after_insert'] = 'new_insert';
1852
        $this->assertEquals(
1853
            '/table/change',
1854
            $this->insertEdit->getGotoInclude('index')
1855
        );
1856
    }
1857
1858
    /**
1859
     * Test for getErrorUrl
1860
     */
1861
    public function testGetErrorUrl(): void
1862
    {
1863
        $GLOBALS['cfg']['ServerDefault'] = 1;
1864
        $this->assertEquals(
1865
            'index.php?route=/table/change&lang=en',
1866
            $this->insertEdit->getErrorUrl([])
1867
        );
1868
1869
        $_POST['err_url'] = 'localhost';
1870
        $this->assertEquals(
1871
            'localhost',
1872
            $this->insertEdit->getErrorUrl([])
1873
        );
1874
    }
1875
1876
    /**
1877
     * Test for buildSqlQuery
1878
     */
1879
    public function testBuildSqlQuery(): void
1880
    {
1881
        $GLOBALS['db'] = 'db';
1882
        $GLOBALS['table'] = 'table';
1883
        $query_fields = [
1884
            'a',
1885
            'b',
1886
        ];
1887
        $value_sets = [
1888
            1,
1889
            2,
1890
        ];
1891
1892
        $this->assertEquals(
1893
            ['INSERT IGNORE INTO `table` (a, b) VALUES (1), (2)'],
1894
            $this->insertEdit->buildSqlQuery(true, $query_fields, $value_sets)
1895
        );
1896
1897
        $this->assertEquals(
1898
            ['INSERT INTO `table` (a, b) VALUES (1), (2)'],
1899
            $this->insertEdit->buildSqlQuery(false, $query_fields, $value_sets)
1900
        );
1901
    }
1902
1903
    /**
1904
     * Test for executeSqlQuery
1905
     */
1906
    public function testExecuteSqlQuery(): void
1907
    {
1908
        $query = [
1909
            'SELECT * FROM `test_db`.`test_table`;',
1910
            'SELECT * FROM `test_db`.`test_table_yaml`;',
1911
        ];
1912
        $GLOBALS['sql_query'] = 'SELECT * FROM `test_db`.`test_table`;';
1913
        $GLOBALS['cfg']['IgnoreMultiSubmitErrors'] = false;
1914
        $_POST['submit_type'] = '';
1915
1916
        $this->insertEdit = new InsertEdit($GLOBALS['dbi']);
1917
        $result = $this->insertEdit->executeSqlQuery([], $query);
1918
1919
        $this->assertEquals(['sql_query' => 'SELECT * FROM `test_db`.`test_table`;'], $result[0]);
1920
        $this->assertEquals([], $result[3]);
1921
        $this->assertEquals('SELECT * FROM `test_db`.`test_table`;', $result[5]);
1922
    }
1923
1924
    /**
1925
     * Test for executeSqlQuery
1926
     */
1927
    public function testExecuteSqlQueryWithTryQuery(): void
1928
    {
1929
        $query = [
1930
            'SELECT * FROM `test_db`.`test_table`;',
1931
            'SELECT * FROM `test_db`.`test_table_yaml`;',
1932
        ];
1933
        $GLOBALS['sql_query'] = 'SELECT * FROM `test_db`.`test_table`;';
1934
        $GLOBALS['cfg']['IgnoreMultiSubmitErrors'] = true;
1935
        $_POST['submit_type'] = '';
1936
1937
        $this->insertEdit = new InsertEdit($GLOBALS['dbi']);
1938
        $result = $this->insertEdit->executeSqlQuery([], $query);
1939
1940
        $this->assertEquals(['sql_query' => 'SELECT * FROM `test_db`.`test_table`;'], $result[0]);
1941
        $this->assertEquals([], $result[3]);
1942
        $this->assertEquals('SELECT * FROM `test_db`.`test_table`;', $result[5]);
1943
    }
1944
1945
    /**
1946
     * Test for getWarningMessages
1947
     */
1948
    public function testGetWarningMessages(): void
1949
    {
1950
        $warnings = [
1951
            [
1952
                'Level' => 1,
1953
                'Code' => 42,
1954
                'Message' => 'msg1',
1955
            ],
1956
            [
1957
                'Level' => 2,
1958
                'Code' => 43,
1959
                'Message' => 'msg2',
1960
            ],
1961
        ];
1962
1963
        $dbi = $this->getMockBuilder(DatabaseInterface::class)
1964
            ->disableOriginalConstructor()
1965
            ->getMock();
1966
1967
        $dbi->expects($this->once())
1968
            ->method('getWarnings')
1969
            ->will($this->returnValue($warnings));
1970
1971
        $GLOBALS['dbi'] = $dbi;
1972
        $this->insertEdit = new InsertEdit($GLOBALS['dbi']);
1973
1974
        $result = $this->callFunction(
1975
            $this->insertEdit,
1976
            InsertEdit::class,
1977
            'getWarningMessages',
1978
            []
1979
        );
1980
1981
        $this->assertEquals(
1982
            [
1983
                '1: #42 msg1',
1984
                '2: #43 msg2',
1985
            ],
1986
            $result
1987
        );
1988
    }
1989
1990
    /**
1991
     * Test for getDisplayValueForForeignTableColumn
1992
     */
1993
    public function testGetDisplayValueForForeignTableColumn(): void
1994
    {
1995
        $map = [];
1996
        $map['f']['foreign_db'] = 'information_schema';
1997
        $map['f']['foreign_table'] = 'TABLES';
1998
        $map['f']['foreign_field'] = 'f';
1999
2000
        $dbi = $this->getMockBuilder(DatabaseInterface::class)
2001
            ->disableOriginalConstructor()
2002
            ->getMock();
2003
2004
        $dbi->expects($this->once())
2005
            ->method('tryQuery')
2006
            ->with(
2007
                'SELECT `TABLE_COMMENT` FROM `information_schema`.`TABLES` WHERE '
2008
                . '`f`=1',
2009
                DatabaseInterface::CONNECT_USER,
2010
                DatabaseInterface::QUERY_STORE
2011
            )
2012
            ->will($this->returnValue('r1'));
2013
2014
        $dbi->expects($this->once())
2015
            ->method('numRows')
2016
            ->with('r1')
2017
            ->will($this->returnValue('2'));
2018
2019
        $dbi->expects($this->once())
2020
            ->method('fetchRow')
2021
            ->with('r1')
2022
            ->will($this->returnValue(['2']));
2023
2024
        $GLOBALS['dbi'] = $dbi;
2025
        $this->insertEdit = new InsertEdit($GLOBALS['dbi']);
2026
2027
        $result = $this->insertEdit->getDisplayValueForForeignTableColumn('=1', $map, 'f');
2028
2029
        $this->assertEquals(2, $result);
2030
    }
2031
2032
    /**
2033
     * Test for getLinkForRelationalDisplayField
2034
     */
2035
    public function testGetLinkForRelationalDisplayField(): void
2036
    {
2037
        $GLOBALS['cfg']['ServerDefault'] = 1;
2038
        $_SESSION['tmpval']['relational_display'] = 'K';
2039
        $map = [];
2040
        $map['f']['foreign_db'] = 'information_schema';
2041
        $map['f']['foreign_table'] = 'TABLES';
2042
        $map['f']['foreign_field'] = 'f';
2043
2044
        $result = $this->insertEdit->getLinkForRelationalDisplayField($map, 'f', '=1', 'a>', 'b<');
2045
2046
        $sqlSignature = Core::signSqlQuery(
2047
            'SELECT * FROM `information_schema`.`TABLES` WHERE `f`=1'
2048
        );
2049
2050
        $this->assertEquals(
2051
            '<a href="index.php?route=/sql&db=information_schema&table=TABLES&pos=0&'
2052
            . 'sql_signature=' . $sqlSignature . '&'
2053
            . 'sql_query=SELECT+%2A+FROM+%60information_schema%60.%60TABLES%60+WHERE'
2054
            . '+%60f%60%3D1&lang=en" title="a&gt;">b&lt;</a>',
2055
            $result
2056
        );
2057
2058
        $_SESSION['tmpval']['relational_display'] = 'D';
2059
        $result = $this->insertEdit->getLinkForRelationalDisplayField($map, 'f', '=1', 'a>', 'b<');
2060
2061
        $this->assertEquals(
2062
            '<a href="index.php?route=/sql&db=information_schema&table=TABLES&pos=0&'
2063
            . 'sql_signature=' . $sqlSignature . '&'
2064
            . 'sql_query=SELECT+%2A+FROM+%60information_schema%60.%60TABLES%60+WHERE'
2065
            . '+%60f%60%3D1&lang=en" title="b&lt;">a&gt;</a>',
2066
            $result
2067
        );
2068
    }
2069
2070
    /**
2071
     * Test for transformEditedValues
2072
     */
2073
    public function testTransformEditedValues(): void
2074
    {
2075
        $_SESSION[' HMAC_secret '] = hash('sha1', 'test');
2076
        $edited_values = [
2077
            ['c' => 'cname'],
2078
        ];
2079
        $GLOBALS['cfg']['DefaultTransformations']['PreApPend'] = [
2080
            '',
2081
            '',
2082
        ];
2083
        $GLOBALS['cfg']['ServerDefault'] = 1;
2084
        $_POST['where_clause'] = '1';
2085
        $_POST['where_clause_sign'] = Core::signSqlQuery($_POST['where_clause']);
2086
        $transformation = ['transformation_options' => "'','option ,, quoted',abd"];
2087
        $result = $this->insertEdit->transformEditedValues(
2088
            'db',
2089
            'table',
2090
            $transformation,
2091
            $edited_values,
2092
            'Text_Plain_PreApPend.php',
2093
            'c',
2094
            ['a' => 'b'],
2095
            'transformation'
2096
        );
2097
2098
        $this->assertEquals(
2099
            [
2100
                'a' => 'b',
2101
                'transformations' => ['cnameoption ,, quoted'],
2102
            ],
2103
            $result
2104
        );
2105
    }
2106
2107
    /**
2108
     * Test for getQueryValuesForInsertAndUpdateInMultipleEdit
2109
     */
2110
    public function testGetQueryValuesForInsertAndUpdateInMultipleEdit(): void
2111
    {
2112
        $multi_edit_columns_name = ['0' => 'fld'];
2113
2114
        $result = $this->insertEdit->getQueryValuesForInsertAndUpdateInMultipleEdit(
2115
            $multi_edit_columns_name,
2116
            [],
2117
            '',
2118
            [],
2119
            [],
2120
            true,
2121
            [1],
2122
            [2],
2123
            'foo',
2124
            [],
2125
            '0',
2126
            []
2127
        );
2128
2129
        $this->assertEquals(
2130
            [
2131
                [
2132
                    1,
2133
                    'foo',
2134
                ],
2135
                [
2136
                    2,
2137
                    '`fld`',
2138
                ],
2139
            ],
2140
            $result
2141
        );
2142
2143
        $result = $this->insertEdit->getQueryValuesForInsertAndUpdateInMultipleEdit(
2144
            $multi_edit_columns_name,
2145
            [],
2146
            '',
2147
            [],
2148
            [],
2149
            false,
2150
            [1],
2151
            [2],
2152
            'foo',
2153
            [],
2154
            '0',
2155
            ['a']
2156
        );
2157
2158
        $this->assertEquals(
2159
            [
2160
                [
2161
                    1,
2162
                    '`fld` = foo',
2163
                ],
2164
                [2],
2165
            ],
2166
            $result
2167
        );
2168
2169
        $result = $this->insertEdit->getQueryValuesForInsertAndUpdateInMultipleEdit(
2170
            $multi_edit_columns_name,
2171
            ['b'],
2172
            "'`c`'",
2173
            ['c'],
2174
            [],
2175
            false,
2176
            [1],
2177
            [2],
2178
            'foo',
2179
            [],
2180
            '0',
2181
            ['a']
2182
        );
2183
2184
        $this->assertEquals(
2185
            [
2186
                [1],
2187
                [2],
2188
            ],
2189
            $result
2190
        );
2191
2192
        $result = $this->insertEdit->getQueryValuesForInsertAndUpdateInMultipleEdit(
2193
            $multi_edit_columns_name,
2194
            ['b'],
2195
            "'`c`'",
2196
            ['c'],
2197
            [3],
2198
            false,
2199
            [1],
2200
            [2],
2201
            'foo',
2202
            [],
2203
            0,
2204
            []
2205
        );
2206
2207
        $this->assertEquals(
2208
            [
2209
                [
2210
                    1,
2211
                    '`fld` = foo',
2212
                ],
2213
                [2],
2214
            ],
2215
            $result
2216
        );
2217
    }
2218
2219
    /**
2220
     * Test for getCurrentValueAsAnArrayForMultipleEdit
2221
     */
2222
    public function testGetCurrentValueAsAnArrayForMultipleEdit(): void
2223
    {
2224
        $result = $this->insertEdit->getCurrentValueAsAnArrayForMultipleEdit(
2225
            [],
2226
            [],
2227
            [],
2228
            'currVal',
2229
            [],
2230
            [],
2231
            [],
2232
            '0'
2233
        );
2234
2235
        $this->assertEquals('currVal', $result);
2236
2237
        // case 2
2238
        $multi_edit_funcs = ['UUID'];
2239
2240
        $dbi = $this->getMockBuilder(DatabaseInterface::class)
2241
            ->disableOriginalConstructor()
2242
            ->getMock();
2243
2244
        $dbi->expects($this->once())
2245
            ->method('fetchValue')
2246
            ->with('SELECT UUID()')
2247
            ->will($this->returnValue('uuid1234'));
2248
2249
        $GLOBALS['dbi'] = $dbi;
2250
        $this->insertEdit = new InsertEdit($GLOBALS['dbi']);
2251
2252
        $result = $this->insertEdit->getCurrentValueAsAnArrayForMultipleEdit(
2253
            $multi_edit_funcs,
2254
            [],
2255
            [],
2256
            'currVal',
2257
            [],
2258
            [],
2259
            [],
2260
            '0'
2261
        );
2262
2263
        $this->assertEquals("'uuid1234'", $result);
2264
2265
        // case 3
2266
        $multi_edit_funcs = ['AES_ENCRYPT'];
2267
        $multi_edit_salt = [''];
2268
        $result = $this->insertEdit->getCurrentValueAsAnArrayForMultipleEdit(
2269
            $multi_edit_funcs,
2270
            $multi_edit_salt,
2271
            [],
2272
            "'''",
2273
            [],
2274
            ['func'],
2275
            ['func'],
2276
            '0'
2277
        );
2278
        $this->assertEquals("AES_ENCRYPT(''','')", $result);
2279
2280
        // case 4
2281
        $multi_edit_funcs = ['func'];
2282
        $multi_edit_salt = [];
2283
        $result = $this->insertEdit->getCurrentValueAsAnArrayForMultipleEdit(
2284
            $multi_edit_funcs,
2285
            $multi_edit_salt,
2286
            [],
2287
            "'''",
2288
            [],
2289
            ['func'],
2290
            ['func'],
2291
            '0'
2292
        );
2293
        $this->assertEquals("func(''')", $result);
2294
2295
        // case 5
2296
        $result = $this->insertEdit->getCurrentValueAsAnArrayForMultipleEdit(
2297
            $multi_edit_funcs,
2298
            $multi_edit_salt,
2299
            [],
2300
            "''",
2301
            [],
2302
            ['func'],
2303
            ['func'],
2304
            '0'
2305
        );
2306
        $this->assertEquals('func()', $result);
2307
    }
2308
2309
    /**
2310
     * Test for getCurrentValueForDifferentTypes
2311
     */
2312
    public function testGetCurrentValueForDifferentTypes(): void
2313
    {
2314
        $this->insertEdit = new InsertEdit($GLOBALS['dbi']);
2315
2316
        $result = $this->insertEdit->getCurrentValueForDifferentTypes(
2317
            '123',
2318
            '0',
2319
            [],
2320
            '',
2321
            [],
2322
            0,
2323
            [],
2324
            [],
2325
            [],
2326
            true,
2327
            true,
2328
            '',
2329
            'test_table',
2330
            []
2331
        );
2332
2333
        $this->assertEquals(
2334
            '123',
2335
            $result
2336
        );
2337
2338
        // case 2
2339
        $result = $this->insertEdit->getCurrentValueForDifferentTypes(
2340
            false,
2341
            '0',
2342
            ['test'],
2343
            '',
2344
            [1],
2345
            0,
2346
            [],
2347
            [],
2348
            [],
2349
            true,
2350
            true,
2351
            '',
2352
            'test_table',
2353
            []
2354
        );
2355
2356
        $this->assertEquals(
2357
            'NULL',
2358
            $result
2359
        );
2360
2361
        // case 3
2362
        $result = $this->insertEdit->getCurrentValueForDifferentTypes(
2363
            false,
2364
            '0',
2365
            ['test'],
2366
            '',
2367
            [],
2368
            0,
2369
            [],
2370
            [],
2371
            [],
2372
            true,
2373
            true,
2374
            '',
2375
            'test_table',
2376
            []
2377
        );
2378
2379
        $this->assertEquals(
2380
            "''",
2381
            $result
2382
        );
2383
2384
        // case 4
2385
        $_POST['fields']['multi_edit'][0][0] = [];
2386
        $result = $this->insertEdit->getCurrentValueForDifferentTypes(
2387
            false,
2388
            '0',
2389
            ['set'],
2390
            '',
2391
            [],
2392
            0,
2393
            [],
2394
            [],
2395
            [],
2396
            true,
2397
            true,
2398
            '',
2399
            'test_table',
2400
            []
2401
        );
2402
2403
        $this->assertEquals(
2404
            "''",
2405
            $result
2406
        );
2407
2408
        // case 5
2409
        $result = $this->insertEdit->getCurrentValueForDifferentTypes(
2410
            false,
2411
            '0',
2412
            ['protected'],
2413
            '',
2414
            [],
2415
            0,
2416
            ['name'],
2417
            [],
2418
            [],
2419
            true,
2420
            true,
2421
            '`id` = 4',
2422
            'test_table',
2423
            []
2424
        );
2425
2426
        $this->assertEquals(
2427
            '0x313031',
2428
            $result
2429
        );
2430
2431
        // case 6
2432
        $result = $this->insertEdit->getCurrentValueForDifferentTypes(
2433
            false,
2434
            '0',
2435
            ['protected'],
2436
            '',
2437
            [],
2438
            0,
2439
            ['a'],
2440
            [],
2441
            [],
2442
            true,
2443
            true,
2444
            '',
2445
            'test_table',
2446
            []
2447
        );
2448
2449
        $this->assertEquals(
2450
            '',
2451
            $result
2452
        );
2453
2454
        // case 7
2455
        $result = $this->insertEdit->getCurrentValueForDifferentTypes(
2456
            false,
2457
            '0',
2458
            ['bit'],
2459
            '20\'12',
2460
            [],
2461
            0,
2462
            ['a'],
2463
            [],
2464
            [],
2465
            true,
2466
            true,
2467
            '',
2468
            'test_table',
2469
            []
2470
        );
2471
2472
        $this->assertEquals(
2473
            "b'00010'",
2474
            $result
2475
        );
2476
2477
        // case 7
2478
        $result = $this->insertEdit->getCurrentValueForDifferentTypes(
2479
            false,
2480
            '0',
2481
            ['date'],
2482
            '20\'12',
2483
            [],
2484
            0,
2485
            ['a'],
2486
            [],
2487
            [],
2488
            true,
2489
            true,
2490
            '',
2491
            'test_table',
2492
            []
2493
        );
2494
2495
        $this->assertEquals(
2496
            "'20\\'12'",
2497
            $result
2498
        );
2499
2500
        // case 8
2501
        $_POST['fields']['multi_edit'][0][0] = [];
2502
        $result = $this->insertEdit->getCurrentValueForDifferentTypes(
2503
            false,
2504
            '0',
2505
            ['set'],
2506
            '',
2507
            [],
2508
            0,
2509
            [],
2510
            [1],
2511
            [],
2512
            true,
2513
            true,
2514
            '',
2515
            'test_table',
2516
            []
2517
        );
2518
2519
        $this->assertEquals(
2520
            'NULL',
2521
            $result
2522
        );
2523
2524
        // case 9
2525
        $result = $this->insertEdit->getCurrentValueForDifferentTypes(
2526
            false,
2527
            '0',
2528
            ['protected'],
2529
            '',
2530
            [],
2531
            0,
2532
            ['a'],
2533
            [],
2534
            [1],
2535
            true,
2536
            true,
2537
            '',
2538
            'test_table',
2539
            []
2540
        );
2541
2542
        $this->assertEquals(
2543
            "''",
2544
            $result
2545
        );
2546
    }
2547
2548
    /**
2549
     * Test for verifyWhetherValueCanBeTruncatedAndAppendExtraData
2550
     */
2551
    public function testVerifyWhetherValueCanBeTruncatedAndAppendExtraData(): void
2552
    {
2553
        $extra_data = ['isNeedToRecheck' => true];
2554
2555
        $_POST['where_clause'] = [];
2556
        $_POST['where_clause'][0] = 1;
2557
2558
        $dbi = $this->getMockBuilder(DatabaseInterface::class)
2559
            ->disableOriginalConstructor()
2560
            ->getMock();
2561
2562
        $dbi->expects($this->exactly(3))
2563
            ->method('tryQuery')
2564
            ->with('SELECT `table`.`a` FROM `db`.`table` WHERE 1');
2565
2566
        $meta1 = new FieldMetadata(MYSQLI_TYPE_TINY, 0, (object) []);
2567
        $meta2 = new FieldMetadata(MYSQLI_TYPE_TINY, 0, (object) []);
2568
        $meta3 = new FieldMetadata(MYSQLI_TYPE_TIMESTAMP, 0, (object) []);
2569
        $dbi->expects($this->exactly(3))
2570
            ->method('getFieldsMeta')
2571
            ->will($this->onConsecutiveCalls([$meta1], [$meta2], [$meta3]));
2572
2573
        $dbi->expects($this->exactly(3))
2574
            ->method('fetchRow')
2575
            ->will($this->onConsecutiveCalls(null, [0 => '123'], [0 => '2013-08-28 06:34:14']));
2576
2577
        $dbi->expects($this->exactly(3))
2578
            ->method('freeResult');
2579
2580
        $GLOBALS['dbi'] = $dbi;
2581
        $this->insertEdit = new InsertEdit($GLOBALS['dbi']);
2582
2583
        $this->insertEdit->verifyWhetherValueCanBeTruncatedAndAppendExtraData(
2584
            'db',
2585
            'table',
2586
            'a',
2587
            $extra_data
2588
        );
2589
2590
        $this->assertFalse($extra_data['isNeedToRecheck']);
2591
2592
        $this->insertEdit->verifyWhetherValueCanBeTruncatedAndAppendExtraData(
2593
            'db',
2594
            'table',
2595
            'a',
2596
            $extra_data
2597
        );
2598
2599
        $this->assertEquals('123', $extra_data['truncatableFieldValue']);
2600
        $this->assertTrue($extra_data['isNeedToRecheck']);
2601
2602
        $this->insertEdit->verifyWhetherValueCanBeTruncatedAndAppendExtraData(
2603
            'db',
2604
            'table',
2605
            'a',
2606
            $extra_data
2607
        );
2608
2609
        $this->assertEquals(
2610
            '2013-08-28 06:34:14.000000',
2611
            $extra_data['truncatableFieldValue']
2612
        );
2613
        $this->assertTrue($extra_data['isNeedToRecheck']);
2614
    }
2615
2616
    /**
2617
     * Test for getTableColumns
2618
     */
2619
    public function testGetTableColumns(): void
2620
    {
2621
        $dbi = $this->getMockBuilder(DatabaseInterface::class)
2622
            ->disableOriginalConstructor()
2623
            ->getMock();
2624
2625
        $dbi->expects($this->once())
2626
            ->method('selectDb')
2627
            ->with('db');
2628
2629
        $dbi->expects($this->once())
2630
            ->method('getColumns')
2631
            ->with('db', 'table')
2632
            ->will($this->returnValue(['a' => 'b', 'c' => 'd']));
2633
2634
        $GLOBALS['dbi'] = $dbi;
2635
        $this->insertEdit = new InsertEdit($GLOBALS['dbi']);
2636
2637
        $result = $this->insertEdit->getTableColumns('db', 'table');
2638
2639
        $this->assertEquals(
2640
            [
2641
                'b',
2642
                'd',
2643
            ],
2644
            $result
2645
        );
2646
    }
2647
2648
    /**
2649
     * Test for determineInsertOrEdit
2650
     */
2651
    public function testDetermineInsertOrEdit(): void
2652
    {
2653
        $dbi = $this->getMockBuilder(DatabaseInterface::class)
2654
            ->disableOriginalConstructor()
2655
            ->getMock();
2656
2657
        $GLOBALS['dbi'] = $dbi;
2658
        $_POST['where_clause'] = '1';
2659
        $_SESSION['edit_next'] = '1';
2660
        $_POST['ShowFunctionFields'] = true;
2661
        $_POST['ShowFieldTypesInDataEditView'] = true;
2662
        $_POST['after_insert'] = 'edit_next';
2663
        $GLOBALS['cfg']['InsertRows'] = 2;
2664
        $GLOBALS['cfg']['ShowSQL'] = false;
2665
        $_POST['default_action'] = 'insert';
2666
2667
        $responseMock = $this->getMockBuilder(Response::class)
2668
            ->disableOriginalConstructor()
2669
            ->onlyMethods(['addHtml'])
2670
            ->getMock();
2671
2672
        $restoreInstance = Response::getInstance();
2673
        $response = new ReflectionProperty(Response::class, 'instance');
2674
        $response->setAccessible(true);
2675
        $response->setValue($responseMock);
2676
2677
        $this->insertEdit = new InsertEdit($GLOBALS['dbi']);
2678
2679
        $result = $this->insertEdit->determineInsertOrEdit('1', 'db', 'table');
2680
2681
        $this->assertEquals(
2682
            [
2683
                false,
2684
                null,
2685
                [1],
2686
                null,
2687
                [null],
2688
                [null],
2689
                false,
2690
                'edit_next',
2691
            ],
2692
            $result
2693
        );
2694
2695
        // case 2
2696
        unset($_POST['where_clause']);
2697
        unset($_SESSION['edit_next']);
2698
        $_POST['default_action'] = '';
2699
2700
        $result = $this->insertEdit->determineInsertOrEdit(null, 'db', 'table');
2701
2702
        $response->setValue($restoreInstance);
2703
2704
        $this->assertEquals(
2705
            [
2706
                true,
2707
                null,
2708
                [],
2709
                null,
2710
                null,
2711
                [
2712
                    false,
2713
                    false,
2714
                ],
2715
                false,
2716
                'edit_next',
2717
            ],
2718
            $result
2719
        );
2720
    }
2721
2722
    /**
2723
     * Test for getCommentsMap
2724
     */
2725
    public function testGetCommentsMap(): void
2726
    {
2727
        $GLOBALS['cfg']['ShowPropertyComments'] = false;
2728
2729
        $dbi = $this->getMockBuilder(DatabaseInterface::class)
2730
            ->disableOriginalConstructor()
2731
            ->getMock();
2732
2733
        $dbi->expects($this->once())
2734
            ->method('getColumns')
2735
            ->with('db', 'table', null, true)
2736
            ->will(
2737
                $this->returnValue(
2738
                    [
2739
                        [
2740
                            'Comment' => 'b',
2741
                            'Field' => 'd',
2742
                        ],
2743
                    ]
2744
                )
2745
            );
2746
2747
        $dbi->expects($this->any())
2748
            ->method('getTable')
2749
            ->will(
2750
                $this->returnValue(
2751
                    new Table('table', 'db')
2752
                )
2753
            );
2754
2755
        $GLOBALS['dbi'] = $dbi;
2756
        $this->insertEdit = new InsertEdit($GLOBALS['dbi']);
2757
2758
        $this->assertEquals(
2759
            [],
2760
            $this->insertEdit->getCommentsMap('db', 'table')
2761
        );
2762
2763
        $GLOBALS['cfg']['ShowPropertyComments'] = true;
2764
2765
        $this->assertEquals(
2766
            ['d' => 'b'],
2767
            $this->insertEdit->getCommentsMap('db', 'table')
2768
        );
2769
    }
2770
2771
    /**
2772
     * Test for getUrlParameters
2773
     */
2774
    public function testGetUrlParameters(): void
2775
    {
2776
        global $goto;
2777
2778
        $_POST['sql_query'] = 'SELECT';
2779
        $goto = 'tbl_sql.php';
2780
2781
        $this->assertEquals(
2782
            [
2783
                'db' => 'foo',
2784
                'sql_query' => 'SELECT',
2785
                'table' => 'bar',
2786
            ],
2787
            $this->insertEdit->getUrlParameters('foo', 'bar')
2788
        );
2789
    }
2790
2791
    /**
2792
     * Test for getHtmlForIgnoreOption
2793
     */
2794
    public function testGetHtmlForIgnoreOption(): void
2795
    {
2796
        $expected = '<input type="checkbox" %sname="insert_ignore_1"'
2797
            . ' id="insert_ignore_1"><label for="insert_ignore_1">'
2798
            . 'Ignore</label><br>' . "\n";
2799
        $checked = 'checked="checked" ';
2800
        $this->assertEquals(
2801
            sprintf($expected, $checked),
2802
            $this->insertEdit->getHtmlForIgnoreOption(1)
2803
        );
2804
2805
        $this->assertEquals(
2806
            sprintf($expected, ''),
2807
            $this->insertEdit->getHtmlForIgnoreOption(1, false)
2808
        );
2809
    }
2810
2811
    /**
2812
     * Test for getHtmlForInsertEditFormColumn
2813
     */
2814
    public function testGetHtmlForInsertEditFormColumn(): void
2815
    {
2816
        $_SESSION[' HMAC_secret '] = hash('sha1', 'test');
2817
        $o_rows = 0;
2818
        $tabindex = 0;
2819
        $GLOBALS['plugin_scripts'] = [];
2820
        $foreigners = ['foreign_keys_data' => []];
2821
        $table_columns = [
2822
            [
2823
                'Field' => 'col',
2824
                'Type' => 'varchar(20)',
2825
                'Null' => 'Yes',
2826
                'Privileges' => 'insert,update,select',
2827
            ],
2828
        ];
2829
        $repopulate = [md5('col') => 'val'];
2830
        $column_mime = [
2831
            'input_transformation' => 'Input/Image_JPEG_Upload.php',
2832
            'input_transformation_options' => '150',
2833
        ];
2834
2835
        // Test w/ input transformation
2836
        $actual = $this->callFunction(
2837
            $this->insertEdit,
2838
            InsertEdit::class,
2839
            'getHtmlForInsertEditFormColumn',
2840
            [
2841
                $table_columns,
2842
                0,
2843
                [],
2844
                false,
2845
                [],
2846
                '',
2847
                '',
2848
                '',
2849
                false,
2850
                [],
2851
                &$o_rows,
2852
                &$tabindex,
2853
                0,
2854
                false,
2855
                $foreigners,
2856
                0,
2857
                'table',
2858
                'db',
2859
                0,
2860
                0,
2861
                '',
2862
                '',
2863
                $repopulate,
2864
                $column_mime,
2865
                '',
2866
            ]
2867
        );
2868
2869
        $this->assertStringContainsString(
2870
            'col',
2871
            $actual
2872
        );
2873
        $this->assertStringContainsString(
2874
            '<option>AES_ENCRYPT</option>',
2875
            $actual
2876
        );
2877
        $this->assertStringContainsString(
2878
            '<span class="column_type" dir="ltr">varchar(20)</span>',
2879
            $actual
2880
        );
2881
        $this->assertStringContainsString(
2882
            '<tr class="noclick">',
2883
            $actual
2884
        );
2885
        $this->assertStringContainsString(
2886
            '<span class="default_value hide">',
2887
            $actual
2888
        );
2889
        $this->assertStringContainsString(
2890
            '<img src="" width="150" height="100" '
2891
            . 'alt="Image preview here">',
2892
            $actual
2893
        );
2894
        $this->assertStringContainsString(
2895
            '<input type="file" '
2896
            . 'name="fields_upload[d89e2ddb530bb8953b290ab0793aecb0]" '
2897
            . 'accept="image/*" '
2898
            . 'class="image-upload"'
2899
            . '>',
2900
            $actual
2901
        );
2902
2903
        // Test w/o input_transformation
2904
        $table_columns = [
2905
            [
2906
                'Field' => 'qwerty',
2907
                'Type' => 'datetime',
2908
                'Null' => 'Yes',
2909
                'Key' => '',
2910
                'Extra' => '',
2911
                'Default' => null,
2912
                'Privileges' => 'insert,update,select',
2913
            ],
2914
        ];
2915
        $repopulate = [md5('qwerty') => '12-10-14'];
2916
        $actual = $this->callFunction(
2917
            $this->insertEdit,
2918
            InsertEdit::class,
2919
            'getHtmlForInsertEditFormColumn',
2920
            [
2921
                $table_columns,
2922
                0,
2923
                [],
2924
                false,
2925
                [],
2926
                '',
2927
                '',
2928
                '[a][0]',
2929
                true,
2930
                [],
2931
                &$o_rows,
2932
                &$tabindex,
2933
                0,
2934
                false,
2935
                $foreigners,
2936
                0,
2937
                'table',
2938
                'db',
2939
                0,
2940
                0,
2941
                '',
2942
                '',
2943
                $repopulate,
2944
                [],
2945
                '',
2946
            ]
2947
        );
2948
        $this->assertStringContainsString('qwerty', $actual);
2949
        $this->assertStringContainsString('<option>UUID</option>', $actual);
2950
        $this->assertStringContainsString('<span class="column_type" dir="ltr">datetime</span>', $actual);
2951
        $this->assertStringContainsString(
2952
            '<input type="text" '
2953
            . 'name="fields[a][0][d8578edf8458ce06fbc5bb76a58c5ca4]" '
2954
            . 'value="12-10-14.000000"',
2955
            $actual
2956
        );
2957
2958
        $this->assertStringContainsString(
2959
            '<select name="funcs[multi_edit][0][d8578edf8458ce06fbc5bb76a58c5ca4]"'
2960
            . ' onchange="return verificationsAfterFieldChange(\'d8578edf8458ce06fbc5bb76a58c5ca4\','
2961
            . ' \'0\', \'datetime\')" id="field_1_1">',
2962
            $actual
2963
        );
2964
        $this->assertStringContainsString('<option>DATE</option>', $actual);
2965
2966
        $this->assertStringContainsString(
2967
            '<input type="hidden" name="fields_null_prev[multi_edit][0][d8578edf8458ce06fbc5bb76a58c5ca4]">',
2968
            $actual
2969
        );
2970
2971
        $this->assertStringContainsString(
2972
            '<input type="checkbox" class="checkbox_null"'
2973
            . ' name="fields_null[multi_edit][0][d8578edf8458ce06fbc5bb76a58c5ca4]" id="field_1_2"'
2974
            . ' aria-label="Use the NULL value for this column.">',
2975
            $actual
2976
        );
2977
2978
        $this->assertStringContainsString(
2979
            '<input type="hidden" class="nullify_code"'
2980
            . ' name="nullify_code[multi_edit][0][d8578edf8458ce06fbc5bb76a58c5ca4]" value="5"',
2981
            $actual
2982
        );
2983
2984
        $this->assertStringContainsString(
2985
            '<input type="hidden" class="hashed_field"'
2986
            . ' name="hashed_field[multi_edit][0][d8578edf8458ce06fbc5bb76a58c5ca4]" '
2987
            . 'value="d8578edf8458ce06fbc5bb76a58c5ca4">',
2988
            $actual
2989
        );
2990
2991
        $this->assertStringContainsString(
2992
            '<input type="hidden" class="multi_edit"'
2993
            . ' name="multi_edit[multi_edit][0][d8578edf8458ce06fbc5bb76a58c5ca4]" value="[multi_edit][0]"',
2994
            $actual
2995
        );
2996
    }
2997
2998
    /**
2999
     * Test for getHtmlForInsertEditRow
3000
     */
3001
    public function testGetHtmlForInsertEditRow(): void
3002
    {
3003
        $o_rows = 0;
3004
        $tabindex = 0;
3005
        $GLOBALS['plugin_scripts'] = [];
3006
        $GLOBALS['cfg']['LongtextDoubleTextarea'] = true;
3007
        $GLOBALS['cfg']['CharEditing'] = true;
3008
        $GLOBALS['cfg']['TextareaRows'] = 10;
3009
        $GLOBALS['cfg']['TextareaCols'] = 11;
3010
        $foreigners = ['foreign_keys_data' => []];
3011
        $table_columns = [
3012
            [
3013
                'Field' => 'test',
3014
                'Extra' => '',
3015
                'Type' => 'longtext',
3016
                'Null' => 'Yes',
3017
                'pma_type' => 'longtext',
3018
                'True_Type' => 'longtext',
3019
                'Privileges' => 'select,insert,update,references',
3020
            ],
3021
        ];
3022
        $actual = $this->insertEdit->getHtmlForInsertEditRow(
3023
            [],
3024
            $table_columns,
3025
            [],
3026
            false,
3027
            [],
3028
            '',
3029
            '',
3030
            '',
3031
            false,
3032
            [],
3033
            $o_rows,
3034
            $tabindex,
3035
            1,
3036
            false,
3037
            $foreigners,
3038
            0,
3039
            'table',
3040
            'db',
3041
            0,
3042
            0,
3043
            'ltr',
3044
            [],
3045
            ['wc']
3046
        );
3047
        $this->assertStringContainsString(
3048
            'test',
3049
            $actual
3050
        );
3051
        $this->assertStringContainsString(
3052
            '<th>Column</th>',
3053
            $actual
3054
        );
3055
        $this->assertStringContainsString(
3056
            '<a',
3057
            $actual
3058
        );
3059
        $this->assertStringContainsString(
3060
            '<th class="w-50">Value</th>',
3061
            $actual
3062
        );
3063
        $this->assertStringContainsString(
3064
            '<span class="column_type" dir="ltr">longtext</span>',
3065
            $actual
3066
        );
3067
        $this->assertStringContainsString(
3068
            '<textarea name="fields[multi_edit][0][098f6bcd4621d373cade4e832627b4f6]" id="field_1_3"'
3069
                . ' data-type="CHAR" dir="ltr" rows="20" cols="22"',
3070
            $actual
3071
        );
3072
    }
3073
3074
    /**
3075
     * Test for getHtmlForInsertEditRow based on the column privilges
3076
     */
3077
    public function testGetHtmlForInsertEditRowBasedOnColumnPrivileges(): void
3078
    {
3079
        $o_rows = 0;
3080
        $tabindex = 0;
3081
        $GLOBALS['plugin_scripts'] = [];
3082
        $GLOBALS['cfg']['LongtextDoubleTextarea'] = true;
3083
        $GLOBALS['cfg']['CharEditing'] = true;
3084
        $foreigners = ['foreign_keys_data' => []];
3085
3086
        // edit
3087
        $table_columns = [
3088
            [
3089
                'Field' => 'foo',
3090
                'Type' => 'longtext',
3091
                'Extra' => '',
3092
                'Null' => 'Yes',
3093
                'pma_type' => 'longtext',
3094
                'True_Type' => 'longtext',
3095
                'Privileges' => 'select,insert,update,references',
3096
            ],
3097
            [
3098
                'Field' => 'bar',
3099
                'Type' => 'longtext',
3100
                'Extra' => '',
3101
                'Null' => 'Yes',
3102
                'pma_type' => 'longtext',
3103
                'True_Type' => 'longtext',
3104
                'Privileges' => 'select,insert,references',
3105
            ],
3106
        ];
3107
        $actual = $this->insertEdit->getHtmlForInsertEditRow(
3108
            [],
3109
            $table_columns,
3110
            [],
3111
            false,
3112
            [],
3113
            '',
3114
            '',
3115
            '',
3116
            false,
3117
            [],
3118
            $o_rows,
3119
            $tabindex,
3120
            1,
3121
            false,
3122
            $foreigners,
3123
            0,
3124
            'table',
3125
            'db',
3126
            0,
3127
            0,
3128
            '',
3129
            [],
3130
            ['wc']
3131
        );
3132
        $this->assertStringContainsString(
3133
            'foo',
3134
            $actual
3135
        );
3136
        $this->assertStringNotContainsString(
3137
            'bar',
3138
            $actual
3139
        );
3140
3141
        // insert
3142
        $table_columns = [
3143
            [
3144
                'Field' => 'foo',
3145
                'Type' => 'longtext',
3146
                'Extra' => '',
3147
                'Null' => 'Yes',
3148
                'Key' => '',
3149
                'pma_type' => 'longtext',
3150
                'True_Type' => 'longtext',
3151
                'Privileges' => 'select,insert,update,references',
3152
            ],
3153
            [
3154
                'Field' => 'bar',
3155
                'Type' => 'longtext',
3156
                'Extra' => '',
3157
                'Null' => 'Yes',
3158
                'Key' => '',
3159
                'pma_type' => 'longtext',
3160
                'True_Type' => 'longtext',
3161
                'Privileges' => 'select,update,references',
3162
            ],
3163
            [
3164
                'Field' => 'point',
3165
                'Type' => 'point',
3166
                'Extra' => '',
3167
                'Null' => 'No',
3168
                'Key' => '',
3169
                'pma_type' => 'point',
3170
                'True_Type' => 'point',
3171
                'Privileges' => 'select,update,references',
3172
            ],
3173
        ];
3174
        $actual = $this->insertEdit->getHtmlForInsertEditRow(
3175
            [],
3176
            $table_columns,
3177
            [],
3178
            false,
3179
            [],
3180
            '',
3181
            '',
3182
            '',
3183
            true,
3184
            [],
3185
            $o_rows,
3186
            $tabindex,
3187
            3,
3188
            false,
3189
            $foreigners,
3190
            0,
3191
            'table',
3192
            'db',
3193
            0,
3194
            0,
3195
            '',
3196
            [],
3197
            ['wc']
3198
        );
3199
        $this->assertStringContainsString(
3200
            'foo',
3201
            $actual
3202
        );
3203
        $this->assertStringContainsString(
3204
            '<textarea name="fields[multi_edit][0][37b51d194a7513e45b56f6524f2d51f2]"',
3205
            $actual
3206
        );
3207
        $this->assertStringContainsString(
3208
            '<a href="#" target="_blank"><span class="text-nowrap"><img src="themes/dot.'
3209
            . 'gif" title="Edit/Insert" alt="Edit/Insert" class="icon ic_b_edit">&nbsp;Edit/Insert'
3210
            . '</span></a>',
3211
            $actual
3212
        );
3213
    }
3214
}
3215