%PDF- %PDF-
| Direktori : /www/varak.net/wiki.varak.net/extensions/CirrusSearch/tests/unit/Query/ |
| Current File : //www/varak.net/wiki.varak.net/extensions/CirrusSearch/tests/unit/Query/GeoFeatureTest.php |
<?php
namespace CirrusSearch\Query;
use CirrusSearch\SearchConfig;
use GeoData\Coord;
use LoadBalancer;
use IDatabase;
use MediaWikiTestCase;
use MediaWiki\MediaWikiServices;
use Title;
/**
* Test GeoFeature functions.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*/
class GeoFeatureTest extends MediaWikiTestCase {
public function parseDistanceProvider() {
return [
'unknown units returns null' => [
null,
'100fur',
],
'gibberish returns null' => [
null,
'gibberish',
],
'no space allowed between numbers and units' => [
null,
'100 m',
],
'meters' => [
100,
'100m',
],
'kilometers' => [
1000,
'1km',
],
'yards' => [
366,
'400yd',
],
'one mile rounds down' => [
1609,
'1mi',
],
'two miles rounds up' => [
'3219',
'2mi',
],
'1000 feet rounds up' => [
305,
'1000ft',
],
'3000 feet rounds down' => [
914,
'3000ft',
],
'small requests are bounded' => [
10,
'1ft',
],
'allows large inputs' => [
4321000,
'4321km',
],
];
}
/**
* @dataProvider parseDistanceProvider
*/
public function testParseDistance( $expected, $distance ) {
if ( class_exists( Coord::class ) ) {
$feature = new GeoFeature();
$this->assertEquals( $expected, $feature->parseDistance( $distance, 5000 ) );
} else {
$this->markTestSkipped( 'GeoData extension must be installed' );
}
}
public function parseGeoNearbyProvider() {
return [
'random input' => [
[ null, 0 ],
'gibberish'
],
'random input with comma' => [
[ null, 0 ],
'gibberish,42.42'
],
'random input with valid radius prefix' => [
[ null, 0 ],
'20km,42.42,invalid',
],
'valid coordinate, default radius' => [
[
[ 'lat' => 1.2345, 'lon' => 2.3456 ],
5000,
],
'1.2345,2.3456',
],
'valid coordinate, specific radius in meters' => [
[
[ 'lat' => -5.4321, 'lon' => 42.345 ],
4321,
],
'4321m,-5.4321,42.345',
],
'valid coordinate, specific radius in kilmeters' => [
[
[ 'lat' => 0, 'lon' => 42.345 ],
7000,
],
'7km,0,42.345',
],
'out of bounds positive latitude' => [
[ null, 0 ],
'90.1,0'
],
'out of bounds negative latitude' => [
[ null, 0 ],
'-90.1,17',
],
'out of bounds positive longitude' => [
[ null, 0 ],
'49,180.1',
],
'out of bounds negative longitude' => [
[ null, 0 ],
'49,-180.001',
],
'valid coordinate with spaces' => [
[
[ 'lat' => 1.2345, 'lon' => 9.8765 ],
5000
],
'1.2345, 9.8765'
],
];
}
/**
* @dataProvider parseGeoNearbyProvider
*/
public function testParseGeoNearby( $expected, $value ) {
if ( class_exists( Coord::class ) ) {
$feature = new GeoFeature;
$result = $feature->parseGeoNearby( $value );
if ( $result[0] instanceof Coord ) {
$result[0] = [ 'lat' => $result[0]->lat, 'lon' => $result[0]->lon ];
}
$this->assertEquals( $expected, $result );
} else {
$this->markTestSkipped( 'GeoData extension must be installed' );
}
}
public function parseGeoNearbyTitleProvider() {
return [
'basic page lookup' => [
[
[ 'lat' => 1.2345, 'lon' => 5.4321 ],
5000,
7654321,
],
'San Francisco'
],
'basic page lookup with radius in meters' => [
[
[ 'lat' => 1.2345, 'lon' => 5.4321 ],
1234,
7654321,
],
'1234m,San Francisco'
],
'basic page lookup with radius in kilometers' => [
[
[ 'lat' => 1.2345, 'lon' => 5.4321 ],
2000,
7654321,
],
'2km,San Francisco'
],
'basic page lookup with space between radius and name' => [
[
[ 'lat' => 1.2345, 'lon' => 5.4321 ],
2000,
7654321,
],
'2km, San Francisco'
],
'page with comma in name' => [
[
[ 'lat' => 1.2345, 'lon' => 5.4321 ],
5000,
1234567,
],
'Washington, D.C.'
],
'page with comma in name and radius in kilometers' => [
[
[ 'lat' => 1.2345, 'lon' => 5.4321 ],
7000,
1234567,
],
'7km,Washington, D.C.'
],
'unknown page lookup' => [
[ null, 0, '' ],
'Unknown Title',
],
'unknown page lookup with radius' => [
[ null, 0, '' ],
'4km, Unknown Title',
],
];
}
/**
* @dataProvider parseGeoNearbyTitleProvider
*/
public function testParseGeoNearbyTitle( $expected, $value ) {
if ( ! class_exists( Coord::class ) ) {
$this->markTestSkipped( 'GeoData extension must be installed' );
return;
}
// Replace database with one that will return our fake coordinates if asked
$db = $this->getMock( IDatabase::class );
$db->expects( $this->any() )
->method( 'select' )
->with( 'geo_tags', $this->anything(), $this->anything(), $this->anything() )
->will( $this->returnValue( [
(object) [ 'gt_lat' => 1.2345, 'gt_lon' => 5.4321 ],
] ) );
// Tell LinkCache all titles not explicitly added don't exist
$db->expects( $this->any() )
->method( 'selectRow' )
->with( 'page', $this->anything(), $this->anything(), $this->anything() )
->will( $this->returnValue( false ) );
// Inject mock database into a mock LoadBalancer
$lb = $this->getMockBuilder( LoadBalancer::class )
->disableOriginalConstructor()
->getMock();
$lb->expects( $this->any() )
->method( 'getConnection' )
->will( $this->returnValue( $db ) );
$this->setService( 'DBLoadBalancer', $lb );
// Inject fake San Francisco page into LinkCache so it "exists"
MediaWikiServices::getInstance()->getLinkCache()
->addGoodLinkObj( 7654321, Title::newFromText( 'San Francisco' ) );
// Inject fake page with comma in it as well
MediaWikiServices::getInstance()->getLinkCache()
->addGoodLinkObj( 1234567, Title::newFromText( 'Washington, D.C.' ) );
$config = $this->getMock( SearchConfig::class );
$config->expects( $this->any() )
->method( 'makeId' )
->will( $this->returnCallback( function ( $id ) {
return $id;
} ) );
// Finally run the test
$feature = new GeoFeature;
$result = $feature->parseGeoNearbyTitle( $config, $value );
if ( $result[0] instanceof Coord ) {
$result[0] = [ 'lat' => $result[0]->lat, 'lon' => $result[0]->lon ];
}
$this->assertEquals( $expected, $result );
}
}