diff --git a/src/Database/Query.php b/src/Database/Query.php index f2ed42416..e8b455775 100644 --- a/src/Database/Query.php +++ b/src/Database/Query.php @@ -24,24 +24,48 @@ class Query public const TYPE_SELECT = 'select'; // Order methods - public const TYPE_ORDERDESC = 'orderDesc'; - public const TYPE_ORDERASC = 'orderAsc'; + public const TYPE_ORDER_DESC = 'orderDesc'; + public const TYPE_ORDER_ASC = 'orderAsc'; // Pagination methods public const TYPE_LIMIT = 'limit'; public const TYPE_OFFSET = 'offset'; - public const TYPE_CURSORAFTER = 'cursorAfter'; - public const TYPE_CURSORBEFORE = 'cursorBefore'; - - protected const CHAR_SINGLE_QUOTE = '\''; - protected const CHAR_DOUBLE_QUOTE = '"'; - protected const CHAR_COMMA = ','; - protected const CHAR_SPACE = ' '; - protected const CHAR_BRACKET_START = '['; - protected const CHAR_BRACKET_END = ']'; - protected const CHAR_PARENTHESES_START = '('; - protected const CHAR_PARENTHESES_END = ')'; - protected const CHAR_BACKSLASH = '\\'; + public const TYPE_CURSOR_AFTER = 'cursorAfter'; + public const TYPE_CURSOR_BEFORE = 'cursorBefore'; + + // Logical methods + public const TYPE_AND = 'and'; + public const TYPE_OR = 'or'; + + public const TYPES = [ + self::TYPE_EQUAL, + self::TYPE_NOT_EQUAL, + self::TYPE_LESSER, + self::TYPE_LESSER_EQUAL, + self::TYPE_GREATER, + self::TYPE_GREATER_EQUAL, + self::TYPE_CONTAINS, + self::TYPE_SEARCH, + self::TYPE_IS_NULL, + self::TYPE_IS_NOT_NULL, + self::TYPE_BETWEEN, + self::TYPE_STARTS_WITH, + self::TYPE_ENDS_WITH, + self::TYPE_SELECT, + self::TYPE_ORDER_DESC, + self::TYPE_ORDER_ASC, + self::TYPE_LIMIT, + self::TYPE_OFFSET, + self::TYPE_CURSOR_AFTER, + self::TYPE_CURSOR_BEFORE, + self::TYPE_AND, + self::TYPE_OR, + ]; + + protected const LOGICAL_TYPES = [ + self::TYPE_AND, + self::TYPE_OR, + ]; protected string $method = ''; protected string $attribute = ''; @@ -51,7 +75,6 @@ class Query */ protected array $values = []; - /** * Construct a new query object * @@ -158,7 +181,7 @@ public function setValue(mixed $value): self */ public static function isMethod(string $value): bool { - return match (static::getMethodFromAlias($value)) { + return match ($value) { self::TYPE_EQUAL, self::TYPE_NOT_EQUAL, self::TYPE_LESSER, @@ -167,12 +190,12 @@ public static function isMethod(string $value): bool self::TYPE_GREATER_EQUAL, self::TYPE_CONTAINS, self::TYPE_SEARCH, - self::TYPE_ORDERASC, - self::TYPE_ORDERDESC, + self::TYPE_ORDER_ASC, + self::TYPE_ORDER_DESC, self::TYPE_LIMIT, self::TYPE_OFFSET, - self::TYPE_CURSORAFTER, - self::TYPE_CURSORBEFORE, + self::TYPE_CURSOR_AFTER, + self::TYPE_CURSOR_BEFORE, self::TYPE_IS_NULL, self::TYPE_IS_NOT_NULL, self::TYPE_BETWEEN, @@ -184,303 +207,76 @@ public static function isMethod(string $value): bool } /** - * Parse query filter + * Parse query * - * @param string $filter + * @param array $query * @return self - * @throws Exception + * @throws QueryException */ - public static function parse(string $filter): self + public static function parse(array $query): self { - // Init empty vars we fill later - $method = ''; - $params = []; - - // Separate method from filter - $paramsStart = mb_strpos($filter, static::CHAR_PARENTHESES_START); - - if ($paramsStart === false) { - throw new QueryException('Invalid query'); - } - - $method = mb_substr($filter, 0, $paramsStart); - - // Separate params from filter - $paramsEnd = \strlen($filter) - 1; // -1 to ignore ) - $parametersStart = $paramsStart + 1; // +1 to ignore ( - - // Check for deprecated query syntax - if (\str_contains($method, '.')) { - throw new QueryException('Invalid query method'); - } - - $currentParam = ""; // We build param here before pushing when it's ended - $currentArrayParam = []; // We build array param here before pushing when it's ended - - $stack = []; // State for stack of parentheses - $stackCount = 0; // Length of stack array. Kept as variable to improve performance - $stringStackState = null; // State for string support - - // Loop thorough all characters - for ($i = $parametersStart; $i < $paramsEnd; $i++) { - $char = $filter[$i]; - - $isStringStack = $stringStackState !== null; - $isArrayStack = !$isStringStack && $stackCount > 0; - - if ($char === static::CHAR_BACKSLASH) { - if (!(static::isSpecialChar($filter[$i + 1]))) { - static::appendSymbol($isStringStack, $filter[$i], $i, $filter, $currentParam); - } - - static::appendSymbol($isStringStack, $filter[$i + 1], $i, $filter, $currentParam); - $i++; - - continue; - } - - // String support + escaping support - if ( - (self::isQuote($char)) && // Must be string indicator - ($filter[$i - 1] !== static::CHAR_BACKSLASH || $filter[$i - 2] === static::CHAR_BACKSLASH) // Must not be escaped; - ) { - if ($isStringStack) { - // Dont mix-up string symbols. Only allow the same as on start - if ($char === $stringStackState) { - // End of string - $stringStackState = null; - } - - // Either way, add symbol to builder - static::appendSymbol($isStringStack, $char, $i, $filter, $currentParam); - } else { - // Start of string - $stringStackState = $char; - static::appendSymbol($isStringStack, $char, $i, $filter, $currentParam); - } - - continue; - } - - // Array support - if (!($isStringStack)) { - if ($char === static::CHAR_BRACKET_START) { - // Start of array - $stack[] = $char; - $stackCount++; - continue; - } elseif ($char === static::CHAR_BRACKET_END) { - // End of array - \array_pop($stack); - $stackCount--; - - if (strlen($currentParam)) { - $currentArrayParam[] = $currentParam; - } - - $params[] = $currentArrayParam; - $currentArrayParam = []; - $currentParam = ""; - - continue; - } elseif ($char === static::CHAR_COMMA) { // Params separation support - // If in array stack, dont merge yet, just mark it in array param builder - if ($isArrayStack) { - $currentArrayParam[] = $currentParam; - $currentParam = ""; - } else { - // Append from parap builder. Either value, or array - if (empty($currentArrayParam)) { - if (strlen($currentParam)) { - $params[] = $currentParam; - } - - $currentParam = ""; - } - } - continue; - } - } + $method = $query['method'] ?? ''; + $attribute = $query['attribute'] ?? ''; + $values = $query['values'] ?? []; - // Value, not relevant to syntax - static::appendSymbol($isStringStack, $char, $i, $filter, $currentParam); + if (!self::isMethod($method)) { + throw new QueryException('Invalid query method: ' . $method); } - if (strlen($currentParam)) { - $params[] = $currentParam; - $currentParam = ""; - } - - $parsedParams = []; - - foreach ($params as $param) { - // If array, parse each child separatelly - if (\is_array($param)) { - foreach ($param as $element) { - $arr[] = self::parseValue($element); - } - - $parsedParams[] = $arr ?? []; - } else { - $parsedParams[] = self::parseValue($param); + if (\in_array($method, self::LOGICAL_TYPES)) { + foreach ($values as $index => $value) { + $values[$index] = self::parse($value); } } - $method = static::getMethodFromAlias($method); - switch ($method) { - case self::TYPE_EQUAL: - case self::TYPE_NOT_EQUAL: - case self::TYPE_LESSER: - case self::TYPE_LESSER_EQUAL: - case self::TYPE_GREATER: - case self::TYPE_GREATER_EQUAL: - case self::TYPE_CONTAINS: - case self::TYPE_SEARCH: - case self::TYPE_IS_NULL: - case self::TYPE_IS_NOT_NULL: - case self::TYPE_STARTS_WITH: - case self::TYPE_ENDS_WITH: - $attribute = $parsedParams[0] ?? ''; - if (count($parsedParams) < 2) { - return new self($method, $attribute); - } - return new self($method, $attribute, \is_array($parsedParams[1]) ? $parsedParams[1] : [$parsedParams[1]]); - - case self::TYPE_BETWEEN: - return new self($method, $parsedParams[0], [$parsedParams[1], $parsedParams[2]]); - case self::TYPE_SELECT: - return new self($method, values: $parsedParams[0]); - case self::TYPE_ORDERASC: - case self::TYPE_ORDERDESC: - return new self($method, $parsedParams[0] ?? ''); - - case self::TYPE_LIMIT: - case self::TYPE_OFFSET: - case self::TYPE_CURSORAFTER: - case self::TYPE_CURSORBEFORE: - if (count($parsedParams) > 0) { - return new self($method, values: [$parsedParams[0]]); - } - return new self($method); - - default: - return new self($method); - } + return new self($method, $attribute, $values); } /** - * Utility method to only append symbol if relevant. + * Parse an array of queries * - * @param bool $isStringStack - * @param string $char - * @param int $index - * @param string $filter - * @param string $currentParam - * @return void - */ - protected static function appendSymbol(bool $isStringStack, string $char, int $index, string $filter, string &$currentParam): void - { - // Ignore spaces and commas outside of string - $canBeIgnored = false; - - if ($char === static::CHAR_SPACE) { - $canBeIgnored = true; - } elseif ($char === static::CHAR_COMMA) { - $canBeIgnored = true; - } - - if ($canBeIgnored) { - if ($isStringStack) { - $currentParam .= $char; - } - } else { - $currentParam .= $char; - } - } - - protected static function isQuote(string $char): bool + * @param array> $queries + * + * @return array + * @throws Exception + */ + public static function parseQueries(array $queries): array { - if ($char === self::CHAR_SINGLE_QUOTE) { - return true; - } elseif ($char === self::CHAR_DOUBLE_QUOTE) { - return true; - } - - return false; - } + $parsed = []; - protected static function isSpecialChar(string $char): bool - { - if ($char === static::CHAR_COMMA) { - return true; - } elseif ($char === static::CHAR_BRACKET_END) { - return true; - } elseif ($char === static::CHAR_BRACKET_START) { - return true; - } elseif ($char === static::CHAR_DOUBLE_QUOTE) { - return true; - } elseif ($char === static::CHAR_SINGLE_QUOTE) { - return true; + foreach ($queries as $query) { + $parsed[] = Query::parse($query); } - return false; + return $parsed; } /** - * Parses value. - * - * @param string $value - * @return mixed + * @return array */ - protected static function parseValue(string $value): mixed - { - $value = \trim($value); - - if ($value === 'false') { // Boolean value - return false; - } elseif ($value === 'true') { - return true; - } elseif ($value === 'null') { // Null value - return null; - } elseif (\is_numeric($value)) { // Numeric value - // Cast to number - return $value + 0; - } elseif (\str_starts_with($value, static::CHAR_DOUBLE_QUOTE) || \str_starts_with($value, static::CHAR_SINGLE_QUOTE)) { // String param - $value = \substr($value, 1, -1); // Remove '' or "" - return $value; + public function toArray(): array + { + $array = [ + 'method' => $this->method, + 'attribute' => $this->attribute, + ]; + + if (\in_array($array['method'], self::LOGICAL_TYPES)) { + foreach ($this->values as $index => $value) { + $array['values'][$index] = $this->toArray(); + } + } else { + $array['values'] = $this->values; } - // Unknown format - return $value; - } - - /** - * Returns Method from Alias. - * - * @param string $method - * @return string - */ - protected static function getMethodFromAlias(string $method): string - { - return $method; - /* - Commented out as we didn't consider this important at the moment, since IDE autocomplete should do the job. - return match ($method) { - 'lt' => self::TYPE_LESSER, - 'lte' => self::TYPE_LESSEREQUAL, - 'gt' => self::TYPE_GREATER, - 'gte' => self::TYPE_GREATEREQUAL, - 'eq' => self::TYPE_EQUAL, - default => $method - }; - */ + return $array; } /** * Helper method to create Query with equal method * * @param string $attribute - * @param array $values + * @param array $values * @return Query */ public static function equal(string $attribute, array $values): self @@ -492,10 +288,10 @@ public static function equal(string $attribute, array $values): self * Helper method to create Query with notEqual method * * @param string $attribute - * @param mixed $value + * @param string|int|float|bool $value * @return Query */ - public static function notEqual(string $attribute, mixed $value): self + public static function notEqual(string $attribute, string|int|float|bool $value): self { return new self(self::TYPE_NOT_EQUAL, $attribute, [$value]); } @@ -504,10 +300,10 @@ public static function notEqual(string $attribute, mixed $value): self * Helper method to create Query with lessThan method * * @param string $attribute - * @param mixed $value + * @param string|int|float|bool $value * @return Query */ - public static function lessThan(string $attribute, mixed $value): self + public static function lessThan(string $attribute, string|int|float|bool $value): self { return new self(self::TYPE_LESSER, $attribute, [$value]); } @@ -516,10 +312,10 @@ public static function lessThan(string $attribute, mixed $value): self * Helper method to create Query with lessThanEqual method * * @param string $attribute - * @param mixed $value + * @param string|int|float|bool $value * @return Query */ - public static function lessThanEqual(string $attribute, mixed $value): self + public static function lessThanEqual(string $attribute, string|int|float|bool $value): self { return new self(self::TYPE_LESSER_EQUAL, $attribute, [$value]); } @@ -528,10 +324,10 @@ public static function lessThanEqual(string $attribute, mixed $value): self * Helper method to create Query with greaterThan method * * @param string $attribute - * @param mixed $value + * @param string|int|float|bool $value * @return Query */ - public static function greaterThan(string $attribute, mixed $value): self + public static function greaterThan(string $attribute, string|int|float|bool $value): self { return new self(self::TYPE_GREATER, $attribute, [$value]); } @@ -540,10 +336,10 @@ public static function greaterThan(string $attribute, mixed $value): self * Helper method to create Query with greaterThanEqual method * * @param string $attribute - * @param mixed $value + * @param string|int|float|bool $value * @return Query */ - public static function greaterThanEqual(string $attribute, mixed$value): self + public static function greaterThanEqual(string $attribute, string|int|float|bool $value): self { return new self(self::TYPE_GREATER_EQUAL, $attribute, [$value]); } @@ -564,11 +360,11 @@ public static function contains(string $attribute, array $values): self * Helper method to create Query with between method * * @param string $attribute - * @param mixed $start - * @param mixed $end + * @param string|int|float|bool $start + * @param string|int|float|bool $end * @return Query */ - public static function between(string $attribute, mixed $start, mixed $end): self + public static function between(string $attribute, string|int|float|bool $start, string|int|float|bool $end): self { return new self(self::TYPE_BETWEEN, $attribute, [$start, $end]); } @@ -577,10 +373,10 @@ public static function between(string $attribute, mixed $start, mixed $end): sel * Helper method to create Query with search method * * @param string $attribute - * @param mixed $value + * @param string|int|float|bool $value * @return Query */ - public static function search(string $attribute, mixed $value): self + public static function search(string $attribute, string|int|float|bool $value): self { return new self(self::TYPE_SEARCH, $attribute, [$value]); } @@ -602,9 +398,9 @@ public static function select(array $attributes): self * @param string $attribute * @return Query */ - public static function orderDesc(string $attribute): self + public static function orderDesc(string $attribute = ''): self { - return new self(self::TYPE_ORDERDESC, $attribute); + return new self(self::TYPE_ORDER_DESC, $attribute); } /** @@ -613,9 +409,9 @@ public static function orderDesc(string $attribute): self * @param string $attribute * @return Query */ - public static function orderAsc(string $attribute): self + public static function orderAsc(string $attribute = ''): self { - return new self(self::TYPE_ORDERASC, $attribute); + return new self(self::TYPE_ORDER_ASC, $attribute); } /** @@ -648,7 +444,7 @@ public static function offset(int $value): self */ public static function cursorAfter(Document $value): self { - return new self(self::TYPE_CURSORAFTER, values: [$value]); + return new self(self::TYPE_CURSOR_AFTER, values: [$value]); } /** @@ -659,7 +455,7 @@ public static function cursorAfter(Document $value): self */ public static function cursorBefore(Document $value): self { - return new self(self::TYPE_CURSORBEFORE, values: [$value]); + return new self(self::TYPE_CURSOR_BEFORE, values: [$value]); } /** @@ -704,8 +500,9 @@ public static function endsWith(string $attribute, string $value): self public static function getByType(array $queries, array $types): array { $filtered = []; + foreach ($queries as $query) { - if (in_array($query->getMethod(), $types, true)) { + if (\in_array($query->getMethod(), $types, true)) { $filtered[] = clone $query; } } @@ -738,6 +535,7 @@ public static function groupByType(array $queries): array $orderTypes = []; $cursor = null; $cursorDirection = null; + foreach ($queries as $query) { if (!$query instanceof Query) { continue; @@ -746,16 +544,19 @@ public static function groupByType(array $queries): array $method = $query->getMethod(); $attribute = $query->getAttribute(); $values = $query->getValues(); + switch ($method) { - case Query::TYPE_ORDERASC: - case Query::TYPE_ORDERDESC: + case Query::TYPE_ORDER_ASC: + case Query::TYPE_ORDER_DESC: if (!empty($attribute)) { $orderAttributes[] = $attribute; } - $orderTypes[] = $method === Query::TYPE_ORDERASC ? Database::ORDER_ASC : Database::ORDER_DESC; - break; + $orderTypes[] = $method === Query::TYPE_ORDER_ASC + ? Database::ORDER_ASC + : Database::ORDER_DESC; + break; case Query::TYPE_LIMIT: // keep the 1st limit encountered and ignore the rest if ($limit !== null) { @@ -764,25 +565,23 @@ public static function groupByType(array $queries): array $limit = $values[0] ?? $limit; break; - case Query::TYPE_OFFSET: - // keep the 1st offset encountered and ignore the rest + // Keep the 1st offset encountered and ignore the rest if ($offset !== null) { break; } $offset = $values[0] ?? $limit; break; - - case Query::TYPE_CURSORAFTER: - case Query::TYPE_CURSORBEFORE: - // keep the 1st cursor encountered and ignore the rest + case Query::TYPE_CURSOR_AFTER: + case Query::TYPE_CURSOR_BEFORE: + // Keep the 1st cursor encountered and ignore the rest if ($cursor !== null) { break; } $cursor = $values[0] ?? $limit; - $cursorDirection = $method === Query::TYPE_CURSORAFTER ? Database::CURSOR_AFTER : Database::CURSOR_BEFORE; + $cursorDirection = $method === Query::TYPE_CURSOR_AFTER ? Database::CURSOR_AFTER : Database::CURSOR_BEFORE; break; case Query::TYPE_SELECT: @@ -806,26 +605,4 @@ public static function groupByType(array $queries): array 'cursorDirection' => $cursorDirection, ]; } - - /** - * Iterate over $queries attempting to parse each - * - * @param array $queries - * - * @return array - * @throws Exception - */ - public static function parseQueries(array $queries): array - { - $parsed = []; - foreach ($queries as $query) { - try { - $parsed[] = Query::parse($query); - } catch (\Throwable $th) { - throw new QueryException("Invalid query: ${query}", previous: $th); - } - } - - return $parsed; - } } diff --git a/src/Database/Validator/Queries.php b/src/Database/Validator/Queries.php index f184b86bb..2f2322add 100644 --- a/src/Database/Validator/Queries.php +++ b/src/Database/Validator/Queries.php @@ -47,7 +47,7 @@ public function getDescription(): string } /** - * @param array $value + * @param array> $value * @return bool */ public function isValid($value): bool @@ -76,10 +76,10 @@ public function isValid($value): bool Query::TYPE_SELECT => Base::METHOD_TYPE_SELECT, Query::TYPE_LIMIT => Base::METHOD_TYPE_LIMIT, Query::TYPE_OFFSET => Base::METHOD_TYPE_OFFSET, - Query::TYPE_CURSORAFTER, - Query::TYPE_CURSORBEFORE => Base::METHOD_TYPE_CURSOR, - Query::TYPE_ORDERASC, - Query::TYPE_ORDERDESC => Base::METHOD_TYPE_ORDER, + Query::TYPE_CURSOR_AFTER, + Query::TYPE_CURSOR_BEFORE => Base::METHOD_TYPE_CURSOR, + Query::TYPE_ORDER_ASC, + Query::TYPE_ORDER_DESC => Base::METHOD_TYPE_ORDER, Query::TYPE_EQUAL, Query::TYPE_NOT_EQUAL, Query::TYPE_LESSER, diff --git a/src/Database/Validator/Query/Cursor.php b/src/Database/Validator/Query/Cursor.php index b976d8412..46020d7b4 100644 --- a/src/Database/Validator/Query/Cursor.php +++ b/src/Database/Validator/Query/Cursor.php @@ -26,7 +26,7 @@ public function isValid($value): bool $method = $value->getMethod(); - if ($method === Query::TYPE_CURSORAFTER || $method === Query::TYPE_CURSORBEFORE) { + if ($method === Query::TYPE_CURSOR_AFTER || $method === Query::TYPE_CURSOR_BEFORE) { $cursor = $value->getValue(); if ($cursor instanceof Document) { diff --git a/src/Database/Validator/Query/Order.php b/src/Database/Validator/Query/Order.php index 40ef707d4..196079618 100644 --- a/src/Database/Validator/Query/Order.php +++ b/src/Database/Validator/Query/Order.php @@ -56,7 +56,7 @@ public function isValid($value): bool $method = $value->getMethod(); $attribute = $value->getAttribute(); - if ($method === Query::TYPE_ORDERASC || $method === Query::TYPE_ORDERDESC) { + if ($method === Query::TYPE_ORDER_ASC || $method === Query::TYPE_ORDER_DESC) { if ($attribute === '') { return true; } diff --git a/tests/Database/Base.php b/tests/Database/Base.php index f38f70b25..7008215a4 100644 --- a/tests/Database/Base.php +++ b/tests/Database/Base.php @@ -12525,66 +12525,6 @@ public function testEmptyOperatorValues(): void $this->assertEquals('Invalid query: Equal queries require at least one value.', $e->getMessage()); } - try { - static::getDatabase()->findOne('documents', [ - Query::search('string', null), - ]); - $this->fail('Failed to throw exception'); - } catch (Exception $e) { - $this->assertInstanceOf(Exception::class, $e); - $this->assertEquals('Invalid query: Query type does not match expected: string', $e->getMessage()); - } - - try { - static::getDatabase()->findOne('documents', [ - Query::notEqual('string', []), - ]); - $this->fail('Failed to throw exception'); - } catch (Exception $e) { - $this->assertInstanceOf(Exception::class, $e); - $this->assertEquals('Invalid query: Query type does not match expected: string', $e->getMessage()); - } - - try { - static::getDatabase()->findOne('documents', [ - Query::lessThan('string', []), - ]); - $this->fail('Failed to throw exception'); - } catch (Exception $e) { - $this->assertInstanceOf(Exception::class, $e); - $this->assertEquals('Invalid query: Query type does not match expected: string', $e->getMessage()); - } - - try { - static::getDatabase()->findOne('documents', [ - Query::lessThanEqual('string', []), - ]); - $this->fail('Failed to throw exception'); - } catch (Exception $e) { - $this->assertInstanceOf(Exception::class, $e); - $this->assertEquals('Invalid query: Query type does not match expected: string', $e->getMessage()); - } - - try { - static::getDatabase()->findOne('documents', [ - Query::greaterThan('string', []), - ]); - $this->fail('Failed to throw exception'); - } catch (Exception $e) { - $this->assertInstanceOf(Exception::class, $e); - $this->assertEquals('Invalid query: Query type does not match expected: string', $e->getMessage()); - } - - try { - static::getDatabase()->findOne('documents', [ - Query::greaterThanEqual('string', []), - ]); - $this->fail('Failed to throw exception'); - } catch (Exception $e) { - $this->assertInstanceOf(Exception::class, $e); - $this->assertEquals('Invalid query: Query type does not match expected: string', $e->getMessage()); - } - try { static::getDatabase()->findOne('documents', [ Query::contains('string', []), diff --git a/tests/Database/QueryTest.php b/tests/Database/QueryTest.php index a7e497959..aa4b44118 100644 --- a/tests/Database/QueryTest.php +++ b/tests/Database/QueryTest.php @@ -4,6 +4,7 @@ use Utopia\Database\Document; use Utopia\Database\Query; +use Utopia\Database\Exception\Query as QueryException; use PHPUnit\Framework\TestCase; class QueryTest extends TestCase @@ -24,9 +25,9 @@ public function testCreate(): void $this->assertEquals('title', $query->getAttribute()); $this->assertEquals('Iron Man', $query->getValues()[0]); - $query = new Query(Query::TYPE_ORDERDESC, 'score'); + $query = new Query(Query::TYPE_ORDER_DESC, 'score'); - $this->assertEquals(Query::TYPE_ORDERDESC, $query->getMethod()); + $this->assertEquals(Query::TYPE_ORDER_DESC, $query->getMethod()); $this->assertEquals('score', $query->getAttribute()); $this->assertEquals([], $query->getValues()); @@ -56,7 +57,7 @@ public function testCreate(): void $query = Query::orderAsc('score'); - $this->assertEquals(Query::TYPE_ORDERASC, $query->getMethod()); + $this->assertEquals(Query::TYPE_ORDER_ASC, $query->getMethod()); $this->assertEquals('score', $query->getAttribute()); $this->assertEquals([], $query->getValues()); @@ -69,7 +70,7 @@ public function testCreate(): void $cursor = new Document(); $query = Query::cursorAfter($cursor); - $this->assertEquals(Query::TYPE_CURSORAFTER, $query->getMethod()); + $this->assertEquals(Query::TYPE_CURSOR_AFTER, $query->getMethod()); $this->assertEquals('', $query->getAttribute()); $this->assertEquals([$cursor], $query->getValues()); @@ -86,351 +87,234 @@ public function testCreate(): void $this->assertEquals([], $query->getValues()); } + /** + * @return void + * @throws QueryException + */ public function testParse(): void { - $query = Query::parse('equal("title", "Iron Man")'); + $query = Query::parse([ + 'method' => 'equal', + 'attribute' => 'title', + 'values' => ['Iron Man'] + ]); $this->assertEquals('equal', $query->getMethod()); $this->assertEquals('title', $query->getAttribute()); $this->assertEquals('Iron Man', $query->getValues()[0]); - $query = Query::parse('lessThan("year", 2001)'); + $query = Query::parse([ + 'method' => 'lessThan', + 'attribute' => 'year', + 'values' => [2001] + ]); $this->assertEquals('lessThan', $query->getMethod()); $this->assertEquals('year', $query->getAttribute()); $this->assertEquals(2001, $query->getValues()[0]); - $query = Query::parse('equal("published", true)'); + $query = Query::parse([ + 'method' => 'equal', + 'attribute' => 'published', + 'values' => [true] + ]); $this->assertEquals('equal', $query->getMethod()); $this->assertEquals('published', $query->getAttribute()); $this->assertTrue($query->getValues()[0]); - $query = Query::parse('equal("published", false)'); + $query = Query::parse([ + 'method' => 'equal', + 'attribute' => 'published', + 'values' => [false] + ]); $this->assertEquals('equal', $query->getMethod()); $this->assertEquals('published', $query->getAttribute()); $this->assertFalse($query->getValues()[0]); - $query = Query::parse('equal("actors", [ " Johnny Depp ", " Brad Pitt" , \'Al Pacino \' ])'); + $query = Query::parse([ + 'method' => 'equal', + 'attribute' => 'actors', + 'values' => [' Johnny Depp ', ' Brad Pitt', 'Al Pacino '] + ]); $this->assertEquals('equal', $query->getMethod()); $this->assertEquals('actors', $query->getAttribute()); - $this->assertEquals(" Johnny Depp ", $query->getValues()[0]); - $this->assertEquals(" Brad Pitt", $query->getValues()[1]); - $this->assertEquals("Al Pacino ", $query->getValues()[2]); + $this->assertEquals(' Johnny Depp ', $query->getValues()[0]); + $this->assertEquals(' Brad Pitt', $query->getValues()[1]); + $this->assertEquals('Al Pacino ', $query->getValues()[2]); - $query = Query::parse('equal("actors", ["Brad Pitt", "Johnny Depp"])'); + $query = Query::parse([ + 'method' => 'equal', + 'attribute' => 'actors', + 'values' => ['Brad Pitt', 'Johnny Depp'] + ]); $this->assertEquals('equal', $query->getMethod()); $this->assertEquals('actors', $query->getAttribute()); - $this->assertEquals("Brad Pitt", $query->getValues()[0]); - $this->assertEquals("Johnny Depp", $query->getValues()[1]); + $this->assertEquals('Brad Pitt', $query->getValues()[0]); + $this->assertEquals('Johnny Depp', $query->getValues()[1]); - $query = Query::parse('contains("writers","Tim O\'Reilly")'); + $query = Query::parse([ + 'method' => 'contains', + 'attribute' => 'writers', + 'values' => ['Tim O\'Reilly'] + ]); $this->assertEquals('contains', $query->getMethod()); $this->assertEquals('writers', $query->getAttribute()); - $this->assertEquals("Tim O'Reilly", $query->getValues()[0]); + $this->assertEquals('Tim O\'Reilly', $query->getValues()[0]); - $query = Query::parse('greaterThan("score", 8.5)'); + $query = Query::parse([ + 'method' => 'greaterThan', + 'attribute' => 'score', + 'values' => [8.5] + ]); $this->assertEquals('greaterThan', $query->getMethod()); $this->assertEquals('score', $query->getAttribute()); $this->assertEquals(8.5, $query->getValues()[0]); - $query = Query::parse('notEqual("director", "null")'); + $query = Query::parse([ + 'method' => 'notEqual', + 'attribute' => 'director', + 'values' => ['null'] + ]); $this->assertEquals('notEqual', $query->getMethod()); $this->assertEquals('director', $query->getAttribute()); $this->assertEquals('null', $query->getValues()[0]); - $query = Query::parse('notEqual("director", null)'); + $query = Query::parse([ + 'method' => 'notEqual', + 'attribute' => 'director', + 'values' => [null] + ]); $this->assertEquals('notEqual', $query->getMethod()); $this->assertEquals('director', $query->getAttribute()); $this->assertEquals(null, $query->getValues()[0]); - $query = Query::parse('isNull("director")'); + $query = Query::parse([ + 'method' => 'isNull', + 'attribute' => 'director', + 'values' => [] + ]); $this->assertEquals('isNull', $query->getMethod()); $this->assertEquals('director', $query->getAttribute()); $this->assertEquals([], $query->getValues()); - $query = Query::parse('isNotNull("director")'); + $query = Query::parse([ + 'method' => 'isNotNull', + 'attribute' => 'director', + 'values' => [] + ]); $this->assertEquals('isNotNull', $query->getMethod()); $this->assertEquals('director', $query->getAttribute()); $this->assertEquals([], $query->getValues()); - $query = Query::parse('startsWith("director", "Quentin")'); + $query = Query::parse([ + 'method' => 'startsWith', + 'attribute' => 'director', + 'values' => ['Quentin'] + ]); $this->assertEquals('startsWith', $query->getMethod()); $this->assertEquals('director', $query->getAttribute()); $this->assertEquals(['Quentin'], $query->getValues()); - $query = Query::parse('endsWith("director", "Tarantino")'); + $query = Query::parse([ + 'method' => 'endsWith', + 'attribute' => 'director', + 'values' => ['Tarantino'] + ]); $this->assertEquals('endsWith', $query->getMethod()); $this->assertEquals('director', $query->getAttribute()); $this->assertEquals(['Tarantino'], $query->getValues()); - $query = Query::parse('select(["title", "director"])'); + $query = Query::parse([ + 'method' => 'select', + 'attribute' => null, + 'values' => ['title', 'director'] + ]); $this->assertEquals('select', $query->getMethod()); - $this->assertEquals('', $query->getAttribute()); - $this->assertEquals('title', $query->getValues()[0]); - $this->assertEquals('director', $query->getValues()[1]); + $this->assertEquals(null, $query->getAttribute()); + $this->assertEquals(['title', 'director'], $query->getValues()); - $query = Query::parse('between("age", 15, 18)'); + $query = Query::parse([ + 'method' => 'between', + 'attribute' => 'age', + 'values' => [15, 18] + ]); $this->assertEquals('between', $query->getMethod()); $this->assertEquals('age', $query->getAttribute()); - $this->assertEquals(15, $query->getValues()[0]); - $this->assertEquals(18, $query->getValues()[1]); + $this->assertEquals([15, 18], $query->getValues()); - $query = Query::parse('between("lastUpdate", "DATE1", "DATE2")'); + $query = Query::parse([ + 'method' => 'between', + 'attribute' => 'lastUpdate', + 'values' => ['DATE1', 'DATE2'] + ]); $this->assertEquals('between', $query->getMethod()); $this->assertEquals('lastUpdate', $query->getAttribute()); - $this->assertEquals('DATE1', $query->getValues()[0]); - $this->assertEquals('DATE2', $query->getValues()[1]); - } + $this->assertEquals(['DATE1', 'DATE2'], $query->getValues()); + + $query = Query::parse([ + 'method' => 'equal', + 'attribute' => 'attr', + 'values' => [1] + ]); - public function testParseV2(): void - { - $query = Query::parse('equal("attr", 1)'); $this->assertCount(1, $query->getValues()); - $this->assertEquals("attr", $query->getAttribute()); + $this->assertEquals('attr', $query->getAttribute()); $this->assertEquals([1], $query->getValues()); - $query = Query::parse('equal("attr", [0])'); - $this->assertCount(1, $query->getValues()); - $this->assertEquals("attr", $query->getAttribute()); - $this->assertEquals([0], $query->getValues()); + $query = Query::parse([ + 'method' => 'equal', + 'attribute' => 'attr', + 'values' => [0] + ]); - $query = Query::parse('equal("attr", 0,)'); $this->assertCount(1, $query->getValues()); - $this->assertEquals("attr", $query->getAttribute()); + $this->assertEquals('attr', $query->getAttribute()); $this->assertEquals([0], $query->getValues()); - $query = Query::parse('equal("attr", ["0"])'); - $this->assertCount(1, $query->getValues()); - $this->assertEquals("attr", $query->getAttribute()); - $this->assertEquals(["0"], $query->getValues()); - - $query = Query::parse('equal(1, ["[Hello] World"])'); - $this->assertCount(1, $query->getValues()); - $this->assertEquals(1, $query->getAttribute()); - $this->assertEquals("[Hello] World", $query->getValues()[0]); - - $query = Query::parse('equal(1, , , ["[Hello] World"], , , )'); - $this->assertCount(1, $query->getValues()); - $this->assertEquals(1, $query->getAttribute()); - $this->assertEquals("[Hello] World", $query->getValues()[0]); - - $query = Query::parse('equal(1, ["(Hello) World"])'); - $this->assertCount(1, $query->getValues()); - $this->assertEquals(1, $query->getAttribute()); - $this->assertEquals("(Hello) World", $query->getValues()[0]); - - $query = Query::parse('equal(1, ["Hello , World"])'); - $this->assertCount(1, $query->getValues()); - $this->assertEquals(1, $query->getAttribute()); - $this->assertEquals("Hello , World", $query->getValues()[0]); - - $query = Query::parse('equal(1, ["Hello , World"])'); - $this->assertCount(1, $query->getValues()); - $this->assertEquals(1, $query->getAttribute()); - $this->assertEquals("Hello , World", $query->getValues()[0]); - - $query = Query::parse('equal(1, ["Hello /\ World"])'); - $this->assertCount(1, $query->getValues()); - $this->assertEquals(1, $query->getAttribute()); - $this->assertEquals("Hello /\ World", $query->getValues()[0]); - - $query = Query::parse('equal(1, ["I\'m [**awesome**], \"Dev\"eloper"])'); - $this->assertCount(1, $query->getValues()); - $this->assertEquals(1, $query->getAttribute()); - $this->assertEquals("I'm [**awesome**], \"Dev\"eloper", $query->getValues()[0]); + $query = Query::parse([ + 'method' => 'equal', + 'attribute' => 1, + 'values' => ['[Hello] World'] + ]); - $query = Query::parse('equal(1, "\\\\")'); $this->assertCount(1, $query->getValues()); $this->assertEquals(1, $query->getAttribute()); - $this->assertEquals("\\\\", $query->getValues()[0]); + $this->assertEquals(['[Hello] World'], $query->getValues()); - $query = Query::parse('equal(1, "Hello\\\\")'); - $this->assertCount(1, $query->getValues()); - $this->assertEquals(1, $query->getAttribute()); - $this->assertEquals("Hello\\\\", $query->getValues()[0]); + $query = Query::parse([ + 'method' => 'equal', + 'attribute' => 1, + 'values' => ['(Hello) World'] + ]); - $query = Query::parse('equal(1, "Hello\\\\", "World")'); $this->assertCount(1, $query->getValues()); $this->assertEquals(1, $query->getAttribute()); - $this->assertEquals("Hello\\\\", $query->getValues()[0]); + $this->assertEquals(['(Hello) World'], $query->getValues()); - $query = Query::parse('equal(1, "Hello\\", World")'); - $this->assertCount(1, $query->getValues()); - $this->assertEquals(1, $query->getAttribute()); - $this->assertEquals("Hello\", World", $query->getValues()[0]); + $query = Query::parse([ + 'method' => 'equal', + 'attribute' => 1, + 'values' => ['Hello /\\ World'] + ]); - $query = Query::parse('equal(1, "Hello\\\\\\", ", "World")'); $this->assertCount(1, $query->getValues()); $this->assertEquals(1, $query->getAttribute()); - $this->assertEquals("Hello\\\\\", ", $query->getValues()[0]); - - $query = Query::parse('equal()'); - $this->assertCount(0, $query->getValues()); - $this->assertEquals('', $query->getAttribute()); - $this->assertEquals(null, $query->getValue()); - - $query = Query::parse('limit()'); - $this->assertCount(0, $query->getValues()); - $this->assertEquals('', $query->getAttribute()); - $this->assertEquals(null, $query->getValue()); - - $query = Query::parse('offset()'); - $this->assertCount(0, $query->getValues()); - $this->assertEquals('', $query->getAttribute()); - $this->assertEquals(null, $query->getValue()); - - $query = Query::parse('cursorAfter()'); - $this->assertCount(0, $query->getValues()); - $this->assertEquals('', $query->getAttribute()); - $this->assertEquals(null, $query->getValue()); - - $query = Query::parse('orderDesc()'); - $this->assertCount(0, $query->getValues()); - $this->assertEquals('', $query->getAttribute()); - $this->assertEquals(null, $query->getValue()); - - $query = Query::parse('equal("count", 0)'); - $this->assertCount(1, $query->getValues()); - $this->assertEquals("count", $query->getAttribute()); - $this->assertEquals(0, $query->getValue()); - - $query = Query::parse('equal("value", "NormalString")'); - $this->assertCount(1, $query->getValues()); - $this->assertEquals("value", $query->getAttribute()); - $this->assertEquals("NormalString", $query->getValue()); - - $query = Query::parse('equal("value", "{"type":"json","somekey":"someval"}")'); - $this->assertCount(1, $query->getValues()); - $this->assertEquals("value", $query->getAttribute()); - $this->assertEquals('{"type":"json","somekey":"someval"}', $query->getValue()); - - $query = Query::parse('equal("value", "{ NormalStringInBraces }")'); - $this->assertCount(1, $query->getValues()); - $this->assertEquals("value", $query->getAttribute()); - $this->assertEquals('{ NormalStringInBraces }', $query->getValue()); - - $query = Query::parse('equal("value", ""NormalStringInDoubleQuotes"")'); - $this->assertCount(1, $query->getValues()); - $this->assertEquals("value", $query->getAttribute()); - $this->assertEquals('"NormalStringInDoubleQuotes"', $query->getValue()); - - $query = Query::parse('equal("value", "{"NormalStringInDoubleQuotesAndBraces"}")'); - $this->assertCount(1, $query->getValues()); - $this->assertEquals("value", $query->getAttribute()); - $this->assertEquals('{"NormalStringInDoubleQuotesAndBraces"}', $query->getValue()); - - $query = Query::parse('equal("value", "\'NormalStringInSingleQuotes\'")'); - $this->assertCount(1, $query->getValues()); - $this->assertEquals("value", $query->getAttribute()); - $this->assertEquals('\'NormalStringInSingleQuotes\'', $query->getValue()); - - $query = Query::parse('equal("value", "{\'NormalStringInSingleQuotesAndBraces\'}")'); - $this->assertCount(1, $query->getValues()); - $this->assertEquals("value", $query->getAttribute()); - $this->assertEquals('{\'NormalStringInSingleQuotesAndBraces\'}', $query->getValue()); - - $query = Query::parse('equal("value", "SingleQuote\'InMiddle")'); - $this->assertCount(1, $query->getValues()); - $this->assertEquals("value", $query->getAttribute()); - $this->assertEquals('SingleQuote\'InMiddle', $query->getValue()); - - $query = Query::parse('equal("value", "DoubleQuote"InMiddle")'); - $this->assertCount(1, $query->getValues()); - $this->assertEquals("value", $query->getAttribute()); - $this->assertEquals('DoubleQuote"InMiddle', $query->getValue()); - - $query = Query::parse('equal("value", "Slash/InMiddle")'); - $this->assertCount(1, $query->getValues()); - $this->assertEquals("value", $query->getAttribute()); - $this->assertEquals('Slash/InMiddle', $query->getValue()); - - $query = Query::parse('equal("value", "Backslash\InMiddle")'); - $this->assertCount(1, $query->getValues()); - $this->assertEquals("value", $query->getAttribute()); - $this->assertEquals('Backslash\InMiddle', $query->getValue()); - - $query = Query::parse('equal("value", "Colon:InMiddle")'); - $this->assertCount(1, $query->getValues()); - $this->assertEquals("value", $query->getAttribute()); - $this->assertEquals('Colon:InMiddle', $query->getValue()); - - $query = Query::parse('equal("value", ""quoted":"colon"")'); - $this->assertCount(1, $query->getValues()); - $this->assertEquals("value", $query->getAttribute()); - $this->assertEquals('"quoted":"colon"', $query->getValue()); - } - - /* - Tests for aliases if we enable them: - public function testAlias(): void { - $query = Query::parse('eq(1)'); - $this->assertEquals(Query::TYPE_EQUAL, $query->getMethod()); - $query = Query::parse('lt(1)'); - $this->assertEquals(Query::TYPE_LESSER, $query->getMethod()); - $query = Query::parse('lte(1)'); - $this->assertEquals(Query::TYPE_LESSEREQUAL, $query->getMethod()); - $query = Query::parse('gt(1)'); - $this->assertEquals(Query::TYPE_GREATER, $query->getMethod()); - $query = Query::parse('gte(1)'); - $this->assertEquals(Query::TYPE_GREATEREQUAL, $query->getMethod()); - } - */ - - public function testParseComplex(): void - { - $queries = [ - Query::parse('equal("One",[55.55,\'Works\',true])'), - // Same query with random spaces - Query::parse('equal("One" , [55.55, \'Works\',true])') - ]; - - foreach ($queries as $query) { - $this->assertEquals('equal', $query->getMethod()); - - $this->assertIsString($query->getAttribute()); - $this->assertEquals('One', $query->getAttribute()); - - $this->assertCount(3, $query->getValues()); - - $this->assertIsNumeric($query->getValues()[0]); - $this->assertEquals(55.55, $query->getValues()[0]); - - $this->assertEquals('Works', $query->getValues()[1]); - - $this->assertTrue($query->getValues()[2]); - } - } - - public function testGetAttribute(): void - { - $query = Query::parse('equal("title", "Iron Man")'); - - $this->assertIsArray($query->getValues()); - $this->assertCount(1, $query->getValues()); - $this->assertEquals('title', $query->getAttribute()); - $this->assertEquals('Iron Man', $query->getValues()[0]); - } - - public function testGetMethod(): void - { - $query = Query::parse('equal("title", "Iron Man")'); - - $this->assertEquals('equal', $query->getMethod()); + $this->assertEquals(['Hello /\ World'], $query->getValues()); } public function testisMethod(): void @@ -462,26 +346,17 @@ public function testisMethod(): void $this->assertTrue(Query::isMethod(Query::TYPE_GREATER_EQUAL)); $this->assertTrue(Query::isMethod(Query::TYPE_CONTAINS)); $this->assertTrue(Query::isMethod(QUERY::TYPE_SEARCH)); - $this->assertTrue(Query::isMethod(QUERY::TYPE_ORDERASC)); - $this->assertTrue(Query::isMethod(QUERY::TYPE_ORDERDESC)); + $this->assertTrue(Query::isMethod(QUERY::TYPE_ORDER_ASC)); + $this->assertTrue(Query::isMethod(QUERY::TYPE_ORDER_DESC)); $this->assertTrue(Query::isMethod(QUERY::TYPE_LIMIT)); $this->assertTrue(Query::isMethod(QUERY::TYPE_OFFSET)); - $this->assertTrue(Query::isMethod(QUERY::TYPE_CURSORAFTER)); - $this->assertTrue(Query::isMethod(QUERY::TYPE_CURSORBEFORE)); + $this->assertTrue(Query::isMethod(QUERY::TYPE_CURSOR_AFTER)); + $this->assertTrue(Query::isMethod(QUERY::TYPE_CURSOR_BEFORE)); $this->assertTrue(Query::isMethod(QUERY::TYPE_IS_NULL)); $this->assertTrue(Query::isMethod(QUERY::TYPE_IS_NOT_NULL)); $this->assertTrue(Query::isMethod(QUERY::TYPE_BETWEEN)); $this->assertTrue(Query::isMethod(QUERY::TYPE_SELECT)); - /* - Tests for aliases if we enable them: - $this->assertTrue(Query::isMethod('lt')); - $this->assertTrue(Query::isMethod('lte')); - $this->assertTrue(Query::isMethod('gt')); - $this->assertTrue(Query::isMethod('gte')); - $this->assertTrue(Query::isMethod('eq')); - */ - $this->assertFalse(Query::isMethod('invalid')); $this->assertFalse(Query::isMethod('lte ')); } diff --git a/tests/Database/Validator/DocumentQueriesTest.php b/tests/Database/Validator/DocumentQueriesTest.php index aac1c235d..a47900c79 100644 --- a/tests/Database/Validator/DocumentQueriesTest.php +++ b/tests/Database/Validator/DocumentQueriesTest.php @@ -63,7 +63,7 @@ public function testValidQueries(): void $validator = new DocumentQueries($this->collection['attributes']); $queries = [ - 'select(["title"])', + Query::select(['title']), ]; $this->assertEquals(true, $validator->isValid($queries)); @@ -78,8 +78,7 @@ public function testValidQueries(): void public function testInvalidQueries(): void { $validator = new DocumentQueries($this->collection['attributes']); - - $queries = [Query::limit(1)]; // We only accept Select queries + $queries = [Query::limit(1)]; $this->assertEquals(false, $validator->isValid($queries)); } } diff --git a/tests/Database/Validator/DocumentsQueriesTest.php b/tests/Database/Validator/DocumentsQueriesTest.php index e928e6785..17109d0c3 100644 --- a/tests/Database/Validator/DocumentsQueriesTest.php +++ b/tests/Database/Validator/DocumentsQueriesTest.php @@ -116,30 +116,95 @@ public function testValidQueries(): void $validator = new Documents($this->collection['attributes'], $this->collection['indexes']); $queries = [ - 'equal("description", "Best movie ever")', - 'equal("description", [""])', - 'lessThanEqual("price", 6.50)', - 'lessThan("price", 6.50)', - 'greaterThan("rating", 4)', - 'greaterThan("rating", 0)', - 'greaterThanEqual("rating", 6)', - 'between("price", 1.50, 6.50)', - 'search("title", "SEO")', - 'startsWith("title", "Good")', - 'endsWith("title", "Night")', - 'isNull("title")', - 'isNotNull("title")', - 'cursorAfter("a")', - 'cursorBefore("b")', - 'orderAsc("title")', - 'limit(10)', - 'offset(10)', + [ + 'method' => 'equal', + 'attribute' => 'description', + 'values' => ['Best movie ever'] + ], + [ + 'method' => 'equal', + 'attribute' => 'description', + 'values' => [''] + ], + [ + 'method' => 'lessThanEqual', + 'attribute' => 'price', + 'values' => [6.50] + ], + [ + 'method' => 'lessThan', + 'attribute' => 'price', + 'values' => [6.50] + ], + [ + 'method' => 'greaterThan', + 'attribute' => 'rating', + 'values' => [4] + ], + [ + 'method' => 'greaterThan', + 'attribute' => 'rating', + 'values' => [0] + ], + [ + 'method' => 'greaterThanEqual', + 'attribute' => 'rating', + 'values' => [6] + ], + [ + 'method' => 'between', + 'attribute' => 'price', + 'values' => [1.50, 6.50] + ], + [ + 'method' => 'search', + 'attribute' => 'title', + 'values' => ['SEO'] + ], + [ + 'method' => 'startsWith', + 'attribute' => 'title', + 'values' => ['Good'] + ], + [ + 'method' => 'endsWith', + 'attribute' => 'title', + 'values' => ['Night'] + ], + [ + 'method' => 'isNull', + 'attribute' => 'title', + ], + [ + 'method' => 'isNotNull', + 'attribute' => 'title', + ], + [ + 'method' => 'cursorAfter', + 'values' => ['a'], + ], + [ + 'method' => 'cursorBefore', + 'values' => ['b'], + ], + [ + 'method' => 'orderAsc', + 'attribute' => 'title', + ], + [ + 'method' => 'limit', + 'values' => [10] + ], + [ + 'method' => 'offset', + 'values' => [10] + ] ]; - $queries[] = Query::orderDesc(''); + $queries[] = Query::orderDesc(); $this->assertEquals(true, $validator->isValid($queries)); - $queries = ['equal("is_bool", false)']; + $queries = [Query::equal('is_bool', [false])]; $this->assertEquals(true, $validator->isValid($queries)); } @@ -150,30 +215,42 @@ public function testInvalidQueries(): void { $validator = new Documents($this->collection['attributes'], $this->collection['indexes']); - $this->assertEquals(false, $validator->isValid(['notEqual("title", ["Iron Man", "Ant Man"])',])); - $this->assertEquals('Invalid query: NotEqual queries require exactly one value.', $validator->getDescription()); - - $queries = ['search("description", "iron")']; - $this->assertEquals(false, $validator->isValid($queries)); - $this->assertEquals('Searching by attribute "description" requires a fulltext index.', $validator->getDescription()); - - $queries = ['equal("not_found", 4)']; + $queries = [[ + 'method' => 'notEqual', + 'attribute' => 'title', + 'values' => ['Iron Man', 'Ant Man'] + ]]; $this->assertEquals(false, $validator->isValid($queries)); - $this->assertEquals('Invalid query: Attribute not found in schema: not_found', $validator->getDescription()); + $this->assertEquals('Invalid query: NotEqual queries require exactly one value.', $validator->getDescription()); - $queries = ['search("description", "iron")']; + $queries = [[ + 'method' => 'search', + 'attribute' => 'description', + 'values' => ['iron'] + ]]; $this->assertEquals(false, $validator->isValid($queries)); $this->assertEquals('Searching by attribute "description" requires a fulltext index.', $validator->getDescription()); - $queries = ['equal("not_found", 4)']; + $queries = [[ + 'method' => 'equal', + 'attribute' => 'not_found', + 'values' => [4] + ]]; $this->assertEquals(false, $validator->isValid($queries)); $this->assertEquals('Invalid query: Attribute not found in schema: not_found', $validator->getDescription()); - $queries = ['limit(-1)']; + $queries = [[ + 'method' => 'limit', + 'values' => [-1] + ]]; $this->assertEquals(false, $validator->isValid($queries)); $this->assertEquals('Invalid query: Invalid limit: Value must be a valid range between 1 and ' . number_format(PHP_INT_MAX), $validator->getDescription()); - $queries = ['equal("title", [])']; // empty array + $queries = [[ + 'method' => 'equal', + 'attribute' => 'title', + 'values' => [] + ]]; // empty array $this->assertEquals(false, $validator->isValid($queries)); $this->assertEquals('Invalid query: Equal queries require at least one value.', $validator->getDescription()); } diff --git a/tests/Database/Validator/IndexedQueriesTest.php b/tests/Database/Validator/IndexedQueriesTest.php index 764626fd5..7e4d83e01 100644 --- a/tests/Database/Validator/IndexedQueriesTest.php +++ b/tests/Database/Validator/IndexedQueriesTest.php @@ -86,17 +86,41 @@ public function testValid(): void ] ); - $this->assertEquals(true, $validator->isValid(['cursorAfter("asdf")']), $validator->getDescription()); + $this->assertEquals(true, $validator->isValid([[ + 'method' => 'cursorAfter', + 'attribute' => null, + 'values' => ['asdf'], + ]]), $validator->getDescription()); $this->assertEquals(true, $validator->isValid([Query::cursorAfter(new Document(['$id' => 'asdf']))]), $validator->getDescription()); - $this->assertEquals(true, $validator->isValid(['equal("name", "value")']), $validator->getDescription()); + $this->assertEquals(true, $validator->isValid([[ + 'method' => 'equal', + 'attribute' => 'name', + 'values' => ['value'], + ]]), $validator->getDescription()); $this->assertEquals(true, $validator->isValid([Query::equal('name', ['value'])]), $validator->getDescription()); - $this->assertEquals(true, $validator->isValid(['limit(10)']), $validator->getDescription()); + $this->assertEquals(true, $validator->isValid([[ + 'method' => 'limit', + 'attribute' => null, + 'values' => [10], + ]]), $validator->getDescription()); $this->assertEquals(true, $validator->isValid([Query::limit(10)]), $validator->getDescription()); - $this->assertEquals(true, $validator->isValid(['offset(10)']), $validator->getDescription()); + $this->assertEquals(true, $validator->isValid([[ + 'method' => 'offset', + 'attribute' => null, + 'values' => [10], + ]]), $validator->getDescription()); $this->assertEquals(true, $validator->isValid([Query::offset(10)]), $validator->getDescription()); - $this->assertEquals(true, $validator->isValid(['orderAsc("name")']), $validator->getDescription()); + $this->assertEquals(true, $validator->isValid([[ + 'method' => 'orderAsc', + 'attribute' => 'name', + 'values' => [], + ]]), $validator->getDescription()); $this->assertEquals(true, $validator->isValid([Query::orderAsc('name')]), $validator->getDescription()); - $this->assertEquals(true, $validator->isValid(['search("name", "value")']), $validator->getDescription()); + $this->assertEquals(true, $validator->isValid([[ + 'method' => 'search', + 'attribute' => 'name', + 'values' => ['value'], + ]]), $validator->getDescription()); $this->assertEquals(true, $validator->isValid([Query::search('name', 'value')]), $validator->getDescription()); } @@ -129,9 +153,20 @@ public function testMissingIndex(): void ] ); - $this->assertEquals(false, $validator->isValid(['equal("dne", "value")']), $validator->getDescription()); - $this->assertEquals(false, $validator->isValid(['orderAsc("dne")']), $validator->getDescription()); - $this->assertEquals(false, $validator->isValid(['search("name", "value")']), $validator->getDescription()); + $this->assertEquals(false, $validator->isValid([[ + 'type' => 'equal', + 'attribute' => 'dne', + 'values' => ['value'] + ]]), $validator->getDescription()); + $this->assertEquals(false, $validator->isValid([[ + 'type' => 'orderAsc', + 'attribute' => 'dne', + ]]), $validator->getDescription()); + $this->assertEquals(false, $validator->isValid([[ + 'type' => 'search', + 'attribute' => 'name', + 'values' => ['value'] + ]]), $validator->getDescription()); } public function testTwoAttributesFulltext(): void diff --git a/tests/Database/Validator/QueriesTest.php b/tests/Database/Validator/QueriesTest.php index 20afc1ee3..65e18f6ef 100644 --- a/tests/Database/Validator/QueriesTest.php +++ b/tests/Database/Validator/QueriesTest.php @@ -6,6 +6,7 @@ use PHPUnit\Framework\TestCase; use Utopia\Database\Database; use Utopia\Database\Document; +use Utopia\Database\Query; use Utopia\Database\Validator\Queries; use Utopia\Database\Validator\Query\Cursor; use Utopia\Database\Validator\Query\Filter; @@ -30,26 +31,19 @@ public function testEmptyQueries(): void $this->assertEquals(true, $validator->isValid([])); } - public function testInvalidQuery(): void - { - $validator = new Queries(); - - $this->assertEquals(false, $validator->isValid(["this.is.invalid"])); - } - public function testInvalidMethod(): void { $validator = new Queries(); - $this->assertEquals(false, $validator->isValid(['equal("attr", "value")'])); + $this->assertEquals(false, $validator->isValid([Query::equal('attr', ["value"])])); $validator = new Queries([new Limit()]); - $this->assertEquals(false, $validator->isValid(['equal("attr", "value")'])); + $this->assertEquals(false, $validator->isValid([Query::equal('attr', ["value"])])); } public function testInvalidValue(): void { $validator = new Queries([new Limit()]); - $this->assertEquals(false, $validator->isValid(['limit(-1)'])); + $this->assertEquals(false, $validator->isValid([Query::limit(-1)])); } /** @@ -76,10 +70,10 @@ public function testValid(): void ] ); - $this->assertEquals(true, $validator->isValid(['cursorAfter("asdf")']), $validator->getDescription()); - $this->assertEquals(true, $validator->isValid(['equal("name", "value")']), $validator->getDescription()); - $this->assertEquals(true, $validator->isValid(['limit(10)']), $validator->getDescription()); - $this->assertEquals(true, $validator->isValid(['offset(10)']), $validator->getDescription()); - $this->assertEquals(true, $validator->isValid(['orderAsc("name")']), $validator->getDescription()); + $this->assertEquals(true, $validator->isValid([Query::cursorAfter(new Document(['$id' => 'asdf']))]), $validator->getDescription()); + $this->assertEquals(true, $validator->isValid([Query::equal('name', ['value'])]), $validator->getDescription()); + $this->assertEquals(true, $validator->isValid([Query::limit(10)]), $validator->getDescription()); + $this->assertEquals(true, $validator->isValid([Query::offset(10)]), $validator->getDescription()); + $this->assertEquals(true, $validator->isValid([Query::orderAsc('name')]), $validator->getDescription()); } } diff --git a/tests/Database/Validator/Query/CursorTest.php b/tests/Database/Validator/Query/CursorTest.php index f68d2bd3a..f2ca6fb67 100644 --- a/tests/Database/Validator/Query/CursorTest.php +++ b/tests/Database/Validator/Query/CursorTest.php @@ -12,8 +12,8 @@ public function testValueSuccess(): void { $validator = new Cursor(); - $this->assertTrue($validator->isValid(new Query(Query::TYPE_CURSORAFTER, values: ['asdf']))); - $this->assertTrue($validator->isValid(new Query(Query::TYPE_CURSORBEFORE, values: ['asdf']))); + $this->assertTrue($validator->isValid(new Query(Query::TYPE_CURSOR_AFTER, values: ['asdf']))); + $this->assertTrue($validator->isValid(new Query(Query::TYPE_CURSOR_BEFORE, values: ['asdf']))); } public function testValueFailure(): void diff --git a/tests/Database/Validator/Query/FilterTest.php b/tests/Database/Validator/Query/FilterTest.php index 752dd97a3..2aac3561b 100644 --- a/tests/Database/Validator/Query/FilterTest.php +++ b/tests/Database/Validator/Query/FilterTest.php @@ -54,43 +54,16 @@ public function testFailure(): void $this->assertFalse($this->validator->isValid(Query::equal('', ['v']))); $this->assertFalse($this->validator->isValid(Query::orderAsc('attr'))); $this->assertFalse($this->validator->isValid(Query::orderDesc('attr'))); - $this->assertFalse($this->validator->isValid(new Query(Query::TYPE_CURSORAFTER, values: ['asdf']))); - $this->assertFalse($this->validator->isValid(new Query(Query::TYPE_CURSORBEFORE, values: ['asdf']))); - } - - public function testTypeMissmatch(): void - { - $this->assertFalse($this->validator->isValid(Query::parse('equal("attr", false)'))); - $this->assertEquals('Query type does not match expected: string', $this->validator->getDescription()); - - $this->assertFalse($this->validator->isValid(Query::parse('equal("attr", null)'))); - $this->assertEquals('Query type does not match expected: string', $this->validator->getDescription()); + $this->assertFalse($this->validator->isValid(new Query(Query::TYPE_CURSOR_AFTER, values: ['asdf']))); + $this->assertFalse($this->validator->isValid(new Query(Query::TYPE_CURSOR_BEFORE, values: ['asdf']))); } public function testEmptyValues(): void { - $this->assertFalse($this->validator->isValid(Query::parse('notEqual("attr", [])'))); - $this->assertEquals('NotEqual queries require exactly one value.', $this->validator->getDescription()); - - $this->assertFalse($this->validator->isValid(Query::parse('contains("attr", [])'))); + $this->assertFalse($this->validator->isValid(Query::contains('attr', []))); $this->assertEquals('Contains queries require at least one value.', $this->validator->getDescription()); - $this->assertFalse($this->validator->isValid(Query::parse('equal("attr", [])'))); + $this->assertFalse($this->validator->isValid(Query::equal('attr', []))); $this->assertEquals('Equal queries require at least one value.', $this->validator->getDescription()); - - $this->assertFalse($this->validator->isValid(Query::parse('lessThan("attr", [])'))); - $this->assertEquals('LessThan queries require exactly one value.', $this->validator->getDescription()); - - $this->assertFalse($this->validator->isValid(Query::parse('lessThanEqual("attr", [])'))); - $this->assertEquals('LessThanEqual queries require exactly one value.', $this->validator->getDescription()); - - $this->assertFalse($this->validator->isValid(Query::parse('search("attr", [])'))); - $this->assertEquals('Search queries require exactly one value.', $this->validator->getDescription()); - - $this->assertFalse($this->validator->isValid(Query::parse('greaterThanEqual("attr", [])'))); - $this->assertEquals('GreaterThanEqual queries require exactly one value.', $this->validator->getDescription()); - - $this->assertFalse($this->validator->isValid(Query::parse('greaterThan("attr", [])'))); - $this->assertEquals('GreaterThan queries require exactly one value.', $this->validator->getDescription()); } } diff --git a/tests/Database/Validator/Query/OrderTest.php b/tests/Database/Validator/Query/OrderTest.php index c7a0d7826..40d4f05e2 100644 --- a/tests/Database/Validator/Query/OrderTest.php +++ b/tests/Database/Validator/Query/OrderTest.php @@ -5,6 +5,7 @@ use PHPUnit\Framework\TestCase; use Utopia\Database\Database; use Utopia\Database\Document; +use Utopia\Database\Exception; use Utopia\Database\Query; use Utopia\Database\Validator\Query\Base; use Utopia\Database\Validator\Query\Order; @@ -13,6 +14,9 @@ class OrderTest extends TestCase { protected Base|null $validator = null; + /** + * @throws Exception + */ public function setUp(): void { $this->validator = new Order( @@ -30,9 +34,9 @@ public function setUp(): void public function testValueSuccess(): void { $this->assertTrue($this->validator->isValid(Query::orderAsc('attr'))); - $this->assertTrue($this->validator->isValid(Query::orderAsc(''))); + $this->assertTrue($this->validator->isValid(Query::orderAsc())); $this->assertTrue($this->validator->isValid(Query::orderDesc('attr'))); - $this->assertTrue($this->validator->isValid(Query::orderDesc(''))); + $this->assertTrue($this->validator->isValid(Query::orderDesc())); } public function testValueFailure(): void diff --git a/tests/Database/Validator/Query/SelectTest.php b/tests/Database/Validator/Query/SelectTest.php index a4972bbed..3d0a7cbf4 100644 --- a/tests/Database/Validator/Query/SelectTest.php +++ b/tests/Database/Validator/Query/SelectTest.php @@ -5,6 +5,7 @@ use PHPUnit\Framework\TestCase; use Utopia\Database\Database; use Utopia\Database\Document; +use Utopia\Database\Exception; use Utopia\Database\Query; use Utopia\Database\Validator\Query\Base; use Utopia\Database\Validator\Query\Select; @@ -13,6 +14,9 @@ class SelectTest extends TestCase { protected Base|null $validator = null; + /** + * @throws Exception + */ public function setUp(): void { $this->validator = new Select( diff --git a/tests/Database/Validator/QueryTest.php b/tests/Database/Validator/QueryTest.php index 76f78c1a5..a66945121 100644 --- a/tests/Database/Validator/QueryTest.php +++ b/tests/Database/Validator/QueryTest.php @@ -110,40 +110,27 @@ public function testQuery(): void { $validator = new Documents($this->attributes, []); - $this->assertEquals(true, $validator->isValid([Query::parse('equal("$id", ["Iron Man", "Ant Man"])')])); - $this->assertEquals(true, $validator->isValid([Query::parse('equal("$id", "Iron Man")')])); - $this->assertEquals(true, $validator->isValid([Query::parse('equal("description", "Best movie ever")')])); - $this->assertEquals(true, $validator->isValid([Query::parse('greaterThan("rating", 4)')])); - $this->assertEquals(true, $validator->isValid([Query::parse('notEqual("title", ["Iron Man"])')])); - $this->assertEquals(true, $validator->isValid([Query::parse('lessThan("price", 6.50)')])); - $this->assertEquals(true, $validator->isValid([Query::parse('lessThanEqual("price", 6)')])); - $this->assertEquals(true, $validator->isValid([Query::parse('contains("tags", ["action1", "action2"])')])); - $this->assertEquals(true, $validator->isValid([Query::parse('contains("tags", "action1")')])); - $this->assertEquals(true, $validator->isValid([Query::parse('cursorAfter("docId")')])); - $this->assertEquals(true, $validator->isValid([Query::parse('cursorBefore("docId")')])); - $this->assertEquals(true, $validator->isValid([Query::parse('orderAsc("title")')])); - $this->assertEquals(true, $validator->isValid([Query::parse('orderDesc("title")')])); - $this->assertEquals(true, $validator->isValid([Query::parse('isNull("title")')])); - $this->assertEquals(true, $validator->isValid([Query::parse('isNotNull("title")')])); - $this->assertEquals(true, $validator->isValid([Query::parse('between("price", 1.5, 10.9)')])); - $this->assertEquals(true, $validator->isValid([Query::parse('between("birthDay","2024-01-01", "2023-01-01")')])); - $this->assertEquals(true, $validator->isValid([Query::parse('startsWith("title", "Fro")')])); - $this->assertEquals(true, $validator->isValid([Query::parse('endsWith("title", "Zen")')])); - $this->assertEquals(true, $validator->isValid([Query::parse('select(["title", "description"])')])); - $this->assertEquals(true, $validator->isValid([Query::parse('notEqual("title", [""])')])); - } - - /** - * @throws Exception - */ - public function testInvalidMethod(): void - { - $validator = new Documents($this->attributes, []); - - $this->assertEquals(false, $validator->isValid([Query::parse('eqqual("title", "Iron Man")')])); - $this->assertEquals('Invalid query method: eqqual', $validator->getDescription()); - - $this->assertEquals(false, $validator->isValid([Query::parse('notEqual("title", ["Iron Man", "Ant Man"])')])); + $this->assertEquals(true, $validator->isValid([Query::equal('$id', ['Iron Man', 'Ant Man'])])); + $this->assertEquals(true, $validator->isValid([Query::equal('$id', ['Iron Man'])])); + $this->assertEquals(true, $validator->isValid([Query::equal('description', ['Best movie ever'])])); + $this->assertEquals(true, $validator->isValid([Query::greaterThan('rating', 4)])); + $this->assertEquals(true, $validator->isValid([Query::notEqual('title', 'Iron Man')])); + $this->assertEquals(true, $validator->isValid([Query::lessThan('price', 6.50)])); + $this->assertEquals(true, $validator->isValid([Query::lessThanEqual('price', 6)])); + $this->assertEquals(true, $validator->isValid([Query::contains('tags', ['action1', 'action2'])])); + $this->assertEquals(true, $validator->isValid([Query::contains('tags', ['action1'])])); + $this->assertEquals(true, $validator->isValid([Query::cursorAfter(new Document(['$id' => 'docId']))])); + $this->assertEquals(true, $validator->isValid([Query::cursorBefore(new Document(['$id' => 'docId']))])); + $this->assertEquals(true, $validator->isValid([Query::orderAsc('title')])); + $this->assertEquals(true, $validator->isValid([Query::orderDesc('title')])); + $this->assertEquals(true, $validator->isValid([Query::isNull('title')])); + $this->assertEquals(true, $validator->isValid([Query::isNotNull('title')])); + $this->assertEquals(true, $validator->isValid([Query::between('price', 1.5, 10.9)])); + $this->assertEquals(true, $validator->isValid([Query::between('birthDay', '2024-01-01', '2023-01-01')])); + $this->assertEquals(true, $validator->isValid([Query::startsWith('title', 'Fro')])); + $this->assertEquals(true, $validator->isValid([Query::endsWith('title', 'Zen')])); + $this->assertEquals(true, $validator->isValid([Query::select(['title', 'description'])])); + $this->assertEquals(true, $validator->isValid([Query::notEqual('title', '')])); } /** @@ -153,12 +140,19 @@ public function testAttributeNotFound(): void { $validator = new Documents($this->attributes, []); - $response = $validator->isValid([Query::parse('equal("name", "Iron Man")')]); + $response = $validator->isValid([Query::parse([ + 'method' => 'equal', + 'attribute' => 'name', + 'values' => ['Iron Man'] + ])]); $this->assertEquals(false, $response); $this->assertEquals('Invalid query: Attribute not found in schema: name', $validator->getDescription()); - $response = $validator->isValid([Query::parse('orderAsc("name")')]); + $response = $validator->isValid([Query::parse([ + 'method' => 'orderAsc', + 'attribute' => 'name', + ])]); $this->assertEquals(false, $response); $this->assertEquals('Invalid query: Attribute not found in schema: name', $validator->getDescription()); @@ -171,7 +165,11 @@ public function testAttributeWrongType(): void { $validator = new Documents($this->attributes, []); - $response = $validator->isValid([Query::parse('equal("title", 1776)')]); + $response = $validator->isValid([Query::parse([ + 'method' => 'equal', + 'attribute' => 'title', + 'values' => [1776] + ])]); $this->assertEquals(false, $response); $this->assertEquals('Invalid query: Query type does not match expected: string', $validator->getDescription()); @@ -183,7 +181,7 @@ public function testAttributeWrongType(): void public function testQueryDate(): void { $validator = new Documents($this->attributes, []); - $response = $validator->isValid([Query::parse('greaterThan("birthDay", "1960-01-01 10:10:10")')]); + $response = $validator->isValid([Query::greaterThan('birthDay', '1960-01-01 10:10:10')]); $this->assertEquals(true, $response); } @@ -194,16 +192,10 @@ public function testQueryLimit(): void { $validator = new Documents($this->attributes, []); - $response = $validator->isValid([Query::parse('limit(25)')]); + $response = $validator->isValid([Query::limit(25)]); $this->assertEquals(true, $response); - $response = $validator->isValid([Query::parse('limit()')]); - $this->assertEquals(false, $response); - - $response = $validator->isValid([Query::parse('limit(-1)')]); - $this->assertEquals(false, $response); - - $response = $validator->isValid([Query::parse('limit("aaa")')]); + $response = $validator->isValid([Query::limit(-1)]); $this->assertEquals(false, $response); } @@ -214,16 +206,10 @@ public function testQueryOffset(): void { $validator = new Documents($this->attributes, []); - $response = $validator->isValid([Query::parse('offset(25)')]); + $response = $validator->isValid([Query::offset(25)]); $this->assertEquals(true, $response); - $response = $validator->isValid([Query::parse('offset()')]); - $this->assertEquals(false, $response); - - $response = $validator->isValid([Query::parse('offset(-1)')]); - $this->assertEquals(false, $response); - - $response = $validator->isValid([Query::parse('offset("aaa")')]); + $response = $validator->isValid([Query::offset(-1)]); $this->assertEquals(false, $response); } @@ -234,16 +220,16 @@ public function testQueryOrder(): void { $validator = new Documents($this->attributes, []); - $response = $validator->isValid([Query::parse('orderAsc("title")')]); + $response = $validator->isValid([Query::orderAsc('title')]); $this->assertEquals(true, $response); - $response = $validator->isValid([Query::parse('orderAsc("")')]); + $response = $validator->isValid([Query::orderAsc('')]); $this->assertEquals(true, $response); - $response = $validator->isValid([Query::parse('orderAsc()')]); + $response = $validator->isValid([Query::orderAsc()]); $this->assertEquals(true, $response); - $response = $validator->isValid([Query::parse('orderAsc("doesNotExist")')]); + $response = $validator->isValid([Query::orderAsc('doesNotExist')]); $this->assertEquals(false, $response); } @@ -254,11 +240,8 @@ public function testQueryCursor(): void { $validator = new Documents($this->attributes, []); - $response = $validator->isValid([Query::parse('cursorAfter("asdf")')]); + $response = $validator->isValid([Query::cursorAfter(new Document(['$id' => 'asdf']))]); $this->assertEquals(true, $response); - - $response = $validator->isValid([Query::parse('cursorAfter()')]); - $this->assertEquals(false, $response); } /** @@ -273,10 +256,10 @@ public function testQueryGetByType(): void Query::cursorAfter(new Document([])), ]; - $queries = Query::getByType($queries, [Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE]); + $queries = Query::getByType($queries, [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]); $this->assertCount(2, $queries); foreach ($queries as $query) { - $this->assertEquals(true, in_array($query->getMethod(), [Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE])); + $this->assertEquals(true, in_array($query->getMethod(), [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE])); } } @@ -305,9 +288,6 @@ public function testQueryEmpty(): void $response = $validator->isValid([Query::equal('price', [])]); $this->assertEquals(false, $response); - $response = $validator->isValid([Query::greaterThan('price', null)]); - $this->assertEquals(false, $response); - $response = $validator->isValid([Query::isNull('price')]); $this->assertEquals(true, $response); }