%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /www/varak.net/wiki.varak.net/extensions/CirrusSearch/tests/unit/Query/
Upload File :
Create Path :
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 );
	}
}

Zerion Mini Shell 1.0