Skip to content

Commit e6c2564

Browse files
jenkins-botGerrit Code Review
authored andcommitted
Merge "Search: Validate pagination query params for SimplePropertySearch"
2 parents 26c09cc + ba61974 commit e6c2564

File tree

3 files changed

+103
-8
lines changed

3 files changed

+103
-8
lines changed

repo/domains/search/src/Application/UseCases/SimplePropertySearch/SimplePropertySearchValidator.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@
1010
* @license GPL-2.0-or-later
1111
*/
1212
class SimplePropertySearchValidator {
13+
1314
public const LANGUAGE_QUERY_PARAM = 'language';
15+
public const LIMIT_QUERY_PARAM = 'limit';
16+
public const OFFSET_QUERY_PARAM = 'offset';
17+
18+
private const MAX_LIMIT = 500;
1419

1520
private SearchLanguageValidator $languageValidator;
1621

@@ -38,5 +43,20 @@ public function validate( SimplePropertySearchRequest $request ): void {
3843
throw new LogicException( 'unknown validation error code ' . $validationError->getCode() );
3944
}
4045
}
46+
47+
$this->validateLimitAndOffset( $request );
48+
}
49+
50+
private function validateLimitAndOffset( SimplePropertySearchRequest $request ): void {
51+
$limit = $request->getLimit();
52+
$offset = $request->getOffset();
53+
54+
if ( $limit < 0 || $limit > self::MAX_LIMIT ) {
55+
throw UseCaseError::invalidQueryParameter( self::LIMIT_QUERY_PARAM );
56+
}
57+
58+
if ( $offset < 0 ) {
59+
throw UseCaseError::invalidQueryParameter( self::OFFSET_QUERY_PARAM );
60+
}
4161
}
4262
}

repo/domains/search/tests/mocha/api-testing/SimplePropertySearchTest.js

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ function newSearchRequest( language, searchTerm ) {
1818
.withQueryParam( 'q', searchTerm );
1919
}
2020

21+
function assertValidError( response, statusCode, responseBodyErrorCode, context ) {
22+
expect( response ).to.have.status( statusCode );
23+
assert.header( response, 'Content-Language', 'en' );
24+
assert.strictEqual( response.body.code, responseBodyErrorCode );
25+
assert.deepStrictEqual( response.body.context, context );
26+
}
27+
2128
describe( 'Simple property search', () => {
2229
let property1;
2330
let property2;
@@ -181,11 +188,7 @@ describe( 'Simple property search', () => {
181188
.assertInvalidRequest()
182189
.makeRequest();
183190

184-
expect( response ).to.have.status( 400 );
185-
186-
assert.header( response, 'Content-Language', 'en' );
187-
assert.strictEqual( response.body.code, 'invalid-query-parameter' );
188-
assert.deepStrictEqual( response.body.context, { parameter: 'language' } );
191+
assertValidError( response, 400, 'invalid-query-parameter', { parameter: 'language' } );
189192
} );
190193

191194
it( 'User-Agent empty', async () => {
@@ -196,6 +199,29 @@ describe( 'Simple property search', () => {
196199
expect( response ).to.have.status( 400 );
197200
assert.strictEqual( response.body.code, 'missing-user-agent' );
198201
} );
199-
} );
200202

203+
Object.entries( {
204+
'invalid limit parameter - exceeds max limit 500': {
205+
parameter: 'limit',
206+
value: 501
207+
},
208+
'invalid limit parameter - negative limit': {
209+
parameter: 'limit',
210+
value: -1
211+
},
212+
'invalid offset parameter - negative offset': {
213+
parameter: 'offset',
214+
value: -2
215+
}
216+
} ).forEach( ( [ title, { parameter, value } ] ) => {
217+
it( title, async () => {
218+
219+
const response = await newSearchRequest( 'en', 'search term' )
220+
.withQueryParam( parameter, value )
221+
.makeRequest();
222+
223+
assertValidError( response, 400, 'invalid-query-parameter', { parameter } );
224+
} );
225+
} );
226+
} );
201227
} );

repo/domains/search/tests/phpunit/Application/UseCases/SimplePropertySearch/SimplePropertySearchValidatorTest.php

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Wikibase\Repo\Tests\Domains\Search\Application\UseCases\SimplePropertySearch;
44

5+
use Generator;
56
use MediaWiki\MediaWikiServices;
67
use PHPUnit\Framework\TestCase;
78
use Wikibase\Repo\Domains\Search\Application\UseCases\SimplePropertySearch\SimplePropertySearchRequest;
@@ -24,18 +25,29 @@
2425
*/
2526
class SimplePropertySearchValidatorTest extends TestCase {
2627

28+
private const DEFAULT_LIMIT = 10;
29+
private const DEFAULT_OFFSET = 0;
30+
2731
/**
2832
* @doesNotPerformAssertions
2933
*/
3034
public function testValidate_passes(): void {
3135
$this->newUseCaseValidator()
32-
->validate( new SimplePropertySearchRequest( 'search term', 'en', 10, 0 ) );
36+
->validate( new SimplePropertySearchRequest( 'search term', 'en', self::DEFAULT_LIMIT, self::DEFAULT_OFFSET ) );
37+
}
38+
39+
/**
40+
* @doesNotPerformAssertions
41+
*/
42+
public function testValidateWithoutLimitAndOffsetParams_passe(): void {
43+
$this->newUseCaseValidator()
44+
->validate( new SimplePropertySearchRequest( 'search term', 'en', null, null ) );
3345
}
3446

3547
public function testGivenInvalidLanguageCode_throws(): void {
3648
try {
3749
$this->newUseCaseValidator()
38-
->validate( new SimplePropertySearchRequest( 'search term', 'xyz', 10, 0 ) );
50+
->validate( new SimplePropertySearchRequest( 'search term', 'xyz', self::DEFAULT_LIMIT, self::DEFAULT_OFFSET ) );
3951

4052
$this->fail( 'Expected exception was not thrown' );
4153
} catch ( UseCaseError $e ) {
@@ -48,6 +60,43 @@ public function testGivenInvalidLanguageCode_throws(): void {
4860
}
4961
}
5062

63+
/**
64+
* @dataProvider provideInvalidLimitAndOffset
65+
*/
66+
public function testGivenInvalidLimitAndOffset_throws(
67+
UseCaseError $expectedError,
68+
int $limit,
69+
int $offset
70+
): void {
71+
try {
72+
$this->newUseCaseValidator()
73+
->validate( new SimplePropertySearchRequest( 'search term', 'en', $limit, $offset ) );
74+
$this->fail( 'Expected exception was not thrown' );
75+
} catch ( UseCaseError $e ) {
76+
$this->assertEquals( $expectedError, $e );
77+
}
78+
}
79+
80+
public static function provideInvalidLimitAndOffset(): Generator {
81+
yield 'invalid limit - negative limit' => [
82+
UseCaseError::invalidQueryParameter( 'limit' ),
83+
-1,
84+
self::DEFAULT_OFFSET,
85+
];
86+
87+
yield 'invalid limit - limit exceeds max (500)' => [
88+
UseCaseError::invalidQueryParameter( 'limit' ),
89+
501,
90+
self::DEFAULT_OFFSET,
91+
];
92+
93+
yield 'invalid offset - negative offset' => [
94+
UseCaseError::invalidQueryParameter( 'offset' ),
95+
self::DEFAULT_LIMIT,
96+
-2,
97+
];
98+
}
99+
51100
private function newUseCaseValidator(): SimplePropertySearchValidator {
52101
return new SimplePropertySearchValidator( $this->newSearchLanguageValidator() );
53102
}

0 commit comments

Comments
 (0)