Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 26 additions & 14 deletions tests/unit/actions/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import pytest

from hcloud import Client
from hcloud.actions import (
Action,
ActionFailedException,
Expand All @@ -16,41 +17,52 @@

class TestBoundAction:
@pytest.fixture()
def bound_running_action(self, mocked_requests):
action_client = ActionsClient(client=mocked_requests)
def bound_running_action(self, client: Client):
# Speed up tests that run `wait_until_finished`
action_client._client._poll_interval_func = lambda _: 0.0
action_client._client._poll_max_retries = 3
client._poll_interval_func = lambda _: 0.0
client._poll_max_retries = 3

return BoundAction(
client=action_client,
client=client.actions,
data=dict(id=14, status=Action.STATUS_RUNNING),
)

def test_wait_until_finished(
self, bound_running_action, mocked_requests, running_action, successfully_action
self,
request_mock: mock.MagicMock,
bound_running_action,
running_action,
successfully_action,
):
mocked_requests.request.side_effect = [running_action, successfully_action]
request_mock.side_effect = [running_action, successfully_action]
bound_running_action.wait_until_finished()
mocked_requests.request.assert_called_with(url="/actions/2", method="GET")
request_mock.assert_called_with(url="/actions/2", method="GET")

assert bound_running_action.status == "success"
assert mocked_requests.request.call_count == 2
assert request_mock.call_count == 2

def test_wait_until_finished_with_error(
self, bound_running_action, mocked_requests, running_action, failed_action
self,
request_mock: mock.MagicMock,
bound_running_action,
running_action,
failed_action,
):
mocked_requests.request.side_effect = [running_action, failed_action]
request_mock.side_effect = [running_action, failed_action]
with pytest.raises(ActionFailedException) as exception_info:
bound_running_action.wait_until_finished()

assert bound_running_action.status == "error"
assert exception_info.value.action.id == 2

def test_wait_until_finished_max_retries(
self, bound_running_action, mocked_requests, running_action, successfully_action
self,
request_mock: mock.MagicMock,
bound_running_action,
running_action,
successfully_action,
):
mocked_requests.request.side_effect = [
request_mock.side_effect = [
running_action,
running_action,
successfully_action,
Expand All @@ -60,7 +72,7 @@ def test_wait_until_finished_max_retries(

assert bound_running_action.status == "running"
assert exception_info.value.action.id == 2
assert mocked_requests.request.call_count == 1
assert request_mock.call_count == 1


class TestResourceActionsClient:
Expand Down
63 changes: 42 additions & 21 deletions tests/unit/certificates/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import pytest

from hcloud import Client
from hcloud.actions import BoundAction
from hcloud.certificates import (
BoundCertificate,
Expand All @@ -15,16 +16,21 @@

class TestBoundCertificate:
@pytest.fixture()
def bound_certificate(self, hetzner_client):
return BoundCertificate(client=hetzner_client.certificates, data=dict(id=14))
def bound_certificate(self, client: Client):
return BoundCertificate(client.certificates, data=dict(id=14))

@pytest.mark.parametrize("params", [{"page": 1, "per_page": 10}, {}])
def test_get_actions_list(
self, hetzner_client, bound_certificate, response_get_actions, params
self,
request_mock: mock.MagicMock,
client: Client,
bound_certificate,
response_get_actions,
params,
):
hetzner_client.request.return_value = response_get_actions
request_mock.return_value = response_get_actions
result = bound_certificate.get_actions_list(**params)
hetzner_client.request.assert_called_with(
request_mock.assert_called_with(
url="/certificates/14/actions", method="GET", params=params
)

Expand All @@ -33,23 +39,29 @@ def test_get_actions_list(

assert len(actions) == 1
assert isinstance(actions[0], BoundAction)
assert actions[0]._client == hetzner_client.actions
assert actions[0]._client == client.actions
assert actions[0].id == 13
assert actions[0].command == "change_protection"

def test_get_actions(self, hetzner_client, bound_certificate, response_get_actions):
hetzner_client.request.return_value = response_get_actions
def test_get_actions(
self,
request_mock: mock.MagicMock,
client: Client,
bound_certificate,
response_get_actions,
):
request_mock.return_value = response_get_actions
actions = bound_certificate.get_actions()

params = {"page": 1, "per_page": 50}

hetzner_client.request.assert_called_with(
request_mock.assert_called_with(
url="/certificates/14/actions", method="GET", params=params
)

assert len(actions) == 1
assert isinstance(actions[0], BoundAction)
assert actions[0]._client == hetzner_client.actions
assert actions[0]._client == client.actions
assert actions[0].id == 13
assert actions[0].command == "change_protection"

Expand Down Expand Up @@ -77,32 +89,41 @@ def test_bound_certificate_init(self, certificate_response):
assert bound_certificate.status.error.message == "error message"

def test_update(
self, hetzner_client, bound_certificate, response_update_certificate
self,
request_mock: mock.MagicMock,
bound_certificate,
response_update_certificate,
):
hetzner_client.request.return_value = response_update_certificate
request_mock.return_value = response_update_certificate
certificate = bound_certificate.update(name="New name")
hetzner_client.request.assert_called_with(
request_mock.assert_called_with(
url="/certificates/14", method="PUT", json={"name": "New name"}
)

assert certificate.id == 2323
assert certificate.name == "New name"

def test_delete(self, hetzner_client, bound_certificate, generic_action):
hetzner_client.request.return_value = generic_action
def test_delete(
self,
request_mock: mock.MagicMock,
bound_certificate,
generic_action,
):
request_mock.return_value = generic_action
delete_success = bound_certificate.delete()
hetzner_client.request.assert_called_with(
url="/certificates/14", method="DELETE"
)
request_mock.assert_called_with(url="/certificates/14", method="DELETE")

assert delete_success is True

def test_retry_issuance(
self, hetzner_client, bound_certificate, response_retry_issuance_action
self,
request_mock: mock.MagicMock,
bound_certificate,
response_retry_issuance_action,
):
hetzner_client.request.return_value = response_retry_issuance_action
request_mock.return_value = response_retry_issuance_action
action = bound_certificate.retry_issuance()
hetzner_client.request.assert_called_with(
request_mock.assert_called_with(
url="/certificates/14/actions/retry", method="POST"
)

Expand Down
18 changes: 12 additions & 6 deletions tests/unit/conftest.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# pylint: disable=redefined-outer-name

from __future__ import annotations

from unittest import mock
Expand All @@ -7,12 +9,16 @@
from hcloud import Client


@pytest.fixture(autouse=True, scope="function")
def mocked_requests():
patcher = mock.patch("hcloud._client.requests")
mocked_requests = patcher.start()
yield mocked_requests
patcher.stop()
@pytest.fixture()
def request_mock() -> mock.MagicMock:
return mock.MagicMock()


@pytest.fixture()
def client(request_mock) -> Client:
c = Client(token="TOKEN")
c.request = request_mock
return c


@pytest.fixture()
Expand Down
Loading