Просмотр исходного кода

Fix lookup of the localised default category (#9543)

The GReader API exposes a translated default category name while the database stores Uncategorized. Resolve that name by the constant category ID so marking the category as read accepts the label returned by the API.

Add SQLite regression coverage for English, Russian and French, ordinary Cyrillic category names with spaces, and missing categories.

Fixes #9542
Artem Netsvetaev 13 часов назад
Родитель
Сommit
62c47b7168
3 измененных файлов с 38 добавлено и 0 удалено
  1. 1 0
      CREDITS.md
  2. 4 0
      app/Models/CategoryDAO.php
  3. 33 0
      tests/app/Models/CategoryDAOTest.php

+ 1 - 0
CREDITS.md

@@ -40,6 +40,7 @@ People are sorted by name so please keep this order.
 * [Antonio Santos](https://github.com/Otolock): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:Otolock), [Web](https://otolock.net/)
 * [Arslan-TR](https://github.com/Arslan-TR): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:Arslan-TR)
 * [ArthurHoaro](https://github.com/ArthurHoaro): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:ArthurHoaro)
+* [Artem Netsvetaev](https://github.com/netsvetoch): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:netsvetoch)
 * [Artur Weigandt](https://github.com/Art4): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:Art4), [Web](https://ruhr.social/@Art4)
 * [ASMfreaK](https://github.com/ASMfreaK): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:ASMfreaK)
 * [Axel Leroy](https://github.com/axeleroy): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:axeleroy), [Web](https://axel.leroy.sh/)

+ 4 - 0
app/Models/CategoryDAO.php

@@ -293,6 +293,10 @@ class FreshRSS_CategoryDAO extends Minz_ModelPdo {
 	}
 
 	public function searchByName(string $name): ?FreshRSS_Category {
+		// The default category exposes a translated name, but its stored name is not translated.
+		if ($name === _t('gen.short.default_category')) {
+			return $this->searchById(self::DEFAULTCATEGORYID);
+		}
 		$sql = <<<'SQL'
 			SELECT * FROM `_category` WHERE name=:name
 			SQL;

+ 33 - 0
tests/app/Models/CategoryDAOTest.php

@@ -0,0 +1,33 @@
+<?php
+declare(strict_types=1);
+
+use PHPUnit\Framework\Attributes\DataProvider;
+
+final class CategoryDAOTest extends \PHPUnit\Framework\TestCase {
+
+	#[DataProvider('provideLanguages')]
+	public function test_searchByName_resolvesLocalisedDefaultCategory(string $language): void {
+		$previousLanguage = Minz_Translate::language();
+		Minz_Translate::init($language);
+		try {
+			$pdo = new Minz_PdoSqlite('sqlite::memory:');
+			$pdo->exec('CREATE TABLE category (id INTEGER PRIMARY KEY, name TEXT, kind INTEGER DEFAULT 0)');
+			$pdo->exec("INSERT INTO category (id, name) VALUES (1, 'Uncategorized'), (2, 'Архив с пробелами')");
+			$dao = new FreshRSS_CategoryDAOSQLite(currentPdo: $pdo);
+
+			$defaultCategory = $dao->searchById(FreshRSS_CategoryDAO::DEFAULTCATEGORYID);
+			self::assertNotNull($defaultCategory);
+			self::assertSame(FreshRSS_CategoryDAO::DEFAULTCATEGORYID, $dao->searchByName($defaultCategory->name())?->id());
+			self::assertSame(FreshRSS_CategoryDAO::DEFAULTCATEGORYID, $dao->searchByName(FreshRSS_CategoryDAO::DEFAULT_CATEGORY_NAME)?->id());
+			self::assertSame(2, $dao->searchByName('Архив с пробелами')?->id());
+			self::assertNull($dao->searchByName('Missing category'));
+		} finally {
+			Minz_Translate::init($previousLanguage);
+		}
+	}
+
+	/** @return list<array{string}> */
+	public static function provideLanguages(): array {
+		return [['en'], ['ru'], ['fr']];
+	}
+}