forked from flatpak/xdg-desktop-portal
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tests/location: Test the location portal with a mocked GeoClue2
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
Showing
4 changed files
with
246 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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), | ||
], | ||
) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|