Skip to content

Commit

Permalink
tests/location: Test the location portal with a mocked GeoClue2
Browse files Browse the repository at this point in the history
This tests more than the C variant of the test and does not depend on
the system provided GeoClue2 to function but instead uses a mocked
GeoClue2.
  • Loading branch information
swick committed Oct 17, 2024
1 parent 0221cfd commit eea9a7c
Show file tree
Hide file tree
Showing 4 changed files with 246 additions and 0 deletions.
1 change: 1 addition & 0 deletions tests/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ if enable_pytest
'test_email.py',
'test_globalshortcuts.py',
'test_inputcapture.py',
'test_location.py',
'test_remotedesktop.py',
'test_trash.py',
]
Expand Down
122 changes: 122 additions & 0 deletions tests/templates/geoclue2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# SPDX-License-Identifier: LGPL-2.1-or-later

from tests.templates import init_template_logger
import dbus.service
import dbus
import tempfile

from dbusmock import mockobject

from gi.repository import GLib

BUS_NAME = "org.freedesktop.GeoClue2"
MAIN_OBJ = "/org/freedesktop/GeoClue2/Manager"
MAIN_IFACE = "org.freedesktop.GeoClue2.Manager"
CLIENT_IFACE = "org.freedesktop.GeoClue2.Client"
LOCATION_IFACE = "org.freedesktop.GeoClue2.Location"
MOCK_IFACE = "org.freedesktop.GeoClue2.Mock"
SYSTEM_BUS = True
VERSION = 1

logger = init_template_logger(__name__)


def load(mock, parameters={}):
mock.AddMethods(
MAIN_IFACE,
[
("GetClient", "", "o", 'ret = dbus.ObjectPath("/org/freedesktop/GeoClue2/Client/1")'),
],
)
mock.AddObject(
"/org/freedesktop/GeoClue2/Client/1",
CLIENT_IFACE,
{
"DesktopId": "",
"DistanceThreshold": 0,
"TimeThreshold": 0,
"RequestedAccuracyLevel": 0,
},
[
("Start", "", "", Start),
("Stop", "", "", Stop),
],
)
mock.client = mockobject.objects["/org/freedesktop/GeoClue2/Client/1"]
mock.client.manager = mock
mock.client.started = False
mock.client.location = 0
mock.client.props = {
"Latitude": 0,
"Longitude": 0,
"Accuracy": 0
}

mock.client.AddMethod(MOCK_IFACE, "ChangeLocation", "a{sv}", "", ChangeLocation)


@dbus.service.method(
CLIENT_IFACE,
in_signature="",
out_signature="",
)
def Start(self):
logger.debug(f"Start()")
self.started = True
self.ChangeLocation(self.props)


@dbus.service.method(
CLIENT_IFACE,
in_signature="",
out_signature="",
)
def Stop(self):
logger.debug(f"Stop()")
self.started = False
self.RemoveObject(f"/org/freedesktop/GeoClue2/Location/{self.location}")


@dbus.service.method(
MOCK_IFACE,
in_signature="a{sv}",
out_signature="",
)
def ChangeLocation(self, props):
logger.debug(f"ChangeLocation({props})")

self.props = props

if self.started != True:
return

old_path = "/"
if self.location > 0:
old_path = f"/org/freedesktop/GeoClue2/Location/{self.location}"
self.location = self.location + 1
new_path = f"/org/freedesktop/GeoClue2/Location/{self.location}"

self.AddObject(
new_path,
LOCATION_IFACE,
{
"Latitude": props["Latitude"],
"Longitude": props["Longitude"],
"Accuracy": props["Accuracy"],
},
[],
)

if old_path != "/":
self.RemoveObject(old_path)

self.EmitSignal(
CLIENT_IFACE,
"LocationUpdated",
"oo",
[
dbus.ObjectPath(old_path),
dbus.ObjectPath(new_path),
],
)

1 change: 1 addition & 0 deletions tests/templates/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ template_files = [
'__init__.py',
'clipboard.py',
'email.py',
'geoclue2.py',
'globalshortcuts.py',
'inputcapture.py',
'remotedesktop.py',
Expand Down
122 changes: 122 additions & 0 deletions tests/test_location.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# SPDX-License-Identifier: LGPL-2.1-or-later


from tests import Session
from pathlib import Path
from gi.repository import GLib

import os
import pytest
import tempfile
import dbus


@pytest.fixture
def portal_name():
return "Location"


@pytest.fixture
def portal_has_impl():
return False


@pytest.fixture
def required_templates():
return {"geoclue2": {}}


class TestLocation:
def test_version(self, portal_mock):
portal_mock.check_version(1)


def get_client_mock(self, portal_mock):
geoclue_manager_proxy = portal_mock.dbus_con_sys.get_object(
"org.freedesktop.GeoClue2",
"/org/freedesktop/GeoClue2/Manager",
)
geoclue_manager = dbus.Interface(
geoclue_manager_proxy,
"org.freedesktop.GeoClue2.Manager"
)
geoclue_client_proxy = portal_mock.dbus_con_sys.get_object(
"org.freedesktop.GeoClue2",
geoclue_manager.GetClient()
)
client_mock = dbus.Interface(
geoclue_client_proxy,
f"org.freedesktop.GeoClue2.Mock"
)
return client_mock


def test_session_update(self, portal_mock):
mainloop = GLib.MainLoop()
GLib.timeout_add(2000, mainloop.quit)
updated_count = 0

location_intf = portal_mock.get_dbus_interface()
session = Session(
portal_mock.dbus_con,
location_intf.CreateSession({"session_handle_token": "session_token0"})
)

def cb_location_updated(session_handle, location):
nonlocal mainloop
nonlocal updated_count

if updated_count == 0:
assert location["Latitude"] == 0
assert location["Longitude"] == 0
assert location["Accuracy"] == 0
elif updated_count == 1:
assert location["Latitude"] == 11
assert location["Longitude"] == 22
assert location["Accuracy"] == 3

updated_count += 1
mainloop.quit()

location_intf.connect_to_signal("LocationUpdated", cb_location_updated)

start_session_request = portal_mock.create_request()
start_session_response = start_session_request.call(
"Start",
session_handle=session.handle,
parent_window="window-hndl",
options = {},
)

assert start_session_response.response == 0

mainloop.run()

assert updated_count == 1

client_mock = self.get_client_mock(portal_mock)
client_mock.ChangeLocation({
"Latitude": dbus.UInt32(11),
"Longitude": dbus.UInt32(22),
"Accuracy": dbus.UInt32(3),
})

mainloop.run()

assert updated_count == 2


def test_bad_accuracy(self, portal_mock):
had_error = False
location_intf = portal_mock.get_dbus_interface()
try:
location_intf.CreateSession({
"session_handle_token": "session_token0",
"accuracy": dbus.UInt32(22),
})
except dbus.exceptions.DBusException as e:
had_error = True
assert e.get_dbus_name() == "org.freedesktop.portal.Error.InvalidArgument"
finally:
assert had_error

0 comments on commit eea9a7c

Please sign in to comment.