LocationTest   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 193
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 9
eloc 123
c 2
b 0
f 0
dl 0
loc 193
rs 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
A testCanSetLocation() 0 11 1
A testDnsLookup() 0 8 1
A testCanSetEncodedLocation() 0 31 1
A testCanSetDnsCoordinate() 0 19 1
A testCanNotSetLocation() 0 7 1
A testCorrectPrecedence() 0 46 1
A testCanHandleGivenCoordinates() 0 11 1
A testCanSetByApi() 0 24 1
A testCanNotSetFixedCoordinates() 0 18 1
1
<?php
2
/*
3
 * LocationTest.php
4
 *
5
 * -Description-
6
 *
7
 * This program is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation, either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
 *
20
 * @package    LibreNMS
21
 * @link       http://librenms.org
22
 * @copyright  2021 Tony Murray
23
 * @author     Tony Murray <[email protected]>
24
 */
25
26
namespace LibreNMS\Tests\Unit;
27
28
use App\Models\Device;
29
use App\Models\Location;
30
use LibreNMS\Config;
31
use LibreNMS\Interfaces\Geocoder;
32
use LibreNMS\Tests\TestCase;
33
use LibreNMS\Util\Dns;
34
use Mockery\MockInterface;
35
36
class LocationTest extends TestCase
37
{
38
    public function testCanSetLocation()
39
    {
40
        $device = Device::factory()->make(); /** @var Device $device */
41
        $device->setLocation('Where');
42
43
        $this->assertEquals($device->location->location, 'Where');
44
        $this->assertNull($device->location->lat);
45
        $this->assertNull($device->location->lng);
46
47
        $device->setLocation(null);
48
        $this->assertNull($device->location);
49
    }
50
51
    public function testCanNotSetLocation()
52
    {
53
        $device = Device::factory()->make(); /** @var Device $device */
54
        $location = Location::factory()->make(); /** @var Location $location */
55
        $device->override_sysLocation = true;
56
        $device->setLocation($location->location);
57
        $this->assertNull($device->location);
58
    }
59
60
    public function testCanSetEncodedLocation()
61
    {
62
        Config::set('geoloc.dns', false);
63
        $device = Device::factory()->make(); /** @var Device $device */
64
65
        // valid coords
66
        $location = Location::factory()->withCoordinates()->make(); /** @var Location $location */
67
        $device->setLocation("$location->location [$location->lat,$location->lng]", true);
68
        $this->assertEquals("$location->location [$location->lat,$location->lng]", $device->location->location);
69
        $this->assertEquals($location->location, $device->location->display());
70
        $this->assertEquals($location->lat, $device->location->lat);
71
        $this->assertEquals($location->lng, $device->location->lng);
72
73
        // with space
74
        $location = Location::factory()->withCoordinates()->make(); /** @var Location $location */
75
        $device->setLocation("$location->location [$location->lat, $location->lng]", true);
76
        $this->assertEquals("$location->location [$location->lat, $location->lng]", $device->location->location);
77
        $this->assertEquals($location->location, $device->location->display());
78
        $this->assertEquals("$location->location [$location->lat,$location->lng]", $device->location->display(true));
79
        $this->assertEquals($location->lat, $device->location->lat);
80
        $this->assertEquals($location->lng, $device->location->lng);
81
82
        // invalid coords
83
        $location = Location::factory()->withCoordinates()->make(['lat' => 251.5007138]); /** @var Location $location */
84
        $name = "$location->location [$location->lat,$location->lng]";
85
        $device->setLocation($name, true);
86
        $this->assertEquals($name, $device->location->location);
87
        $this->assertEquals($name, $device->location->display());
88
        $this->assertEquals($name, $device->location->display(true));
89
        $this->assertNull($device->location->lat);
90
        $this->assertNull($device->location->lng);
91
    }
92
93
    public function testCanHandleGivenCoordinates()
94
    {
95
        Config::set('geoloc.dns', false);
96
        $device = Device::factory()->make(); /** @var Device $device */
97
        $location = Location::factory()->withCoordinates()->make(); /** @var Location $location */
98
        $device->setLocation($location);
99
        $this->assertEquals($location->location, $device->location->location);
100
        $this->assertEquals($location->location, $device->location->display());
101
        $this->assertEquals("$location->location [$location->lat,$location->lng]", $device->location->display(true));
102
        $this->assertEquals($location->lat, $device->location->lat);
103
        $this->assertEquals($location->lng, $device->location->lng);
104
    }
105
106
    public function testCanNotSetFixedCoordinates()
107
    {
108
        $device = Device::factory()->make(); /** @var Device $device */
109
        $locationOne = Location::factory()->withCoordinates()->make(); /** @var Location $locationOne */
110
        $locationTwo = Location::factory(['location' => $locationOne->location])->withCoordinates()->make(); /** @var Location $locationTwo */
111
        $device->setLocation($locationOne);
112
        $this->assertEquals($locationOne->lat, $device->location->lat);
113
        $this->assertEquals($locationOne->lng, $device->location->lng);
114
115
        $device->location->fixed_coordinates = true;
116
        $device->setLocation($locationTwo);
117
        $this->assertEquals($locationOne->lat, $device->location->lat);
118
        $this->assertEquals($locationOne->lng, $device->location->lng);
119
120
        $device->location->fixed_coordinates = false;
121
        $device->setLocation($locationTwo);
122
        $this->assertEquals($locationTwo->lat, $device->location->lat);
123
        $this->assertEquals($locationTwo->lng, $device->location->lng);
124
    }
125
126
    public function testDnsLookup()
127
    {
128
        $example = 'SW1A2AA.find.me.uk';
129
        $expected = ['lat' => 51.50354111111111, 'lng' => -0.12766972222222223];
130
131
        $result = (new Dns())->getCoordinates($example);
132
133
        $this->assertEquals($expected, $result);
134
    }
135
136
    public function testCanSetDnsCoordinate()
137
    {
138
        Config::set('geoloc.dns', true);
139
        $device = Device::factory()->make(); /** @var Device $device */
140
        $location = Location::factory()->withCoordinates()->make(); /** @var Location $location */
141
        $this->mock(Dns::class, function (MockInterface $mock) use ($location) {
142
            $mock->shouldReceive('getCoordinates')->once()->andReturn($location->only(['lat', 'lng']));
143
        });
144
145
        $device->setLocation($location->location, true);
146
        $this->assertEquals($location->location, $device->location->location);
147
        $this->assertEquals($location->lat, $device->location->lat);
148
        $this->assertEquals($location->lng, $device->location->lng);
149
150
        Config::set('geoloc.dns', false);
151
        $device->setLocation('No DNS', true);
152
        $this->assertEquals('No DNS', $device->location->location);
153
        $this->assertNull($device->location->lat);
154
        $this->assertNull($device->location->lng);
155
    }
156
157
    public function testCanSetByApi()
158
    {
159
        $device = Device::factory()->make(); /** @var Device $device */
160
        $location = Location::factory()->withCoordinates()->make(); /** @var Location $location */
161
        $this->mock(Geocoder::class, function (MockInterface $mock) use ($location) {
162
            $mock->shouldReceive('getCoordinates')->once()->andReturn($location->only(['lat', 'lng']));
163
        });
164
165
        Config::set('geoloc.latlng', false);
166
        $device->setLocation('No API', true);
167
        $this->assertEquals('No API', $device->location->location);
168
        $this->assertNull($device->location->lat);
169
        $this->assertNull($device->location->lng);
170
171
        Config::set('geoloc.latlng', true);
172
        $device->setLocation('API', true);
173
        $this->assertEquals('API', $device->location->location);
174
        $this->assertEquals($location->lat, $device->location->lat);
175
        $this->assertEquals($location->lng, $device->location->lng);
176
177
        // preset coord = skip api
178
        $device->setLocation('API', true);
179
        $this->assertEquals($location->lat, $device->location->lat);
180
        $this->assertEquals($location->lng, $device->location->lng);
181
    }
182
183
    public function testCorrectPrecedence()
184
    {
185
        $device = Device::factory()->make(); /** @var Device $device */
186
        $location_encoded = Location::factory()->withCoordinates()->make(); /** @var Location $location_encoded */
187
        $location_fixed = Location::factory()->withCoordinates()->make(); /** @var Location $location_fixed */
188
        $location_api = Location::factory()->withCoordinates()->make(); /** @var Location $location_api */
189
        $location_dns = Location::factory()->withCoordinates()->make(); /** @var Location $location_dns */
190
        Config::set('geoloc.dns', true);
191
        $this->mock(Dns::class, function (MockInterface $mock) use ($location_dns) {
192
            $mock->shouldReceive('getCoordinates')->times(3)->andReturn(
193
                $location_dns->only(['lat', 'lng']),
194
                [],
195
                []
196
            );
197
        });
198
199
        Config::set('geoloc.latlng', true);
200
        $this->mock(Geocoder::class, function (MockInterface $mock) use ($location_api) {
201
            $mock->shouldReceive('getCoordinates')->once()->andReturn($location_api->only(['lat', 'lng']));
202
        });
203
204
        // fixed first
205
        $location_fixed->location = "$location_fixed [-42, 42]"; // encoded should not be used
206
        $device->setLocation($location_fixed, true);
207
        $this->assertEquals($location_fixed->lat, $device->location->lat);
208
        $this->assertEquals($location_fixed->lng, $device->location->lng);
209
210
        // then encoded
211
        $device->setLocation($location_encoded->display(true), true);
212
        $this->assertEquals($location_encoded->lat, $device->location->lat);
213
        $this->assertEquals($location_encoded->lng, $device->location->lng);
214
215
        // then dns
216
        $device->setLocation($location_encoded->location, true);
217
        $this->assertEquals($location_dns->lat, $device->location->lat);
218
        $this->assertEquals($location_dns->lng, $device->location->lng);
219
220
        // then api
221
        $device->setLocation($location_encoded->location, true);
222
        $this->assertEquals($location_dns->lat, $device->location->lat);
223
        $this->assertEquals($location_dns->lng, $device->location->lng);
224
225
        $device->location->lat = null; // won't be used if latitude is set
226
        $device->setLocation($location_encoded->location, true);
227
        $this->assertEquals($location_api->lat, $device->location->lat);
228
        $this->assertEquals($location_api->lng, $device->location->lng);
229
    }
230
}
231