BooleanSearchTest.php 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. <?php
  2. declare(strict_types=1);
  3. use PHPUnit\Framework\Attributes\DataProvider;
  4. final class BooleanSearchTest extends \PHPUnit\Framework\TestCase {
  5. public function __construct(string $name) {
  6. parent::__construct($name);
  7. if (!FreshRSS_Context::hasSystemConf()) {
  8. FreshRSS_Context::initSystem();
  9. }
  10. }
  11. /**
  12. * `FreshRSS_BooleanSearch::prepend()` is used to restrict an existing search with an extra condition,
  13. * such as the maximum publication date of the “mark as read → articles older than one day/week” action.
  14. * @return list<array{string,string,list<string|int>}>
  15. */
  16. public static function providePrependMaxPubdate(): array {
  17. return [
  18. ['', '(e.date <= ?)', [1700000000]],
  19. ['intitle:sale', '(e.date <= ?) AND ((e.title LIKE ?))', [1700000000, '%sale%']],
  20. ['intitle:a OR intitle:b', '(e.date <= ?) AND ((e.title LIKE ?) OR (e.title LIKE ?))', [1700000000, '%a%', '%b%']],
  21. ];
  22. }
  23. /** @param list<string|int> $expectedValues */
  24. #[DataProvider('providePrependMaxPubdate')]
  25. public function test_prepend_restrictsTheSearchInsteadOfWideningIt(string $input, string $expectedSql, array $expectedValues): void {
  26. $booleanSearch = new FreshRSS_BooleanSearch($input);
  27. $maxPubdate = new FreshRSS_Search('');
  28. $maxPubdate->setMaxPubdate(1700000000);
  29. $booleanSearch->prepend($maxPubdate);
  30. [$values, $sql] = FreshRSS_EntryDAO::sqlBooleanSearch('e.', $booleanSearch);
  31. self::assertSame($expectedSql, trim($sql));
  32. self::assertSame($expectedValues, $values);
  33. }
  34. public function test_constructor_acceptsSearchesAtTheLimits(): void {
  35. $input = str_repeat('a', FreshRSS_Context::systemConf()->limits['max_search_length']);
  36. self::assertSame($input, (string)new FreshRSS_BooleanSearch($input));
  37. $input = str_repeat('(', FreshRSS_Context::systemConf()->limits['max_search_parentheses_depth']) . 'ab' .
  38. str_repeat(')', FreshRSS_Context::systemConf()->limits['max_search_parentheses_depth']);
  39. self::assertSame('ab', (string)new FreshRSS_BooleanSearch($input));
  40. }
  41. /** @return list<list{string}> */
  42. public static function provideTooLongOrTooDeepSearches(): array {
  43. $tooLong = str_repeat('a', FreshRSS_Context::systemConf()->limits['max_search_length'] + 1);
  44. $tooDeep = str_repeat('(', FreshRSS_Context::systemConf()->limits['max_search_parentheses_depth'] + 1) . 'ab' .
  45. str_repeat(')', FreshRSS_Context::systemConf()->limits['max_search_parentheses_depth'] + 1);
  46. return [
  47. [$tooLong],
  48. [$tooDeep],
  49. ];
  50. }
  51. #[DataProvider('provideTooLongOrTooDeepSearches')]
  52. public function test_constructor_rejectsTooLongOrTooDeepSearches(string $input): void {
  53. self::expectException(Minz_BadRequestException::class);
  54. new FreshRSS_BooleanSearch($input);
  55. }
  56. }