packages/ztd-query-core/tests/Unit/Exception/DuplicateKeyExceptionTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Exception;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\TestCase;
9use ZtdQuery\Exception\DuplicateKeyException;
10
11#[CoversClass(DuplicateKeyException::class)]
12final class DuplicateKeyExceptionTest extends TestCase
13{
14    public function testGetMessageReturnsFormattedMessage(): void
15    {
16        $exception = new DuplicateKeyException(
17            'INSERT INTO users (id, name) VALUES (1, "Alice")',
18            'users',
19            'PRIMARY',
20            ['id' => 1]
21        );
22
23        self::assertSame("Duplicate entry '1' for key 'PRIMARY' in table 'users'.", $exception->getMessage());
24    }
25
26    public function testGetMessageWithMultipleKeyValues(): void
27    {
28        $exception = new DuplicateKeyException(
29            'INSERT INTO orders (user_id, product_id) VALUES (1, 2)',
30            'orders',
31            'user_product_unique',
32            ['user_id' => 1, 'product_id' => 2]
33        );
34
35        self::assertSame(
36            "Duplicate entry '1, 2' for key 'user_product_unique' in table 'orders'.",
37            $exception->getMessage()
38        );
39    }
40
41    public function testGetMessageWithStringKeyValue(): void
42    {
43        $exception = new DuplicateKeyException(
44            'INSERT INTO users (email) VALUES ("test@example.com")',
45            'users',
46            'email_UNIQUE',
47            ['email' => 'test@example.com']
48        );
49
50        self::assertSame(
51            "Duplicate entry ''test@example.com'' for key 'email_UNIQUE' in table 'users'.",
52            $exception->getMessage()
53        );
54    }
55
56    public function testGetMessageWithNullKeyValue(): void
57    {
58        $exception = new DuplicateKeyException(
59            'INSERT INTO users (id) VALUES (NULL)',
60            'users',
61            'PRIMARY',
62            ['id' => null]
63        );
64
65        self::assertSame("Duplicate entry '' for key 'PRIMARY' in table 'users'.", $exception->getMessage());
66    }
67
68    public function testGetMessageWithEmptyKeyValues(): void
69    {
70        $exception = new DuplicateKeyException(
71            'INSERT INTO users (id) VALUES (1)',
72            'users',
73            'PRIMARY'
74        );
75
76        self::assertSame("Duplicate entry '' for key 'PRIMARY' in table 'users'.", $exception->getMessage());
77    }
78
79    public function testGetSqlReturnsOriginalSql(): void
80    {
81        $sql = 'INSERT INTO users (id) VALUES (1)';
82        $exception = new DuplicateKeyException($sql, 'users', 'PRIMARY', ['id' => 1]);
83
84        self::assertSame($sql, $exception->getSql());
85    }
86
87    public function testGetTableNameReturnsTableName(): void
88    {
89        $exception = new DuplicateKeyException('sql', 'users', 'PRIMARY', ['id' => 1]);
90
91        self::assertSame('users', $exception->getTableName());
92    }
93
94    public function testGetKeyNameReturnsKeyName(): void
95    {
96        $exception = new DuplicateKeyException('sql', 'users', 'PRIMARY', ['id' => 1]);
97
98        self::assertSame('PRIMARY', $exception->getKeyName());
99    }
100
101    public function testGetKeyValuesReturnsKeyValues(): void
102    {
103        $keyValues = ['id' => 1, 'name' => 'Alice'];
104        $exception = new DuplicateKeyException('sql', 'users', 'PRIMARY', $keyValues);
105
106        self::assertSame($keyValues, $exception->getKeyValues());
107    }
108
109    public function testFormatKeyValueKeepsErrorMessagesReadableForDriverValues(): void
110    {
111        self::assertSame("'alice'", DuplicateKeyException::formatKeyValue('alice'));
112        self::assertSame('42', DuplicateKeyException::formatKeyValue(42));
113        self::assertSame('', DuplicateKeyException::formatKeyValue(null));
114        self::assertSame('array', DuplicateKeyException::formatKeyValue(['nested' => true]));
115    }
116
117}
118