Skip to content

Commit

Permalink
[CODE] Refactor default browser fetching
Browse files Browse the repository at this point in the history
  • Loading branch information
ObaraEmmanuel committed Jan 23, 2021
1 parent 5106c6e commit 8faf985
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 61 deletions.
2 changes: 1 addition & 1 deletion browser_history/browsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ class Edge(ChromiumBasedBrowser):
"""

name = "Edge"
aliases = ("msedgehtm", "msedge")
aliases = ("msedgehtm", "msedge", "microsoft-edge")

windows_path = "AppData/Local/Microsoft/Edge/User Data"
mac_path = "Library/Application Support/Microsoft Edge"
Expand Down
49 changes: 33 additions & 16 deletions browser_history/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import inspect
import logging
import platform
import webbrowser
import subprocess

from . import generic

Expand Down Expand Up @@ -83,6 +83,32 @@ def get_subclasses(browser):
import winreg # type: ignore


def _default_browser_linux():
try:
cmd = "xdg-settings get default-web-browser".split()
raw_result = subprocess.check_output(cmd, stderr=subprocess.DEVNULL)
# most have a suffix ".desktop" so just remove it
default = raw_result.decode().strip().lower().replace(".desktop", "")
except (FileNotFoundError, subprocess.CalledProcessError, PermissionError):
logger.warning("Could not determine default browser")
default = None

return default


def _default_browser_win():
reg_path = (
"Software\\Microsoft\\Windows\\Shell\\Associations\\"
"UrlAssociations\\https\\UserChoice"
)
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, reg_path) as key:
default = winreg.QueryValueEx(key, "ProgId")
if default is None:
logger.warning("Could not determine default browser")
return None
return default[0].lower()


def default_browser():
"""This method gets the default browser of the current platform
Expand All @@ -98,26 +124,17 @@ def default_browser():

# Always try to return a lower-cased value for ease of comparison
if plat == Platform.LINUX:
default = webbrowser.get()
if default is None or default.name is None:
logger.warning("Could not determine default browser")
return None
default = default.name.lower()
default = _default_browser_linux()
elif plat == Platform.WINDOWS:
reg_path = (
"Software\\Microsoft\\Windows\\Shell\\Associations\\"
"UrlAssociations\\https\\UserChoice"
)
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, reg_path) as key:
default = winreg.QueryValueEx(key, "ProgId")
if default is None:
logger.warning("Could not determine default browser")
return None
default = default[0].lower()
default = _default_browser_win()
else:
logger.warning("Default browser feature not supported on this OS")
return None

if default is None:
# no need to continue checking default
return None

# ---- convert obtained default to something we understand ----
all_browsers = get_browsers()

Expand Down
76 changes: 32 additions & 44 deletions tests/test_default_browser.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,19 @@
# noqa: F401, F811
# pylint: disable=redefined-outer-name,unused-argument,unused-import

import webbrowser

import pytest

from browser_history.utils import default_browser, get_platform, Platform
from browser_history import browsers
from browser_history import browsers, utils

from .utils import become_mac, become_linux, become_windows # noqa: F401


platform = get_platform()
if platform == Platform.WINDOWS:
import winreg


class MockBrowser:
"""Mock version of return value of webbrowser.get()"""

def __init__(self, name=None):
self.name = name
platform = utils.get_platform()


@pytest.fixture
def change_webbrowser_default(monkeypatch, request):
"""Changes webbrowser.get() to return a specific named
def change_linux_default(monkeypatch, request):
"""Changes utils._default_browser_linux to return a specific named
browser. use @pytest.mark.browser_name(name) to set
browser name
"""
Expand All @@ -38,19 +26,17 @@ def change_webbrowser_default(monkeypatch, request):
browser_name = marker.args[0]

def mock_get():
return MockBrowser(name=browser_name)
return browser_name

monkeypatch.setattr(webbrowser, "get", mock_get)
monkeypatch.setattr(utils, "_default_browser_linux", mock_get)


@pytest.fixture
def change_reg_browser_default(monkeypatch, request):
"""Changes webbrowser.get() to return a specific named
def change_win_default(monkeypatch, request):
"""Changes utils._default_browser_win to return a specific named
browser. use @pytest.mark.browser_name(name) to set
browser name
"""
if platform != Platform.WINDOWS:
pytest.skip("Skipping windows registry based test")

marker = request.node.get_closest_marker("browser_name")

Expand All @@ -59,55 +45,57 @@ def change_reg_browser_default(monkeypatch, request):
else:
browser_name = marker.args[0]

def mock_QueryValueEx(key1, key2):
return [browser_name] if browser_name is not None else None
def mock_get():
return browser_name

monkeypatch.setattr(winreg, "QueryValueEx", mock_QueryValueEx)
monkeypatch.setattr(utils, "_default_browser_win", mock_get)


@pytest.mark.browser_name("firefox")
def test_default_firefox(become_linux, change_webbrowser_default): # noqa: F811
def test_default_firefox(become_linux, change_linux_default): # noqa: F811
"""Test that firefox set as default is recognised
correctly"""
assert default_browser() == browsers.Firefox
assert utils.default_browser() == browsers.Firefox


@pytest.mark.browser_name("chromehtml")
def test_default_chrome(become_linux, change_webbrowser_default): # noqa: F811
def test_default_chrome(become_linux, change_linux_default): # noqa: F811
"""Test that Chrome set as default is recognised
correctly"""
assert default_browser() == browsers.Chrome
assert utils.default_browser() == browsers.Chrome


def test_default_none(become_linux, change_webbrowser_default): # noqa: F811
def test_default_none(become_linux, change_linux_default): # noqa: F811
"""Test that no default set returns None"""
assert default_browser() is None
assert utils.default_browser() is None


@pytest.mark.browser_name("safari")
def test_default_safari(become_mac, change_webbrowser_default): # noqa: F811
def test_default_safari(become_mac, change_linux_default): # noqa: F811
"""Test that Safari set as default in MacOS is NOT
recognised correctly since default browser in MacOS is not
supported."""
assert default_browser() is None
assert utils.default_browser() is None


@pytest.mark.browser_name("chromehtml")
def test_default_windows_chrome(
become_windows, change_reg_browser_default # noqa: F811
):
def test_default_windows_chrome(become_windows, change_win_default): # noqa: F811
"""Test that chrome is identified correctly on Windows"""
assert default_browser() == browsers.Chrome
assert utils.default_browser() == browsers.Chrome


@pytest.mark.browser_name("firefoxurl-308046b0af4a39cb")
def test_default_windows_firefox(become_windows, change_win_default): # noqa: F811
"""Test that firefox is identified correctly on Windows"""
assert utils.default_browser() == browsers.Firefox


@pytest.mark.browser_name("firefoxurl")
def test_default_windows_firefox(
become_windows, change_reg_browser_default # noqa: F811
):
@pytest.mark.browser_name("idontexist-browser")
def test_default_unknown(become_windows, change_win_default): # noqa: F811
"""Test that firefox is identified correctly on Windows"""
assert default_browser() == browsers.Firefox
assert utils.default_browser() is None


def test_default_windows_none(become_windows, change_reg_browser_default): # noqa: F811
def test_default_windows_none(become_windows, change_win_default): # noqa: F811
"""Test that registry returning None is handled correctly"""
assert default_browser() is None
assert utils.default_browser() is None

0 comments on commit 8faf985

Please sign in to comment.