Files
allhaileris afb81b8278
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
init
2026-02-16 15:50:16 +03:00

353 lines
11 KiB
Python

# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This file is formatted with Python Black
import tests as xdp
import dbus
import pytest
import os
import tempfile
from pathlib import Path
from typing import Any
defaults_list = b"""[Default Applications]
x-scheme-handler/http=furrfix.desktop;
text/plain=furrfix.desktop
"""
furrfix_desktop = b"""[Desktop Entry]
Version=1.0
Name=Furrfix
GenericName=Not a Web Browser
Comment=Don't Browse the Web
Exec=true %u
Icon=furrfix
Terminal=false
Type=Application
MimeType=text/plain;text/html;text/xml;application/xhtml+xml;application/vnd.mozilla.xul+xml;text/mml;x-scheme-handler/http;x-scheme-handler/https;x-scheme-handler/xdg-desktop-portal-test;
StartupNotify=true
Categories=Network;WebBrowser;
Keywords=web;browser;internet;
"""
mimeinfo_cache = b"""[MIME Cache]
application/vnd.mozilla.xul+xml=furrfix.desktop;
application/xhtml+xml=furrfix.desktop;
text/plain=furrfix.desktop;
text/html=furrfix.desktop;
text/mml=furrfix.desktop;
text/xml=furrfix.desktop;
x-scheme-handler/http=furrfix.desktop;
x-scheme-handler/https=furrfix.desktop;
x-scheme-handler/xdg-desktop-portal-test=furrfix.desktop;
"""
@pytest.fixture
def xdg_data_home_files():
return {
"applications/defaults.list": defaults_list,
"applications/furrfix.desktop": furrfix_desktop,
"applications/mimeinfo.cache": mimeinfo_cache,
}
@pytest.fixture
def required_templates():
return {
"appchooser": {},
"lockdown": {},
}
class TestOpenURI:
def set_permissions(self, dbus_con, type, permissions):
perm_store_intf = xdp.get_permission_store_iface(dbus_con)
perm_store_intf.SetPermission(
"desktop-used-apps",
True,
"inhibit",
type,
permissions,
)
def enable_paranoid_mode(self, dbus_con, type):
# turn on paranoid mode to ensure we get a backend call
perm_store_intf = xdp.get_permission_store_iface(dbus_con)
perm_store_intf.SetValue(
"desktop-used-apps",
True,
type,
dbus.Dictionary(
{
"always-ask": True,
},
signature="sv",
),
)
def test_version(self, portals, dbus_con):
xdp.check_version(dbus_con, "OpenURI", 5)
def test_http1(self, portals, dbus_con, app_id):
openuri_intf = xdp.get_portal_iface(dbus_con, "OpenURI")
mock_intf = xdp.get_mock_iface(dbus_con)
scheme_handler = "x-scheme-handler/http"
self.enable_paranoid_mode(dbus_con, scheme_handler)
uri = "http://www.flatpak.org"
writable = False
activation_token = "token"
request = xdp.Request(dbus_con, openuri_intf)
options = {
"writable": writable,
"activation_token": activation_token,
}
response = request.call(
"OpenURI",
parent_window="",
uri=uri,
options=options,
)
assert response
assert response.response == 0
# Check the impl portal was called with the right args
method_calls = mock_intf.GetMethodCalls("ChooseApplication")
assert len(method_calls) > 0
_, args = method_calls[-1]
assert args[1] == app_id
assert args[2] == "" # parent window
assert "furrfix" in args[3]
assert args[4]["uri"] == uri
assert args[4]["content_type"] == scheme_handler
assert args[4]["activation_token"] == activation_token
def test_http2(self, portals, dbus_con):
openuri_intf = xdp.get_portal_iface(dbus_con, "OpenURI")
mock_intf = xdp.get_mock_iface(dbus_con)
scheme_handler = "x-scheme-handler/http"
self.set_permissions(dbus_con, scheme_handler, ["furrfix", "3", "3"])
uri = "http://www.flatpak.org"
writable = False
activation_token = "token"
request = xdp.Request(dbus_con, openuri_intf)
options = {
"writable": writable,
"activation_token": activation_token,
}
response = request.call(
"OpenURI",
parent_window="",
uri=uri,
options=options,
)
assert response
assert response.response == 0
# Check the impl portal was not called because the choice thresold
# has been reached
method_calls = mock_intf.GetMethodCalls("ChooseApplication")
assert len(method_calls) == 0
def test_file(self, portals, dbus_con, app_id):
openuri_intf = xdp.get_portal_iface(dbus_con, "OpenURI")
mock_intf = xdp.get_mock_iface(dbus_con)
scheme_handler = "text/plain"
self.enable_paranoid_mode(dbus_con, scheme_handler)
fd, _ = tempfile.mkstemp(prefix="openuri_mock_file_", dir=Path.home())
os.write(fd, b"openuri_mock_file")
writable = False
activation_token = "token"
request = xdp.Request(dbus_con, openuri_intf)
options = {
"writable": writable,
"activation_token": activation_token,
}
response = request.call(
"OpenFile",
parent_window="",
fd=fd,
options=options,
)
assert response
assert response.response == 0
# Check the impl portal was called with the right args
method_calls = mock_intf.GetMethodCalls("ChooseApplication")
assert len(method_calls) > 0
_, args = method_calls[-1]
assert args[1] == app_id
assert args[2] == "" # parent window
assert "furrfix" in args[3]
assert args[4]["content_type"] == scheme_handler
assert args[4]["activation_token"] == activation_token
path = args[4]["uri"]
assert path.startswith("file:///")
with open(path[7:]) as file:
openuri_file_contents = file.read()
assert openuri_file_contents == "openuri_mock_file"
@pytest.mark.parametrize("template_params", ({"appchooser": {"response": 1}},))
def test_cancel(self, portals, dbus_con):
openuri_intf = xdp.get_portal_iface(dbus_con, "OpenURI")
scheme_handler = "x-scheme-handler/http"
self.enable_paranoid_mode(dbus_con, scheme_handler)
uri = "http://www.flatpak.org"
request = xdp.Request(dbus_con, openuri_intf)
options: Any = {}
response = request.call(
"OpenURI",
parent_window="",
uri=uri,
options=options,
)
assert response
assert response.response == 1
@pytest.mark.parametrize(
"template_params", ({"appchooser": {"expect-close": True}},)
)
def test_close(self, portals, dbus_con, app_id):
openuri_intf = xdp.get_portal_iface(dbus_con, "OpenURI")
mock_intf = xdp.get_mock_iface(dbus_con)
scheme_handler = "x-scheme-handler/http"
self.enable_paranoid_mode(dbus_con, scheme_handler)
uri = "http://www.flatpak.org"
writable = False
activation_token = "token"
request = xdp.Request(dbus_con, openuri_intf)
request.schedule_close(1000)
options = {
"writable": writable,
"activation_token": activation_token,
}
request.call(
"OpenURI",
parent_window="",
uri=uri,
options=options,
)
# Only true if the impl.Request was closed too
assert request.closed
# Check the impl portal was called with the right args
method_calls = mock_intf.GetMethodCalls("ChooseApplication")
assert len(method_calls) > 0
_, args = method_calls[-1]
assert args[1] == app_id
assert args[2] == "" # parent window
assert "furrfix" in args[3]
assert args[4]["uri"] == uri
assert args[4]["content_type"] == scheme_handler
assert args[4]["activation_token"] == activation_token
@pytest.mark.parametrize(
"template_params", ({"lockdown": {"disable-application-handlers": True}},)
)
def test_lockdown(self, portals, dbus_con, app_id):
openuri_intf = xdp.get_portal_iface(dbus_con, "OpenURI")
scheme_handler = "x-scheme-handler/http"
self.enable_paranoid_mode(dbus_con, scheme_handler)
uri = "http://www.flatpak.org"
writable = False
activation_token = "token"
request = xdp.Request(dbus_con, openuri_intf)
options = {
"writable": writable,
"activation_token": activation_token,
}
with pytest.raises(dbus.exceptions.DBusException) as excinfo:
request.call(
"OpenURI",
parent_window="",
uri=uri,
options=options,
)
assert (
excinfo.value.get_dbus_name() == "org.freedesktop.portal.Error.NotAllowed"
)
def test_dir(self, portals, dbus_con, app_id):
openuri_intf = xdp.get_portal_iface(dbus_con, "OpenURI")
mock_intf = xdp.get_mock_iface(dbus_con)
scheme_handler = "inode/directory"
self.enable_paranoid_mode(dbus_con, scheme_handler)
fd, file_path = tempfile.mkstemp(prefix="openuri_mock_file_", dir=Path.home())
os.write(fd, b"openuri_mock_file")
activation_token = "token"
request = xdp.Request(dbus_con, openuri_intf)
options = {
"activation_token": activation_token,
}
response = request.call(
"OpenDirectory",
parent_window="",
fd=fd,
options=options,
)
assert response
assert response.response == 0
# Check the appchooser portal got called to open the containing dir
method_calls = mock_intf.GetMethodCalls("ChooseApplication")
assert len(method_calls) > 0
_, args = method_calls[-1]
assert args[1] == app_id
assert args[2] == "" # parent window
assert args[4]["content_type"] == scheme_handler
assert args[4]["activation_token"] == activation_token
path = args[4]["uri"]
assert path.startswith("file:///")
assert Path(path[7:]) == Path(file_path).parent
def test_scheme_supported(self, portals, dbus_con):
openuri_intf = xdp.get_portal_iface(dbus_con, "OpenURI")
supported = openuri_intf.SchemeSupported("https", {})
assert supported
supported = openuri_intf.SchemeSupported("bogusnonexistanthandler", {})
assert not supported
with pytest.raises(dbus.exceptions.DBusException) as excinfo:
openuri_intf.SchemeSupported("", {})
assert (
excinfo.value.get_dbus_name()
== "org.freedesktop.portal.Error.InvalidArgument"
)