Skip to content

Commit edd0871

Browse files
GromNaNalcaeus
authored andcommitted
PHPORM-46 Throw an exception when Query\Builder::orderBy() is used with invalid direction (#7)
* Convert only strings, let the driver fail for int values * Add more tests on Builder::orderBy
1 parent 933073d commit edd0871

File tree

2 files changed

+88
-1
lines changed

2 files changed

+88
-1
lines changed

Diff for: src/Query/Builder.php

+6-1
Original file line numberDiff line numberDiff line change
@@ -513,11 +513,16 @@ public function distinct($column = false)
513513

514514
/**
515515
* @inheritdoc
516+
* @param int|string|array $direction
516517
*/
517518
public function orderBy($column, $direction = 'asc')
518519
{
519520
if (is_string($direction)) {
520-
$direction = (strtolower($direction) == 'asc' ? 1 : -1);
521+
$direction = match ($direction) {
522+
'asc', 'ASC' => 1,
523+
'desc', 'DESC' => -1,
524+
default => throw new \InvalidArgumentException('Order direction must be "asc" or "desc".'),
525+
};
521526
}
522527

523528
if ($column == 'natural') {

Diff for: tests/Query/BuilderTest.php

+82
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Jenssegers\Mongodb\Tests\Query;
66

77
use DateTimeImmutable;
8+
use Illuminate\Tests\Database\DatabaseQueryBuilderTest;
89
use Jenssegers\Mongodb\Connection;
910
use Jenssegers\Mongodb\Query\Builder;
1011
use Jenssegers\Mongodb\Query\Processor;
@@ -63,6 +64,66 @@ public static function provideQueryBuilderToMql(): iterable
6364
fn (Builder $builder) => $builder->limit(10)->offset(5)->select('foo', 'bar'),
6465
];
6566

67+
/** @see DatabaseQueryBuilderTest::testOrderBys() */
68+
yield 'orderBy multiple columns' => [
69+
['find' => [[], ['sort' => ['email' => 1, 'age' => -1]]]],
70+
fn (Builder $builder) => $builder
71+
->orderBy('email')
72+
->orderBy('age', 'desc'),
73+
];
74+
75+
yield 'orders = null' => [
76+
['find' => [[], []]],
77+
function (Builder $builder) {
78+
$builder->orders = null;
79+
80+
return $builder;
81+
},
82+
];
83+
84+
yield 'orders = []' => [
85+
['find' => [[], []]],
86+
function (Builder $builder) {
87+
$builder->orders = [];
88+
89+
return $builder;
90+
},
91+
];
92+
93+
yield 'multiple orders with direction' => [
94+
['find' => [[], ['sort' => ['email' => -1, 'age' => 1]]]],
95+
fn (Builder $builder) => $builder
96+
->orderBy('email', -1)
97+
->orderBy('age', 1),
98+
];
99+
100+
yield 'orderByDesc' => [
101+
['find' => [[], ['sort' => ['email' => -1]]]],
102+
fn (Builder $builder) => $builder->orderByDesc('email'),
103+
];
104+
105+
/** @see DatabaseQueryBuilderTest::testReorder() */
106+
yield 'reorder reset' => [
107+
['find' => [[], []]],
108+
fn (Builder $builder) => $builder->orderBy('name')->reorder(),
109+
];
110+
111+
yield 'reorder column' => [
112+
['find' => [[], ['sort' => ['name' => -1]]]],
113+
fn (Builder $builder) => $builder->orderBy('name')->reorder('name', 'desc'),
114+
];
115+
116+
/** @link https://www.mongodb.com/docs/manual/reference/method/cursor.sort/#text-score-metadata-sort */
117+
yield 'orderBy array meta' => [
118+
['find' => [
119+
['$text' => ['$search' => 'operating']],
120+
['sort' => ['score' => ['$meta' => 'textScore']]],
121+
]],
122+
fn (Builder $builder) => $builder
123+
->where('$text', ['$search' => 'operating'])
124+
->orderBy('score', ['$meta' => 'textScore']),
125+
];
126+
66127
yield 'distinct' => [
67128
['distinct' => ['foo', [], []]],
68129
fn (Builder $builder) => $builder->distinct('foo'),
@@ -74,6 +135,27 @@ public static function provideQueryBuilderToMql(): iterable
74135
];
75136
}
76137

138+
/**
139+
* @dataProvider provideExceptions
140+
*/
141+
public function testException($class, $message, \Closure $build): void
142+
{
143+
$builder = self::getBuilder();
144+
145+
$this->expectException($class);
146+
$this->expectExceptionMessage($message);
147+
$build($builder);
148+
}
149+
150+
public static function provideExceptions(): iterable
151+
{
152+
yield 'orderBy invalid direction' => [
153+
\InvalidArgumentException::class,
154+
'Order direction must be "asc" or "desc"',
155+
fn (Builder $builder) => $builder->orderBy('_id', 'dasc'),
156+
];
157+
}
158+
77159
private static function getBuilder(): Builder
78160
{
79161
$connection = m::mock(Connection::class);

0 commit comments

Comments
 (0)