packages/ztd-query-mysqli-adapter/tests/Integration/MysqliFullTextSearchTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Integration;
6
7use Container\MySql80Container;
8use Container\MySql84Container;
9use mysqli;
10use mysqli_result;
11use PHPUnit\Framework\Attributes\Large;
12use PHPUnit\Framework\TestCase;
13use Testcontainers\Testcontainers;
14use ZtdQuery\Adapter\Mysqli\ZtdMysqli;
15
16#[\PHPUnit\Framework\Attributes\CoversClass(ZtdMysqli::class)]
17#[\PHPUnit\Framework\Attributes\CoversClass(\ZtdQuery\Adapter\Mysqli\Session\ConnectionExecution::class)]
18#[\PHPUnit\Framework\Attributes\CoversClass(\ZtdQuery\Adapter\Mysqli\ZtdMysqliStatement::class)]
19#[\PHPUnit\Framework\Attributes\CoversClass(\ZtdQuery\Adapter\Mysqli\Session\StatementExecution::class)]
20#[\PHPUnit\Framework\Attributes\CoversClass(\ZtdQuery\Adapter\Mysqli\Driver\MysqliConnection::class)]
21#[\PHPUnit\Framework\Attributes\CoversClass(\ZtdQuery\Adapter\Mysqli\Driver\MysqliResultStatement::class)]
22#[\PHPUnit\Framework\Attributes\CoversClass(\ZtdQuery\Adapter\Mysqli\Driver\MysqliResultColumnExtractor::class)]
23#[\PHPUnit\Framework\Attributes\CoversClass(\ZtdQuery\Adapter\Mysqli\Native\MysqliStatementBindingBridge::class)]
24#[\PHPUnit\Framework\Attributes\CoversClass(\ZtdQuery\Adapter\Mysqli\ZtdMysqliException::class)]
25#[\PHPUnit\Framework\Attributes\CoversClass(\ZtdQuery\Adapter\Mysqli\Native\MysqliPropertyReader::class)]
26#[\PHPUnit\Framework\Attributes\CoversClass(\ZtdQuery\Adapter\Mysqli\Session\MysqliResultProcessor::class)]
27#[Large]
28final class MysqliFullTextSearchTest extends TestCase
29{
30    public function testMatchAgainstReadsOnlyShadowRows(): void
31    {
32        $container = Testcontainers::run(getenv('MYSQL_VERSION') === '8.4.7' ? MySql84Container::class : MySql80Container::class);
33        try {
34            $rawMysqli = new mysqli(str_replace('localhost', '127.0.0.1', $container->getHost()), 'root', 'root', 'test', $container->getMappedPort(3306));
35            $rawMysqli->set_charset('utf8mb4');
36
37            $rawMysqli->query(
38                'CREATE TABLE articles (id INT PRIMARY KEY, title VARCHAR(255), body TEXT, '
39                . 'FULLTEXT KEY article_search (title, body)) ENGINE=InnoDB',
40            );
41            $ztdMysqli = ZtdMysqli::fromMysqli($rawMysqli);
42            self::assertNotFalse($ztdMysqli->query(
43                "INSERT INTO articles VALUES (1, 'Search guide', 'exact search terms'), "
44                . "(2, 'Other', 'unrelated')",
45            ));
46
47            $result = $ztdMysqli->query(
48                "SELECT id FROM articles WHERE MATCH(title, body) AGAINST ('search terms')",
49            );
50            self::assertInstanceOf(mysqli_result::class, $result);
51            self::assertSame([['id' => 1]], $result->fetch_all(MYSQLI_ASSOC));
52
53            $physical = $rawMysqli->query('SELECT COUNT(*) AS aggregate FROM articles');
54            self::assertInstanceOf(mysqli_result::class, $physical);
55            self::assertSame([['aggregate' => '0']], $physical->fetch_all(MYSQLI_ASSOC));
56        } finally {
57            $container->stop();
58        }
59    }
60}
61