mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-04-24 23:37:18 +00:00
233 lines
9.5 KiB
Python
233 lines
9.5 KiB
Python
import pytest
|
|
import requests
|
|
|
|
from pathlib import Path
|
|
from pytest_mock import MockerFixture
|
|
from typing import Any
|
|
from unittest.mock import call as MockCall
|
|
|
|
from ahriman.core.configuration import Configuration
|
|
from ahriman.core.upload.github import GitHub
|
|
|
|
|
|
def test_github_release_tag(configuration: Configuration) -> None:
|
|
"""
|
|
must correctly define GitHub release tag
|
|
"""
|
|
_, repository_id = configuration.check_loaded()
|
|
|
|
instance = GitHub(repository_id, configuration, "github:x86_64")
|
|
assert instance.github_release_tag == instance.github_release_tag_name == repository_id.architecture
|
|
|
|
configuration.set_option("github:x86_64", "use_full_release_name", "yes")
|
|
instance = GitHub(repository_id, configuration, "github:x86_64")
|
|
assert instance.github_release_tag == f"{repository_id.name}-{repository_id.architecture}"
|
|
assert instance.github_release_tag_name == f"{repository_id.name} {repository_id.architecture}"
|
|
|
|
|
|
def test_asset_remove(github: GitHub, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
|
"""
|
|
must remove asset from the release
|
|
"""
|
|
request_mock = mocker.patch("ahriman.core.upload.github.GitHub.make_request")
|
|
github.asset_remove(github_release, "asset_name")
|
|
request_mock.assert_called_once_with("DELETE", "asset_url")
|
|
|
|
|
|
def test_asset_remove_unknown(github: GitHub, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
|
"""
|
|
must not fail if no asset found
|
|
"""
|
|
request_mock = mocker.patch("ahriman.core.upload.github.GitHub.make_request")
|
|
github.asset_remove(github_release, "unknown_asset_name")
|
|
request_mock.assert_not_called()
|
|
|
|
|
|
def test_asset_upload(github: GitHub, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
|
"""
|
|
must upload asset to the repository
|
|
"""
|
|
mocker.patch("pathlib.Path.open")
|
|
request_mock = mocker.patch("ahriman.core.upload.github.GitHub.make_request")
|
|
remove_mock = mocker.patch("ahriman.core.upload.github.GitHub.asset_remove")
|
|
|
|
github.asset_upload(github_release, Path("/root/new.tar.xz"))
|
|
request_mock.assert_called_once_with("POST", "upload_url", params=[("name", "new.tar.xz")],
|
|
data=pytest.helpers.anyvar(int),
|
|
headers={"Content-Type": "application/x-tar"})
|
|
remove_mock.assert_not_called()
|
|
|
|
|
|
def test_asset_upload_with_removal(github: GitHub, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
|
"""
|
|
must remove existing file before upload
|
|
"""
|
|
mocker.patch("pathlib.Path.open")
|
|
mocker.patch("ahriman.core.upload.github.GitHub.make_request")
|
|
remove_mock = mocker.patch("ahriman.core.upload.github.GitHub.asset_remove")
|
|
|
|
github.asset_upload(github_release, Path("asset_name"))
|
|
github.asset_upload(github_release, Path("/root/asset_name"))
|
|
remove_mock.assert_has_calls([
|
|
MockCall(github_release, "asset_name"),
|
|
MockCall(github_release, "asset_name"),
|
|
])
|
|
|
|
|
|
def test_asset_upload_empty_mimetype(github: GitHub, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
|
"""
|
|
must upload asset to the repository with empty mime type if the library cannot guess it
|
|
"""
|
|
mocker.patch("pathlib.Path.open")
|
|
mocker.patch("ahriman.core.upload.github.GitHub.asset_remove")
|
|
mocker.patch("mimetypes.guess_type", return_value=(None, None))
|
|
request_mock = mocker.patch("ahriman.core.upload.github.GitHub.make_request")
|
|
|
|
github.asset_upload(github_release, Path("/root/new.tar.xz"))
|
|
request_mock.assert_called_once_with("POST", "upload_url", params=[("name", "new.tar.xz")],
|
|
data=pytest.helpers.anyvar(int),
|
|
headers={"Content-Type": "application/octet-stream"})
|
|
|
|
|
|
def test_files_remove(github: GitHub, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
|
"""
|
|
must remove files from the remote
|
|
"""
|
|
remove_mock = mocker.patch("ahriman.core.upload.github.GitHub.asset_remove")
|
|
github.files_remove(github_release, {Path("a"): "a"}, {"a": "a", "b": "b"})
|
|
remove_mock.assert_called_once_with(github_release, "b")
|
|
|
|
|
|
def test_files_remove_empty(github: GitHub, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
|
"""
|
|
must remove nothing if nothing changed
|
|
"""
|
|
remove_mock = mocker.patch("ahriman.core.upload.github.GitHub.asset_remove")
|
|
github.files_remove(github_release, {Path("a"): "a"}, {"a": "a"})
|
|
remove_mock.assert_not_called()
|
|
|
|
|
|
def test_files_upload(github: GitHub, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
|
"""
|
|
must upload files to the remote
|
|
"""
|
|
upload_mock = mocker.patch("ahriman.core.upload.github.GitHub.asset_upload")
|
|
github.files_upload(github_release, {Path("a"): "a", Path("b"): "c", Path("c"): "c"}, {"a": "a", "b": "b"})
|
|
upload_mock.assert_has_calls([
|
|
MockCall(github_release, Path("b")),
|
|
MockCall(github_release, Path("c")),
|
|
])
|
|
|
|
|
|
def test_files_upload_empty(github: GitHub, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
|
"""
|
|
must upload nothing if nothing changed
|
|
"""
|
|
upload_mock = mocker.patch("ahriman.core.upload.github.GitHub.asset_upload")
|
|
github.files_upload(github_release, {Path("a"): "a"}, {"a": "a"})
|
|
upload_mock.assert_not_called()
|
|
|
|
|
|
def test_get_local_files(github: GitHub, resource_path_root: Path, mocker: MockerFixture) -> None:
|
|
"""
|
|
must get all local files recursively
|
|
"""
|
|
walk_mock = mocker.patch("ahriman.core.upload.github.walk")
|
|
github.get_local_files(resource_path_root)
|
|
walk_mock.assert_called()
|
|
|
|
|
|
def test_release_create(github: GitHub, mocker: MockerFixture) -> None:
|
|
"""
|
|
must create release
|
|
"""
|
|
request_mock = mocker.patch("ahriman.core.upload.github.GitHub.make_request")
|
|
github.release_create()
|
|
request_mock.assert_called_once_with(
|
|
"POST", pytest.helpers.anyvar(str, True),
|
|
json={"tag_name": github.github_release_tag, "name": github.github_release_tag_name})
|
|
|
|
|
|
def test_release_get(github: GitHub, mocker: MockerFixture) -> None:
|
|
"""
|
|
must get release
|
|
"""
|
|
request_mock = mocker.patch("ahriman.core.upload.github.GitHub.make_request")
|
|
github.release_get()
|
|
request_mock.assert_called_once_with("GET", pytest.helpers.anyvar(str, True))
|
|
|
|
|
|
def test_release_get_empty(github: GitHub, mocker: MockerFixture) -> None:
|
|
"""
|
|
must return nothing in case of 404 status code
|
|
"""
|
|
response = requests.Response()
|
|
response.status_code = 404
|
|
mocker.patch("ahriman.core.upload.github.GitHub.make_request",
|
|
side_effect=requests.HTTPError(response=response))
|
|
assert github.release_get() is None
|
|
|
|
|
|
def test_release_get_exception(github: GitHub, mocker: MockerFixture) -> None:
|
|
"""
|
|
must re-raise non HTTPError exception
|
|
"""
|
|
mocker.patch("ahriman.core.upload.github.GitHub.make_request", side_effect=Exception())
|
|
with pytest.raises(Exception):
|
|
github.release_get()
|
|
|
|
|
|
def test_release_get_exception_http_error(github: GitHub, mocker: MockerFixture) -> None:
|
|
"""
|
|
must re-raise HTTPError exception with code differs from 404
|
|
"""
|
|
exception = requests.HTTPError(response=requests.Response())
|
|
mocker.patch("ahriman.core.upload.github.GitHub.make_request", side_effect=exception)
|
|
with pytest.raises(requests.HTTPError):
|
|
github.release_get()
|
|
|
|
|
|
def test_release_update(github: GitHub, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
|
"""
|
|
must update release
|
|
"""
|
|
request_mock = mocker.patch("ahriman.core.upload.github.GitHub.make_request")
|
|
github.release_update(github_release, "body")
|
|
request_mock.assert_called_once_with("POST", "release_url", json={"body": "body"})
|
|
|
|
|
|
def test_release_sync(github: GitHub, mocker: MockerFixture) -> None:
|
|
"""
|
|
must run sync command
|
|
"""
|
|
release_get_mock = mocker.patch("ahriman.core.upload.github.GitHub.release_get", return_value={})
|
|
get_hashes_mock = mocker.patch("ahriman.core.upload.github.GitHub.get_hashes", return_value={})
|
|
get_local_files_mock = mocker.patch("ahriman.core.upload.github.GitHub.get_local_files", return_value={})
|
|
files_upload_mock = mocker.patch("ahriman.core.upload.github.GitHub.files_upload")
|
|
files_remove_mock = mocker.patch("ahriman.core.upload.github.GitHub.files_remove")
|
|
release_update_mock = mocker.patch("ahriman.core.upload.github.GitHub.release_update")
|
|
|
|
github.sync(Path("local"), [])
|
|
release_get_mock.assert_called_once_with()
|
|
get_hashes_mock.assert_called_once_with("")
|
|
get_local_files_mock.assert_called_once_with(Path("local"))
|
|
files_upload_mock.assert_called_once_with({}, {}, {})
|
|
files_remove_mock.assert_called_once_with({}, {}, {})
|
|
release_update_mock.assert_called_once_with({}, pytest.helpers.anyvar(int))
|
|
|
|
|
|
def test_release_sync_create_release(github: GitHub, mocker: MockerFixture) -> None:
|
|
"""
|
|
must create release in case if it does not exist
|
|
"""
|
|
mocker.patch("ahriman.core.upload.github.GitHub.release_get", return_value=None)
|
|
mocker.patch("ahriman.core.upload.github.GitHub.get_hashes")
|
|
mocker.patch("ahriman.core.upload.github.GitHub.get_local_files")
|
|
mocker.patch("ahriman.core.upload.github.GitHub.files_upload")
|
|
mocker.patch("ahriman.core.upload.github.GitHub.files_remove")
|
|
mocker.patch("ahriman.core.upload.github.GitHub.release_update")
|
|
release_create_mock = mocker.patch("ahriman.core.upload.github.GitHub.release_create")
|
|
|
|
github.sync(Path("local"), [])
|
|
release_create_mock.assert_called_once_with()
|