librenms/tests/Unit/LocationTest.php
Jellyfrog 2b3575a5e9
Laravel 10.x Shift (#14995)
* Apply code style

* Remove explicit call to register policies

* Shift core files

* Shift config files

* Default config files

In an effort to make upgrading the constantly changing config files
easier, Shift defaulted them and merged your true customizations -
where ENV variables may not be used.

* Bump Laravel dependencies

* Add type hints for Laravel 10

* Shift cleanup

* wip

* wip

* sync translation

* Sync back config

* Public Path Binding

* QueryException

* monolog

* db::raw

* monolog

* db::raw

* fix larastan collections

* fix phpstan bug looping forever

* larastan errors

* larastan: fix column type

* styleci

* initialize array

* fixes

* fixes

---------

Co-authored-by: Shift <shift@laravelshift.com>
2023-05-24 22:21:54 +02:00

231 lines
10 KiB
PHP

<?php
/*
* LocationTest.php
*
* -Description-
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*
* @package LibreNMS
* @link http://librenms.org
* @copyright 2021 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace LibreNMS\Tests\Unit;
use App\Models\Device;
use App\Models\Location;
use LibreNMS\Config;
use LibreNMS\Interfaces\Geocoder;
use LibreNMS\Tests\TestCase;
use LibreNMS\Util\Dns;
use Mockery\MockInterface;
class LocationTest extends TestCase
{
public function testCanSetLocation(): void
{
$device = Device::factory()->make(); /** @var Device $device */
$device->setLocation('Where');
$this->assertEquals($device->location->location, 'Where');
$this->assertNull($device->location->lat);
$this->assertNull($device->location->lng);
$device->setLocation(null);
$this->assertNull($device->location);
}
public function testCanNotSetLocation(): void
{
$device = Device::factory()->make(); /** @var Device $device */
$location = Location::factory()->make(); /** @var Location $location */
$device->override_sysLocation = true;
$device->setLocation($location->location);
$this->assertNull($device->location);
}
public function testCanSetEncodedLocation(): void
{
Config::set('geoloc.dns', false);
$device = Device::factory()->make(); /** @var Device $device */
// valid coords
$location = Location::factory()->withCoordinates()->make(); /** @var Location $location */
$device->setLocation("$location->location [$location->lat,$location->lng]", true);
$this->assertEquals("$location->location [$location->lat,$location->lng]", $device->location->location);
$this->assertEquals($location->location, $device->location->display());
$this->assertEquals($location->lat, $device->location->lat);
$this->assertEquals($location->lng, $device->location->lng);
// with space
$location = Location::factory()->withCoordinates()->make(); /** @var Location $location */
$device->setLocation("$location->location [$location->lat, $location->lng]", true);
$this->assertEquals("$location->location [$location->lat, $location->lng]", $device->location->location);
$this->assertEquals($location->location, $device->location->display());
$this->assertEquals("$location->location [$location->lat,$location->lng]", $device->location->display(true));
$this->assertEquals($location->lat, $device->location->lat);
$this->assertEquals($location->lng, $device->location->lng);
// invalid coords
$location = Location::factory()->withCoordinates()->make(['lat' => 251.5007138]); /** @var Location $location */
$name = "$location->location [$location->lat,$location->lng]";
$device->setLocation($name, true);
$this->assertEquals($name, $device->location->location);
$this->assertEquals($name, $device->location->display());
$this->assertEquals($name, $device->location->display(true));
$this->assertNull($device->location->lat);
$this->assertNull($device->location->lng);
}
public function testCanHandleGivenCoordinates(): void
{
Config::set('geoloc.dns', false);
$device = Device::factory()->make(); /** @var Device $device */
$location = Location::factory()->withCoordinates()->make(); /** @var Location $location */
$device->setLocation($location);
$this->assertEquals($location->location, $device->location->location);
$this->assertEquals($location->location, $device->location->display());
$this->assertEquals("$location->location [$location->lat,$location->lng]", $device->location->display(true));
$this->assertEquals($location->lat, $device->location->lat);
$this->assertEquals($location->lng, $device->location->lng);
}
public function testCanNotSetFixedCoordinates(): void
{
$device = Device::factory()->make(); /** @var Device $device */
$locationOne = Location::factory()->withCoordinates()->make(); /** @var Location $locationOne */
$locationTwo = Location::factory(['location' => $locationOne->location])->withCoordinates()->make(); /** @var Location $locationTwo */
$device->setLocation($locationOne);
$this->assertEquals($locationOne->lat, $device->location->lat);
$this->assertEquals($locationOne->lng, $device->location->lng);
$device->location->fixed_coordinates = true;
$device->setLocation($locationTwo);
$this->assertEquals($locationOne->lat, $device->location->lat);
$this->assertEquals($locationOne->lng, $device->location->lng);
$device->location->fixed_coordinates = false;
$device->setLocation($locationTwo);
$this->assertEquals($locationTwo->lat, $device->location->lat);
$this->assertEquals($locationTwo->lng, $device->location->lng);
}
public function testDnsLookup(): void
{
$example = 'SW1A2AA.find.me.uk';
$expected = ['lat' => 51.50354111111111, 'lng' => -0.12766972222222223];
$result = (new Dns())->getCoordinates($example);
$this->assertEquals($expected, $result);
}
public function testCanSetDnsCoordinate(): void
{
Config::set('geoloc.dns', true);
$device = Device::factory()->make(); /** @var Device $device */
$location = Location::factory()->withCoordinates()->make(); /** @var Location $location */
$this->mock(Dns::class, function (MockInterface $mock) use ($location) {
$mock->shouldReceive('getCoordinates')->once()->andReturn($location->only(['lat', 'lng']));
});
$device->setLocation($location->location, true);
$this->assertEquals($location->location, $device->location->location);
$this->assertEquals($location->lat, $device->location->lat);
$this->assertEquals($location->lng, $device->location->lng);
Config::set('geoloc.dns', false);
$device->setLocation('No DNS', true);
$this->assertEquals('No DNS', $device->location->location);
$this->assertNull($device->location->lat);
$this->assertNull($device->location->lng);
}
public function testCanSetByApi(): void
{
$device = Device::factory()->make(); /** @var Device $device */
$location = Location::factory()->withCoordinates()->make(); /** @var Location $location */
$this->mock(Geocoder::class, function (MockInterface $mock) use ($location) {
$mock->shouldReceive('getCoordinates')->once()->andReturn($location->only(['lat', 'lng']));
});
Config::set('geoloc.latlng', false);
$device->setLocation('No API', true);
$this->assertEquals('No API', $device->location->location);
$this->assertNull($device->location->lat);
$this->assertNull($device->location->lng);
Config::set('geoloc.latlng', true);
$device->setLocation('API', true);
$this->assertEquals('API', $device->location->location);
$this->assertEquals($location->lat, $device->location->lat);
$this->assertEquals($location->lng, $device->location->lng);
// preset coord = skip api
$device->setLocation('API', true);
$this->assertEquals($location->lat, $device->location->lat);
$this->assertEquals($location->lng, $device->location->lng);
}
public function testCorrectPrecedence(): void
{
$device = Device::factory()->make(); /** @var Device $device */
$location_encoded = Location::factory()->withCoordinates()->make(); /** @var Location $location_encoded */
$location_fixed = Location::factory()->withCoordinates()->make(); /** @var Location $location_fixed */
$location_api = Location::factory()->withCoordinates()->make(); /** @var Location $location_api */
$location_dns = Location::factory()->withCoordinates()->make(); /** @var Location $location_dns */
Config::set('geoloc.dns', true);
$this->mock(Dns::class, function (MockInterface $mock) use ($location_dns) {
$mock->shouldReceive('getCoordinates')->times(3)->andReturn(
$location_dns->only(['lat', 'lng']),
[],
[]
);
});
Config::set('geoloc.latlng', true);
$this->mock(Geocoder::class, function (MockInterface $mock) use ($location_api) {
$mock->shouldReceive('getCoordinates')->once()->andReturn($location_api->only(['lat', 'lng']));
});
// fixed first
$location_fixed->location = "$location_fixed [-42, 42]"; // encoded should not be used
$device->setLocation($location_fixed, true);
$this->assertEquals($location_fixed->lat, $device->location->lat);
$this->assertEquals($location_fixed->lng, $device->location->lng);
// then encoded
$device->setLocation($location_encoded->display(true), true);
$this->assertEquals($location_encoded->lat, $device->location->lat);
$this->assertEquals($location_encoded->lng, $device->location->lng);
// then dns
$device->setLocation($location_encoded->location, true);
$this->assertEquals($location_dns->lat, $device->location->lat);
$this->assertEquals($location_dns->lng, $device->location->lng);
// then api
$device->setLocation($location_encoded->location, true);
$this->assertEquals($location_dns->lat, $device->location->lat);
$this->assertEquals($location_dns->lng, $device->location->lng);
$device->location->lat = null; // won't be used if latitude is set
$device->setLocation($location_encoded->location, true);
$this->assertEquals($location_api->lat, $device->location->lat);
$this->assertEquals($location_api->lng, $device->location->lng);
}
}