|
3 | 3 | namespace Lwt\Tests\Core\Tag; |
4 | 4 |
|
5 | 5 | require_once __DIR__ . '/../../../../src/backend/Core/Bootstrap/EnvLoader.php'; |
| 6 | +require_once __DIR__ . '/../../../../src/backend/Core/Http/url_utilities.php'; |
6 | 7 |
|
7 | 8 | use Lwt\Core\EnvLoader; |
8 | 9 | use Lwt\Core\Globals; |
| 10 | +use Lwt\Database\Connection; |
| 11 | +use Lwt\Database\QueryBuilder; |
9 | 12 | use Lwt\Services\TagService; |
10 | 13 | use PHPUnit\Framework\TestCase; |
11 | 14 |
|
@@ -750,4 +753,58 @@ public function testRemoveTagFromArchivedTextsEmptyTag(): void |
750 | 753 | $this->assertIsString($result); |
751 | 754 | $this->assertStringContainsString('not found', $result); |
752 | 755 | } |
| 756 | + |
| 757 | + /** |
| 758 | + * Test saveWordTagsFromArray handles duplicate tags gracefully (Issue #120) |
| 759 | + * |
| 760 | + * This tests the scenario where a tag exists in the database but the |
| 761 | + * session cache is stale. The function should not throw a duplicate |
| 762 | + * key error. |
| 763 | + */ |
| 764 | + public function testSaveWordTagsFromArrayHandlesDuplicateTags(): void |
| 765 | + { |
| 766 | + if (!Globals::getDbConnection()) { |
| 767 | + $this->markTestSkipped('Database connection not available'); |
| 768 | + } |
| 769 | + |
| 770 | + // Use a highly unique tag name with microseconds |
| 771 | + $uniqueTagName = 'DupTest_' . uniqid('', true); |
| 772 | + |
| 773 | + // Clean up any pre-existing tag with this name (shouldn't exist, but be safe) |
| 774 | + Connection::preparedExecute( |
| 775 | + 'DELETE FROM tags WHERE TgText = ?', |
| 776 | + [$uniqueTagName] |
| 777 | + ); |
| 778 | + |
| 779 | + try { |
| 780 | + // Insert the tag directly into the database |
| 781 | + Connection::preparedExecute( |
| 782 | + 'INSERT INTO tags (TgText) VALUES (?)', |
| 783 | + [$uniqueTagName] |
| 784 | + ); |
| 785 | + |
| 786 | + // Clear the session cache to simulate stale cache |
| 787 | + $_SESSION['TAGS'] = []; |
| 788 | + |
| 789 | + // Try to save a word with this tag - should NOT throw exception |
| 790 | + // even though the tag exists but is not in the cache |
| 791 | + TagService::saveWordTagsFromArray(1, [$uniqueTagName]); |
| 792 | + $this->assertTrue(true, 'saveWordTagsFromArray should handle duplicate tags gracefully'); |
| 793 | + } catch (\RuntimeException $e) { |
| 794 | + if (strpos($e->getMessage(), 'Duplicate entry') !== false) { |
| 795 | + $this->fail('Issue #120: saveWordTagsFromArray throws duplicate key error when cache is stale: ' . $e->getMessage()); |
| 796 | + } |
| 797 | + throw $e; |
| 798 | + } finally { |
| 799 | + // Cleanup: remove the test tag and wordtags associations |
| 800 | + Connection::preparedExecute( |
| 801 | + 'DELETE FROM wordtags WHERE WtTgID IN (SELECT TgID FROM tags WHERE TgText = ?)', |
| 802 | + [$uniqueTagName] |
| 803 | + ); |
| 804 | + Connection::preparedExecute( |
| 805 | + 'DELETE FROM tags WHERE TgText = ?', |
| 806 | + [$uniqueTagName] |
| 807 | + ); |
| 808 | + } |
| 809 | + } |
753 | 810 | } |
0 commit comments