Added tests for updater.core
This commit is contained in:
parent
2a8294d6d0
commit
455c987b67
0
test/__init__.py
Normal file
0
test/__init__.py
Normal file
13
test/conftest.py
Normal file
13
test/conftest.py
Normal file
@ -0,0 +1,13 @@
|
||||
import pytest
|
||||
import json
|
||||
|
||||
update_data= dict(current_version="1.1", description="Snapshot version.", downloads=dict(Windows32="https://google.com_32", Windows64="https://google.com_64"))
|
||||
@pytest.fixture
|
||||
def file_data():
|
||||
global update_data
|
||||
yield json.dumps(update_data)
|
||||
|
||||
@pytest.fixture
|
||||
def json_data():
|
||||
global update_data
|
||||
yield update_data
|
BIN
test/helloworld_v2_win64.zip
Normal file
BIN
test/helloworld_v2_win64.zip
Normal file
Binary file not shown.
164
test/test_core.py
Normal file
164
test/test_core.py
Normal file
@ -0,0 +1,164 @@
|
||||
import sys
|
||||
import os
|
||||
import pytest
|
||||
import requests_mock
|
||||
from unittest import mock
|
||||
from json.decoder import JSONDecodeError
|
||||
from requests.exceptions import HTTPError
|
||||
from updater import core
|
||||
|
||||
app_name: str = "a simple app"
|
||||
current_version: str = "0.15"
|
||||
endpoint: str = "https://gitlab.mcvsoftware.com"
|
||||
|
||||
# Fake a win32api module, as this fails on non-windows platforms without this hack.
|
||||
# ToDo: Find a way to do this better.
|
||||
win32api = mock.Mock(name="win32api")
|
||||
win32api.__name__ = "win32api"
|
||||
sys.modules["win32api"] = win32api
|
||||
|
||||
def test_requests_session():
|
||||
global app_name, current_version, endpoint
|
||||
updater = core.updaterCore(endpoint=endpoint, app_name=app_name, current_version=current_version)
|
||||
updater.create_session()
|
||||
assert hasattr(updater, "session")
|
||||
assert app_name in updater.session.headers.get("User-Agent")
|
||||
assert current_version in updater.session.headers.get("User-Agent")
|
||||
|
||||
def test_get_update_information_valid_json(file_data, json_data):
|
||||
global app_name, current_version, endpoint
|
||||
updater = core.updaterCore(endpoint=endpoint, app_name=app_name, current_version=current_version)
|
||||
updater.create_session()
|
||||
with requests_mock.Mocker(session=updater.session) as mocked:
|
||||
mocked.get(endpoint, json=json_data)
|
||||
contents = updater.get_update_information()
|
||||
assert contents == json_data
|
||||
|
||||
def test_get_update_information_invalid_json(file_data, json_data):
|
||||
global app_name, current_version, endpoint
|
||||
updater = core.updaterCore(endpoint=endpoint, app_name=app_name, current_version=current_version)
|
||||
updater.create_session()
|
||||
with requests_mock.Mocker(session=updater.session) as mocked:
|
||||
mocked.get(endpoint, text="thisisnotjson")
|
||||
with pytest.raises(JSONDecodeError):
|
||||
contents = updater.get_update_information()
|
||||
|
||||
def test_get_update_information_not_found():
|
||||
global app_name, current_version, endpoint
|
||||
updater = core.updaterCore(endpoint=endpoint, app_name=app_name, current_version=current_version)
|
||||
updater.create_session()
|
||||
with requests_mock.Mocker(session=updater.session) as mocked:
|
||||
mocked.get(endpoint, status_code=404)
|
||||
with pytest.raises(HTTPError):
|
||||
contents = updater.get_update_information()
|
||||
|
||||
def test_version_data_no_update(json_data):
|
||||
global app_name, endpoint
|
||||
updater = core.updaterCore(endpoint=endpoint, app_name=app_name, current_version=json_data.get("current_version"))
|
||||
updater.create_session()
|
||||
results = updater.get_version_data(json_data)
|
||||
assert results == (False, False, False)
|
||||
|
||||
@pytest.mark.parametrize("platform, architecture", [
|
||||
("Windows", ("32bit", "")),
|
||||
("Windows", ("64bit", "")),
|
||||
])
|
||||
def test_version_data_update_available(json_data, platform, architecture):
|
||||
global app_name, current_version, endpoint
|
||||
updater = core.updaterCore(endpoint=endpoint, app_name=app_name, current_version=current_version)
|
||||
updater.create_session()
|
||||
with mock.patch("platform.system", return_value=platform):
|
||||
with mock.patch("platform.architecture", return_value=architecture):
|
||||
results = updater.get_version_data(json_data)
|
||||
k = platform+architecture[0][:2]
|
||||
assert results == (json_data["current_version"], json_data["description"], json_data["downloads"][k])
|
||||
|
||||
def test_version_data_architecture_not_found(json_data):
|
||||
global app_name, current_version, endpoint
|
||||
updater = core.updaterCore(endpoint=endpoint, app_name=app_name, current_version=current_version)
|
||||
updater.create_session()
|
||||
with mock.patch("platform.system", return_value="nonos"):
|
||||
with mock.patch("platform.architecture", return_value=("31bits", "")):
|
||||
with pytest.raises(KeyError):
|
||||
results = updater.get_version_data(json_data)
|
||||
|
||||
def test_download_update():
|
||||
global app_name, current_version, endpoint
|
||||
updater = core.updaterCore(endpoint=endpoint, app_name=app_name, current_version=current_version)
|
||||
updater.create_session()
|
||||
with mock.patch("pubsub.pub.sendMessage") as sendMessage_mock:
|
||||
with mock.patch("io.open") as open_mock:
|
||||
with requests_mock.Mocker(session=updater.session) as mocker:
|
||||
updatefile = os.path.join(os.path.dirname(__file__), "helloworld_v2_win64.zip")
|
||||
mocker.get("http://downloads.update.org/update.zip", body=open(updatefile, "rb"))
|
||||
result = updater.download_update(update_url="http://downloads.update.org/update.zip", update_destination="update.zip")
|
||||
open_mock.assert_called_once_with("update.zip", "w+b")
|
||||
assert result == "update.zip"
|
||||
assert sendMessage_mock.call_count > 0
|
||||
|
||||
def test_extract_archive():
|
||||
# This only tests if archive extraction methods were called successfully and with the right parameters.
|
||||
global app_name, current_version, endpoint
|
||||
updater = core.updaterCore(endpoint=endpoint, app_name=app_name, current_version=current_version)
|
||||
zipfile_opened = mock.MagicMock()
|
||||
with mock.patch("zipfile.ZipFile", return_value=zipfile_opened) as zipfile_mock:
|
||||
result = updater.extract_update("update.zip", os.path.dirname(__file__))
|
||||
assert result == os.path.dirname(__file__)
|
||||
zipfile_mock.called_once_with("update.zip")
|
||||
zipfile_opened.extractall.assert_called_once()
|
||||
# Test a password protected update file.
|
||||
zipfile_opened_with_password = mock.MagicMock()
|
||||
with mock.patch("zipfile.ZipFile", return_value=zipfile_opened_with_password) as zipfile_mock:
|
||||
# Set a password manually.
|
||||
updater.password = "MyLongPassword"
|
||||
result2 = updater.extract_update("update.zip", os.path.dirname(__file__))
|
||||
assert result2 == os.path.dirname(__file__)
|
||||
zipfile_mock.called_once_with("update.zip")
|
||||
zipfile_opened_with_password.setpassword.called_once_with("MyLongPassword")
|
||||
zipfile_opened_with_password.extractall.assert_called_once()
|
||||
|
||||
@pytest.mark.parametrize("system", [("Windows"), ("Darwin"), ("Linux")])
|
||||
def test_move_bootstrap(system):
|
||||
global app_name, current_version, endpoint
|
||||
updater = core.updaterCore(endpoint=endpoint, app_name=app_name, current_version=current_version)
|
||||
# provide a fake extraction path.
|
||||
extracted_path = os.path.dirname(__file__)
|
||||
# supposedly, the bootstrap file should be moved to the parent path.
|
||||
|
||||
with mock.patch("platform.system", return_value=system):
|
||||
with mock.patch("os.rename") as os_rename:
|
||||
expected_path = os.path.abspath(os.path.join(extracted_path, "..", updater.bootstrap_name()))
|
||||
result = updater.move_bootstrap(extracted_path)
|
||||
assert result == expected_path
|
||||
os_rename.assert_called_once()
|
||||
|
||||
@pytest.mark.parametrize("system", [("Windows"), ("Darwin"), ("Linux")])
|
||||
def test_execute_bootstrap(system):
|
||||
global app_name, current_version, endpoint
|
||||
updater = core.updaterCore(endpoint=endpoint, app_name=app_name, current_version=current_version)
|
||||
with mock.patch("platform.system", return_value=system):
|
||||
with mock.patch("os.stat") as os_stat:
|
||||
with mock.patch("subprocess.Popen") as subprocess_popen:
|
||||
with mock.patch("os.chmod") as os_chmod:
|
||||
with mock.patch("win32api.ShellExecute") as win32api_ShellExecute:
|
||||
bootstrap_path = os.path.join(os.path.dirname(__file__), updater.bootstrap_name())
|
||||
source_path = os.path.dirname(__file__)
|
||||
updater.execute_bootstrap(bootstrap_path, source_path)
|
||||
if system == "Windows":
|
||||
win32api_ShellExecute.assert_called_once()
|
||||
else:
|
||||
os_chmod.assert_called_once()
|
||||
os_stat.assert_called_once()
|
||||
subprocess_popen.assert_called_once()
|
||||
|
||||
@pytest.mark.parametrize("system, bootstrap_file", [
|
||||
("Windows", "bootstrap.exe"),
|
||||
("Darwin", "bootstrap-mac.sh"),
|
||||
("Linux", "bootstrap-lin.sh")
|
||||
])
|
||||
def test_bootstrap_name(system, bootstrap_file):
|
||||
global app_name, current_version, endpoint
|
||||
updater = core.updaterCore(endpoint=endpoint, app_name=app_name, current_version=current_version)
|
||||
with mock.patch("platform.system", return_value=system):
|
||||
result = updater.bootstrap_name()
|
||||
assert result == bootstrap_file
|
Loading…
Reference in New Issue
Block a user