From f959e9459cecd5ce3bc9e41a4ce92c4d80bc03ca Mon Sep 17 00:00:00 2001 From: jo Date: Wed, 13 Aug 2025 19:33:29 +0200 Subject: [PATCH] tests: use request_mock fixture everywhere --- tests/unit/actions/conftest.py | 79 -- tests/unit/actions/test_client.py | 383 ++++--- tests/unit/certificates/test_client.py | 288 +++--- tests/unit/conftest.py | 127 ++- tests/unit/datacenters/test_client.py | 53 +- tests/unit/firewalls/test_client.py | 274 ++--- tests/unit/floating_ips/test_client.py | 332 +++--- tests/unit/images/test_client.py | 232 ++--- tests/unit/isos/test_client.py | 45 +- tests/unit/load_balancer_types/test_client.py | 57 +- tests/unit/load_balancers/test_client.py | 353 +++---- tests/unit/locations/test_client.py | 53 +- tests/unit/networks/test_client.py | 435 ++++---- tests/unit/placement_groups/test_client.py | 92 +- tests/unit/primary_ips/test_client.py | 277 ++--- tests/unit/server_types/test_client.py | 59 +- tests/unit/servers/conftest.py | 104 -- tests/unit/servers/test_client.py | 964 +++++++++++------- tests/unit/ssh_keys/test_client.py | 125 ++- tests/unit/volumes/test_client.py | 349 ++++--- 20 files changed, 2452 insertions(+), 2229 deletions(-) delete mode 100644 tests/unit/actions/conftest.py diff --git a/tests/unit/actions/conftest.py b/tests/unit/actions/conftest.py deleted file mode 100644 index dbc3cc9f..00000000 --- a/tests/unit/actions/conftest.py +++ /dev/null @@ -1,79 +0,0 @@ -from __future__ import annotations - -import pytest - - -@pytest.fixture() -def generic_action_list(): - return { - "actions": [ - { - "id": 1, - "command": "start_server", - "status": "success", - "progress": 100, - "started": "2016-01-30T23:55:00+00:00", - "finished": "2016-01-30T23:56:00+00:00", - "resources": [{"id": 42, "type": "server"}], - "error": {"code": "action_failed", "message": "Action failed"}, - }, - { - "id": 2, - "command": "stop_server", - "status": "success", - "progress": 100, - "started": "2016-01-30T23:55:00+00:00", - "finished": "2016-01-30T23:56:00+00:00", - "resources": [{"id": 42, "type": "server"}], - "error": {"code": "action_failed", "message": "Action failed"}, - }, - ] - } - - -@pytest.fixture() -def running_action(): - return { - "action": { - "id": 2, - "command": "stop_server", - "status": "running", - "progress": 100, - "started": "2016-01-30T23:55:00+00:00", - "finished": "2016-01-30T23:56:00+00:00", - "resources": [{"id": 42, "type": "server"}], - "error": {"code": "action_failed", "message": "Action failed"}, - } - } - - -@pytest.fixture() -def successfully_action(): - return { - "action": { - "id": 2, - "command": "stop_server", - "status": "success", - "progress": 100, - "started": "2016-01-30T23:55:00+00:00", - "finished": "2016-01-30T23:56:00+00:00", - "resources": [{"id": 42, "type": "server"}], - "error": {"code": "action_failed", "message": "Action failed"}, - } - } - - -@pytest.fixture() -def failed_action(): - return { - "action": { - "id": 2, - "command": "stop_server", - "status": "error", - "progress": 100, - "started": "2016-01-30T23:55:00+00:00", - "finished": "2016-01-30T23:56:00+00:00", - "resources": [{"id": 42, "type": "server"}], - "error": {"code": "action_failed", "message": "Action failed"}, - } - } diff --git a/tests/unit/actions/test_client.py b/tests/unit/actions/test_client.py index f9943087..7534d030 100644 --- a/tests/unit/actions/test_client.py +++ b/tests/unit/actions/test_client.py @@ -4,196 +4,337 @@ import pytest +from hcloud import Client from hcloud.actions import ( - Action, ActionFailedException, - ActionsClient, ActionTimeoutException, BoundAction, ResourceActionsClient, ) +from hcloud.core import ClientEntityBase + +from ..conftest import assert_action1, assert_action2 class TestBoundAction: @pytest.fixture() - def bound_running_action(self, mocked_requests): - action_client = ActionsClient(client=mocked_requests) + def bound_action(self, client: Client, action1_running): # 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, - data=dict(id=14, status=Action.STATUS_RUNNING), + client=client.actions, + data=action1_running, ) def test_wait_until_finished( - self, bound_running_action, mocked_requests, running_action, successfully_action + self, + request_mock: mock.MagicMock, + bound_action: BoundAction, + action1_running, + action1_success, ): - mocked_requests.request.side_effect = [running_action, successfully_action] - bound_running_action.wait_until_finished() - mocked_requests.request.assert_called_with(url="/actions/2", method="GET") - - assert bound_running_action.status == "success" - assert mocked_requests.request.call_count == 2 - - def test_wait_until_finished_with_error( - self, bound_running_action, mocked_requests, running_action, failed_action + request_mock.side_effect = [ + {"action": action1_running}, + {"action": action1_success}, + ] + bound_action.wait_until_finished() + request_mock.assert_called_with(url="/actions/1", method="GET") + + assert bound_action.status == "success" + assert request_mock.call_count == 2 + + def test_wait_until_finished_error( + self, + request_mock: mock.MagicMock, + bound_action: BoundAction, + action1_running, + action1_error, ): - mocked_requests.request.side_effect = [running_action, failed_action] + request_mock.side_effect = [ + {"action": action1_running}, + {"action": action1_error}, + ] with pytest.raises(ActionFailedException) as exception_info: - bound_running_action.wait_until_finished() + bound_action.wait_until_finished() - assert bound_running_action.status == "error" - assert exception_info.value.action.id == 2 + assert bound_action.status == "error" + assert exception_info.value.action.id == 1 + assert request_mock.call_count == 2 def test_wait_until_finished_max_retries( - self, bound_running_action, mocked_requests, running_action, successfully_action + self, + request_mock: mock.MagicMock, + bound_action: BoundAction, + action1_running, ): - mocked_requests.request.side_effect = [ - running_action, - running_action, - successfully_action, + request_mock.side_effect = [ + {"action": action1_running}, + {"action": action1_running}, ] with pytest.raises(ActionTimeoutException) as exception_info: - bound_running_action.wait_until_finished(max_retries=1) + bound_action.wait_until_finished(max_retries=1) + + assert bound_action.status == "running" + assert exception_info.value.action.id == 1 + assert request_mock.call_count == 1 + - assert bound_running_action.status == "running" - assert exception_info.value.action.id == 2 - assert mocked_requests.request.call_count == 1 +def resources_with_actions_client(): + """ + Allows us to run TestResourceActionsClient against all resource clients that have an + resource actions client. + """ + result = [] + client = Client("TOKEN") + for var in vars(client): + prop = getattr(client, var) + # Save the property name when it is a resource client, and the resource client + # has a resource actions client. + if isinstance(prop, ClientEntityBase) and hasattr(prop, "actions"): + result.append(var) + + return result class TestResourceActionsClient: + @pytest.fixture(params=resources_with_actions_client()) + def resource(self, request): + return request.param + @pytest.fixture() - def actions_client(self): - return ResourceActionsClient(client=mock.MagicMock(), resource="/resource") - - def test_get_by_id(self, actions_client, generic_action): - actions_client._client.request.return_value = generic_action - action = actions_client.get_by_id(1) - actions_client._client.request.assert_called_with( - url="/resource/actions/1", method="GET" + def actions_client(self, client: Client, resource: str): + resource_client = getattr(client, resource) + assert isinstance(resource_client.actions, ResourceActionsClient) + return resource_client.actions + + def test_get_by_id( + self, + request_mock: mock.MagicMock, + actions_client: ResourceActionsClient, + resource: str, + action_response, + ): + request_mock.return_value = action_response + + result = actions_client.get_by_id(1) + + request_mock.assert_called_with( + method="GET", + url=f"/{resource}/actions/1", ) - assert action._client == actions_client._client.actions - assert action.id == 1 - assert action.command == "stop_server" + + assert_action1(result, actions_client._client) @pytest.mark.parametrize( "params", - [{}, {"status": ["active"], "sort": ["status"], "page": 2, "per_page": 10}], + [ + {}, + {"status": ["running"], "sort": ["status"], "page": 2, "per_page": 10}, + ], ) - def test_get_list(self, actions_client, generic_action_list, params): - actions_client._client.request.return_value = generic_action_list + def test_get_list( + self, + request_mock: mock.MagicMock, + actions_client: ResourceActionsClient, + resource: str, + action_list_response, + params, + ): + request_mock.return_value = action_list_response + result = actions_client.get_list(**params) - actions_client._client.request.assert_called_with( - url="/resource/actions", method="GET", params=params + + request_mock.assert_called_with( + url=f"/{resource}/actions", + method="GET", + params=params, ) assert result.meta is not None - actions = result.actions - assert len(actions) == 2 + assert len(result.actions) == 2 + assert_action1(result.actions[0], actions_client._client) + assert_action2(result.actions[1], actions_client._client) + + @pytest.mark.parametrize( + "params", + [ + {}, + {"status": ["running"], "sort": ["status"]}, + ], + ) + def test_get_all( + self, + request_mock: mock.MagicMock, + actions_client: ResourceActionsClient, + resource: str, + action_list_response, + params, + ): + request_mock.return_value = action_list_response + + result = actions_client.get_all(**params) - action1 = actions[0] - action2 = actions[1] + request_mock.assert_called_with( + url=f"/{resource}/actions", + method="GET", + params={**params, "page": 1, "per_page": 50}, + ) - assert action1._client == actions_client._client.actions - assert action1.id == 1 - assert action1.command == "start_server" + assert len(result) == 2 + assert_action1(result[0], actions_client._client) + assert_action2(result[1], actions_client._client) - assert action2._client == actions_client._client.actions - assert action2.id == 2 - assert action2.command == "stop_server" - @pytest.mark.parametrize("params", [{}, {"status": ["active"], "sort": ["status"]}]) - def test_get_all(self, actions_client, generic_action_list, params): - actions_client._client.request.return_value = generic_action_list - actions = actions_client.get_all(**params) +class TestResourceClientActions: + @pytest.fixture(params=resources_with_actions_client()) + def resource(self, request): + if request.param == "primary_ips": + pytest.skip("not implemented yet") + return request.param - params.update({"page": 1, "per_page": 50}) + @pytest.fixture() + def resource_client(self, client: Client, resource: str): + return getattr(client, resource) - actions_client._client.request.assert_called_with( - url="/resource/actions", method="GET", params=params + @pytest.mark.parametrize( + "params", + [ + {}, + {"status": ["running"], "sort": ["status"], "page": 2, "per_page": 10}, + ], + ) + def test_get_actions_list( + self, + request_mock: mock.MagicMock, + resource_client, + resource: str, + action_list_response, + params, + ): + request_mock.return_value = action_list_response + + result = resource_client.get_actions_list(mock.MagicMock(id=1), **params) + + request_mock.assert_called_with( + url=f"/{resource}/1/actions", + method="GET", + params=params, ) - assert len(actions) == 2 + assert result.meta is not None + + assert len(result.actions) == 2 + assert_action1(result.actions[0], resource_client._client) + assert_action2(result.actions[1], resource_client._client) + + @pytest.mark.parametrize( + "params", + [ + {}, + {"status": ["running"], "sort": ["status"]}, + ], + ) + def test_get_actions( + self, + request_mock: mock.MagicMock, + resource_client, + resource: str, + action_list_response, + params, + ): + request_mock.return_value = action_list_response - action1 = actions[0] - action2 = actions[1] + result = resource_client.get_actions(mock.MagicMock(id=1), **params) - assert action1._client == actions_client._client.actions - assert action1.id == 1 - assert action1.command == "start_server" + request_mock.assert_called_with( + url=f"/{resource}/1/actions", + method="GET", + params={**params, "page": 1, "per_page": 50}, + ) - assert action2._client == actions_client._client.actions - assert action2.id == 2 - assert action2.command == "stop_server" + assert len(result) == 2 + assert_action1(result[0], resource_client._client) + assert_action2(result[1], resource_client._client) class TestActionsClient: - @pytest.fixture() - def actions_client(self): - return ActionsClient(client=mock.MagicMock()) - - def test_get_by_id(self, actions_client, generic_action): - actions_client._client.request.return_value = generic_action - action = actions_client.get_by_id(1) - actions_client._client.request.assert_called_with( - url="/actions/1", method="GET" + def test_get_by_id( + self, + request_mock: mock.MagicMock, + client: Client, + action_response, + ): + request_mock.return_value = action_response + + result = client.actions.get_by_id(1) + + request_mock.assert_called_with( + method="GET", + url="/actions/1", ) - assert action._client == actions_client._client.actions - assert action.id == 1 - assert action.command == "stop_server" + assert_action1(result, client) @pytest.mark.parametrize( "params", - [{}, {"status": ["active"], "sort": ["status"], "page": 2, "per_page": 10}], + [ + {}, + {"status": ["running"], "sort": ["status"], "page": 2, "per_page": 10}, + ], ) - def test_get_list(self, actions_client, generic_action_list, params): - actions_client._client.request.return_value = generic_action_list + def test_get_list( + self, + request_mock: mock.MagicMock, + client: Client, + action_list_response, + params, + ): + request_mock.return_value = action_list_response + with pytest.deprecated_call(): - result = actions_client.get_list(**params) - actions_client._client.request.assert_called_with( - url="/actions", method="GET", params=params + result = client.actions.get_list(**params) + + request_mock.assert_called_with( + url="/actions", + method="GET", + params=params, ) assert result.meta is not None - actions = result.actions - assert len(actions) == 2 + assert len(result.actions) == 2 + assert_action1(result.actions[0], client) + assert_action2(result.actions[1], client) - action1 = actions[0] - action2 = actions[1] - - assert action1._client == actions_client._client.actions - assert action1.id == 1 - assert action1.command == "start_server" - - assert action2._client == actions_client._client.actions - assert action2.id == 2 - assert action2.command == "stop_server" + @pytest.mark.parametrize( + "params", + [ + {}, + {"status": ["running"], "sort": ["status"]}, + ], + ) + def test_get_all( + self, + request_mock: mock.MagicMock, + client: Client, + action_list_response, + params, + ): + request_mock.return_value = action_list_response - @pytest.mark.parametrize("params", [{}, {"status": ["active"], "sort": ["status"]}]) - def test_get_all(self, actions_client, generic_action_list, params): - actions_client._client.request.return_value = generic_action_list with pytest.deprecated_call(): - actions = actions_client.get_all(**params) + result = client.actions.get_all(**params) params.update({"page": 1, "per_page": 50}) - actions_client._client.request.assert_called_with( - url="/actions", method="GET", params=params + request_mock.assert_called_with( + url="/actions", + method="GET", + params=params, ) - assert len(actions) == 2 - - action1 = actions[0] - action2 = actions[1] - - assert action1._client == actions_client._client.actions - assert action1.id == 1 - assert action1.command == "start_server" - - assert action2._client == actions_client._client.actions - assert action2.id == 2 - assert action2.command == "stop_server" + assert len(result) == 2 + assert_action1(result[0], client) + assert_action2(result[1], client) diff --git a/tests/unit/certificates/test_client.py b/tests/unit/certificates/test_client.py index a4e5ad2e..f0c7c3cc 100644 --- a/tests/unit/certificates/test_client.py +++ b/tests/unit/certificates/test_client.py @@ -4,54 +4,18 @@ import pytest -from hcloud.actions import BoundAction +from hcloud import Client from hcloud.certificates import ( BoundCertificate, Certificate, - CertificatesClient, ManagedCertificateStatus, ) class TestBoundCertificate: @pytest.fixture() - def bound_certificate(self, hetzner_client): - return BoundCertificate(client=hetzner_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 - ): - hetzner_client.request.return_value = response_get_actions - result = bound_certificate.get_actions_list(**params) - hetzner_client.request.assert_called_with( - url="/certificates/14/actions", method="GET", params=params - ) - - actions = result.actions - assert result.meta is not None - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - assert actions[0]._client == hetzner_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 - actions = bound_certificate.get_actions() - - params = {"page": 1, "per_page": 50} - - hetzner_client.request.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].id == 13 - assert actions[0].command == "change_protection" + def bound_certificate(self, client: Client): + return BoundCertificate(client=client.certificates, data=dict(id=14)) def test_bound_certificate_init(self, certificate_response): bound_certificate = BoundCertificate( @@ -77,32 +41,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, + action_response, + ): + request_mock.return_value = action_response 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" ) @@ -111,38 +84,48 @@ def test_retry_issuance( class TestCertificatesClient: - @pytest.fixture() - def certificates_client(self): - return CertificatesClient(client=mock.MagicMock()) - - def test_get_by_id(self, certificates_client, certificate_response): - certificates_client._client.request.return_value = certificate_response - certificate = certificates_client.get_by_id(1) - certificates_client._client.request.assert_called_with( - url="/certificates/1", method="GET" + def test_get_by_id( + self, + request_mock: mock.MagicMock, + client: Client, + certificate_response, + ): + request_mock.return_value = certificate_response + + result = client.certificates.get_by_id(1) + + request_mock.assert_called_with( + method="GET", + url="/certificates/1", ) - assert certificate._client is certificates_client - assert certificate.id == 2323 - assert certificate.name == "My Certificate" + + assert result._client is client.certificates + assert result.id == 2323 + assert result.name == "My Certificate" @pytest.mark.parametrize( "params", [ - { - "name": "My Certificate", - "label_selector": "k==v", - "page": 1, - "per_page": 10, - }, + {"name": "name", "label_selector": "k==v", "page": 1, "per_page": 10}, {"name": ""}, {}, ], ) - def test_get_list(self, certificates_client, two_certificates_response, params): - certificates_client._client.request.return_value = two_certificates_response - result = certificates_client.get_list(**params) - certificates_client._client.request.assert_called_with( - url="/certificates", method="GET", params=params + def test_get_list( + self, + request_mock: mock.MagicMock, + client: Client, + two_certificates_response, + params, + ): + request_mock.return_value = two_certificates_response + + result = client.certificates.get_list(**params) + + request_mock.assert_called_with( + method="GET", + url="/certificates", + params=params, ) certificates = result.certificates @@ -151,23 +134,31 @@ def test_get_list(self, certificates_client, two_certificates_response, params): certificates1 = certificates[0] certificates2 = certificates[1] - assert certificates1._client is certificates_client + assert certificates1._client is client.certificates assert certificates1.id == 2323 assert certificates1.name == "My Certificate" - assert certificates2._client is certificates_client + assert certificates2._client is client.certificates assert certificates2.id == 2324 assert certificates2.name == "My website cert" @pytest.mark.parametrize( "params", [{"name": "My Certificate", "label_selector": "label1"}, {}] ) - def test_get_all(self, certificates_client, two_certificates_response, params): - certificates_client._client.request.return_value = two_certificates_response - certificates = certificates_client.get_all(**params) + def test_get_all( + self, + request_mock: mock.MagicMock, + client: Client, + two_certificates_response, + params, + ): + request_mock.return_value = two_certificates_response + + certificates = client.certificates.get_all(**params) params.update({"page": 1, "per_page": 50}) - certificates_client._client.request.assert_called_with( + + request_mock.assert_called_with( url="/certificates", method="GET", params=params ) @@ -176,35 +167,47 @@ def test_get_all(self, certificates_client, two_certificates_response, params): certificates1 = certificates[0] certificates2 = certificates[1] - assert certificates1._client is certificates_client + assert certificates1._client is client.certificates assert certificates1.id == 2323 assert certificates1.name == "My Certificate" - assert certificates2._client is certificates_client + assert certificates2._client is client.certificates assert certificates2.id == 2324 assert certificates2.name == "My website cert" - def test_get_by_name(self, certificates_client, one_certificates_response): - certificates_client._client.request.return_value = one_certificates_response - certificates = certificates_client.get_by_name("My Certificate") + def test_get_by_name( + self, + request_mock: mock.MagicMock, + client: Client, + one_certificates_response, + ): + request_mock.return_value = one_certificates_response + certificates = client.certificates.get_by_name("My Certificate") params = {"name": "My Certificate"} - certificates_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/certificates", method="GET", params=params ) - assert certificates._client is certificates_client + assert certificates._client is client.certificates assert certificates.id == 2323 assert certificates.name == "My Certificate" - def test_create(self, certificates_client, certificate_response): - certificates_client._client.request.return_value = certificate_response - certificate = certificates_client.create( + def test_create( + self, + request_mock: mock.MagicMock, + client: Client, + certificate_response, + ): + request_mock.return_value = certificate_response + + certificate = client.certificates.create( name="My Certificate", certificate="-----BEGIN CERTIFICATE-----\n...", private_key="-----BEGIN PRIVATE KEY-----\n...", ) - certificates_client._client.request.assert_called_with( + + request_mock.assert_called_with( url="/certificates", method="POST", json={ @@ -219,15 +222,16 @@ def test_create(self, certificates_client, certificate_response): assert certificate.name == "My Certificate" def test_create_managed( - self, certificates_client, create_managed_certificate_response + self, + request_mock: mock.MagicMock, + client: Client, + create_managed_certificate_response, ): - certificates_client._client.request.return_value = ( - create_managed_certificate_response - ) - create_managed_certificate_rsp = certificates_client.create_managed( + request_mock.return_value = create_managed_certificate_response + create_managed_certificate_rsp = client.certificates.create_managed( name="My Certificate", domain_names=["example.com", "*.example.org"] ) - certificates_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/certificates", method="POST", json={ @@ -247,11 +251,15 @@ def test_create_managed( [Certificate(id=1), BoundCertificate(mock.MagicMock(), dict(id=1))], ) def test_update( - self, certificates_client, certificate, response_update_certificate + self, + request_mock: mock.MagicMock, + client: Client, + certificate, + response_update_certificate, ): - certificates_client._client.request.return_value = response_update_certificate - certificate = certificates_client.update(certificate, name="New name") - certificates_client._client.request.assert_called_with( + request_mock.return_value = response_update_certificate + certificate = client.certificates.update(certificate, name="New name") + request_mock.assert_called_with( url="/certificates/1", method="PUT", json={"name": "New name"} ) @@ -262,12 +270,16 @@ def test_update( "certificate", [Certificate(id=1), BoundCertificate(mock.MagicMock(), dict(id=1))], ) - def test_delete(self, certificates_client, certificate, generic_action): - certificates_client._client.request.return_value = generic_action - delete_success = certificates_client.delete(certificate) - certificates_client._client.request.assert_called_with( - url="/certificates/1", method="DELETE" - ) + def test_delete( + self, + request_mock: mock.MagicMock, + client: Client, + certificate, + action_response, + ): + request_mock.return_value = action_response + delete_success = client.certificates.delete(certificate) + request_mock.assert_called_with(url="/certificates/1", method="DELETE") assert delete_success is True @@ -276,65 +288,17 @@ def test_delete(self, certificates_client, certificate, generic_action): [Certificate(id=1), BoundCertificate(mock.MagicMock(), dict(id=1))], ) def test_retry_issuance( - self, certificates_client, certificate, response_retry_issuance_action + self, + request_mock: mock.MagicMock, + client: Client, + certificate, + response_retry_issuance_action, ): - certificates_client._client.request.return_value = ( - response_retry_issuance_action - ) - action = certificates_client.retry_issuance(certificate) - certificates_client._client.request.assert_called_with( + request_mock.return_value = response_retry_issuance_action + action = client.certificates.retry_issuance(certificate) + request_mock.assert_called_with( url="/certificates/1/actions/retry", method="POST" ) assert action.id == 14 assert action.command == "issue_certificate" - - def test_actions_get_by_id(self, certificates_client, response_get_actions): - certificates_client._client.request.return_value = { - "action": response_get_actions["actions"][0] - } - action = certificates_client.actions.get_by_id(13) - - certificates_client._client.request.assert_called_with( - url="/certificates/actions/13", method="GET" - ) - - assert isinstance(action, BoundAction) - assert action._client == certificates_client._client.actions - assert action.id == 13 - assert action.command == "change_protection" - - def test_actions_get_list(self, certificates_client, response_get_actions): - certificates_client._client.request.return_value = response_get_actions - result = certificates_client.actions.get_list() - - certificates_client._client.request.assert_called_with( - url="/certificates/actions", - method="GET", - params={}, - ) - - actions = result.actions - assert result.meta is not None - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - assert actions[0]._client == certificates_client._client.actions - assert actions[0].id == 13 - assert actions[0].command == "change_protection" - - def test_actions_get_all(self, certificates_client, response_get_actions): - certificates_client._client.request.return_value = response_get_actions - actions = certificates_client.actions.get_all() - - certificates_client._client.request.assert_called_with( - url="/certificates/actions", - method="GET", - params={"page": 1, "per_page": 50}, - ) - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - assert actions[0]._client == certificates_client._client.actions - assert actions[0].id == 13 - assert actions[0].command == "change_protection" diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py index 0dd4df46..97098d06 100644 --- a/tests/unit/conftest.py +++ b/tests/unit/conftest.py @@ -1,3 +1,5 @@ +# pylint: disable=redefined-outer-name + from __future__ import annotations from unittest import mock @@ -5,36 +7,115 @@ import pytest from hcloud import Client +from hcloud.actions import BoundAction -@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(): + return mock.MagicMock() @pytest.fixture() -def generic_action(): +def client(request_mock): + c = Client(token="TOKEN") + c.request = request_mock + return c + + +def assert_action1(o: BoundAction, client: Client): + assert o.id == 1 + assert o.command == "command" + assert o._client == client.actions + + +def assert_action2(o: BoundAction, client: Client): + assert o.id == 2 + assert o.command == "command" + assert o._client == client.actions + + +@pytest.fixture() +def action1_running(): return { - "action": { - "id": 1, - "command": "stop_server", - "status": "running", - "progress": 0, - "started": "2016-01-30T23:50+00:00", - "finished": None, - "resources": [{"id": 42, "type": "server"}], - "error": {"code": "action_failed", "message": "Action failed"}, - } + "id": 1, + "command": "command", + "status": "running", + "progress": 20, + "started": "2025-01-30T23:50+00:00", + "finished": None, + "resources": [{"id": 42, "type": "resource"}], + "error": None, } @pytest.fixture() -def hetzner_client(): - client = Client(token="token") - patcher = mock.patch.object(client, "request") - patcher.start() - yield client - patcher.stop() +def action2_running(): + return { + "id": 2, + "command": "command", + "status": "running", + "progress": 40, + "started": "2025-01-30T23:50+00:00", + "finished": None, + "resources": [{"id": 666, "type": "resource"}], + "error": None, + } + + +@pytest.fixture() +def action1_success(action1_running): + return { + **action1_running, + "status": "success", + "progress": 100, + "finished": "2025-01-30T10:40+00:00", + } + + +@pytest.fixture() +def action2_success(action2_running): + return { + **action2_running, + "status": "success", + "progress": 100, + "finished": "2025-01-30T10:40+00:00", + } + + +@pytest.fixture() +def action1_error(action1_running): + return { + **action1_running, + "status": "error", + "progress": 100, + "finished": "2025-01-30T10:40+00:00", + "error": {"code": "action_failed", "message": "Action failed"}, + } + + +@pytest.fixture() +def action2_error(action2_running): + return { + **action2_running, + "status": "error", + "progress": 100, + "finished": "2025-01-30T10:40+00:00", + "error": {"code": "action_failed", "message": "Action failed"}, + } + + +@pytest.fixture() +def action_response(action1_running): + return { + "action": action1_running, + } + + +@pytest.fixture() +def action_list_response(action1_running, action2_running): + return { + "actions": [ + action1_running, + action2_running, + ] + } diff --git a/tests/unit/datacenters/test_client.py b/tests/unit/datacenters/test_client.py index 3da55e37..875ea5e6 100644 --- a/tests/unit/datacenters/test_client.py +++ b/tests/unit/datacenters/test_client.py @@ -4,6 +4,7 @@ import pytest # noqa: F401 +from hcloud import Client from hcloud.datacenters import BoundDatacenter, DatacentersClient, DatacenterServerTypes from hcloud.locations import BoundLocation @@ -58,15 +59,15 @@ def test_bound_datacenter_init(self, datacenter_response): class TestDatacentersClient: @pytest.fixture() - def datacenters_client(self): - return DatacentersClient(client=mock.MagicMock()) + def datacenters_client(self, client: Client): + return DatacentersClient(client) - def test_get_by_id(self, datacenters_client, datacenter_response): - datacenters_client._client.request.return_value = datacenter_response + def test_get_by_id( + self, request_mock: mock.MagicMock, datacenters_client, datacenter_response + ): + request_mock.return_value = datacenter_response datacenter = datacenters_client.get_by_id(1) - datacenters_client._client.request.assert_called_with( - url="/datacenters/1", method="GET" - ) + request_mock.assert_called_with(url="/datacenters/1", method="GET") assert datacenter._client is datacenters_client assert datacenter.id == 1 assert datacenter.name == "fsn1-dc8" @@ -74,12 +75,16 @@ def test_get_by_id(self, datacenters_client, datacenter_response): @pytest.mark.parametrize( "params", [{"name": "fsn1", "page": 1, "per_page": 10}, {"name": ""}, {}] ) - def test_get_list(self, datacenters_client, two_datacenters_response, params): - datacenters_client._client.request.return_value = two_datacenters_response + def test_get_list( + self, + request_mock: mock.MagicMock, + datacenters_client, + two_datacenters_response, + params, + ): + request_mock.return_value = two_datacenters_response result = datacenters_client.get_list(**params) - datacenters_client._client.request.assert_called_with( - url="/datacenters", method="GET", params=params - ) + request_mock.assert_called_with(url="/datacenters", method="GET", params=params) datacenters = result.datacenters assert result.meta is not None @@ -100,14 +105,18 @@ def test_get_list(self, datacenters_client, two_datacenters_response, params): assert isinstance(datacenter2.location, BoundLocation) @pytest.mark.parametrize("params", [{"name": "fsn1"}, {}]) - def test_get_all(self, datacenters_client, two_datacenters_response, params): - datacenters_client._client.request.return_value = two_datacenters_response + def test_get_all( + self, + request_mock: mock.MagicMock, + datacenters_client, + two_datacenters_response, + params, + ): + request_mock.return_value = two_datacenters_response datacenters = datacenters_client.get_all(**params) params.update({"page": 1, "per_page": 50}) - datacenters_client._client.request.assert_called_with( - url="/datacenters", method="GET", params=params - ) + request_mock.assert_called_with(url="/datacenters", method="GET", params=params) assert len(datacenters) == 2 @@ -124,14 +133,14 @@ def test_get_all(self, datacenters_client, two_datacenters_response, params): assert datacenter2.name == "nbg1-dc3" assert isinstance(datacenter2.location, BoundLocation) - def test_get_by_name(self, datacenters_client, one_datacenters_response): - datacenters_client._client.request.return_value = one_datacenters_response + def test_get_by_name( + self, request_mock: mock.MagicMock, datacenters_client, one_datacenters_response + ): + request_mock.return_value = one_datacenters_response datacenter = datacenters_client.get_by_name("fsn1-dc8") params = {"name": "fsn1-dc8"} - datacenters_client._client.request.assert_called_with( - url="/datacenters", method="GET", params=params - ) + request_mock.assert_called_with(url="/datacenters", method="GET", params=params) assert datacenter._client is datacenters_client assert datacenter.id == 1 diff --git a/tests/unit/firewalls/test_client.py b/tests/unit/firewalls/test_client.py index 1226c61f..0c74089c 100644 --- a/tests/unit/firewalls/test_client.py +++ b/tests/unit/firewalls/test_client.py @@ -4,7 +4,7 @@ import pytest -from hcloud.actions import BoundAction +from hcloud import Client from hcloud.firewalls import ( BoundFirewall, Firewall, @@ -18,8 +18,8 @@ class TestBoundFirewall: @pytest.fixture() - def bound_firewall(self, hetzner_client): - return BoundFirewall(client=hetzner_client.firewalls, data=dict(id=1)) + def bound_firewall(self, client: Client): + return BoundFirewall(client=client.firewalls, data=dict(id=1)) def test_bound_firewall_init(self, firewall_response): bound_firewall = BoundFirewall( @@ -71,52 +71,18 @@ def test_bound_firewall_init(self, firewall_response): ] assert firewall_out_rule.description == "allow http out" - @pytest.mark.parametrize( - "params", [{}, {"sort": ["created"], "page": 1, "per_page": 2}] - ) - def test_get_actions_list( - self, hetzner_client, bound_firewall, response_get_actions, params + def test_update( + self, + request_mock: mock.MagicMock, + client: Client, + bound_firewall, + response_update_firewall, ): - hetzner_client.request.return_value = response_get_actions - result = bound_firewall.get_actions_list(**params) - hetzner_client.request.assert_called_with( - url="/firewalls/1/actions", method="GET", params=params - ) - - actions = result.actions - assert result.meta is not None - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - assert actions[0]._client == hetzner_client.actions - assert actions[0].id == 13 - assert actions[0].command == "set_firewall_rules" - - @pytest.mark.parametrize("params", [{}, {"sort": ["created"]}]) - def test_get_actions( - self, hetzner_client, bound_firewall, response_get_actions, params - ): - hetzner_client.request.return_value = response_get_actions - actions = bound_firewall.get_actions(**params) - - params.update({"page": 1, "per_page": 50}) - - hetzner_client.request.assert_called_with( - url="/firewalls/1/actions", method="GET", params=params - ) - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - assert actions[0]._client == hetzner_client.actions - assert actions[0].id == 13 - assert actions[0].command == "set_firewall_rules" - - def test_update(self, hetzner_client, bound_firewall, response_update_firewall): - hetzner_client.request.return_value = response_update_firewall + request_mock.return_value = response_update_firewall firewall = bound_firewall.update( name="New Corporate Intranet Protection", labels={} ) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/firewalls/1", method="PUT", json={"name": "New Corporate Intranet Protection", "labels": {}}, @@ -125,14 +91,20 @@ def test_update(self, hetzner_client, bound_firewall, response_update_firewall): assert firewall.id == 38 assert firewall.name == "New Corporate Intranet Protection" - def test_delete(self, hetzner_client, bound_firewall): + def test_delete(self, request_mock: mock.MagicMock, client: Client, bound_firewall): delete_success = bound_firewall.delete() - hetzner_client.request.assert_called_with(url="/firewalls/1", method="DELETE") + request_mock.assert_called_with(url="/firewalls/1", method="DELETE") assert delete_success is True - def test_set_rules(self, hetzner_client, bound_firewall, response_set_rules): - hetzner_client.request.return_value = response_set_rules + def test_set_rules( + self, + request_mock: mock.MagicMock, + client: Client, + bound_firewall, + response_set_rules, + ): + request_mock.return_value = response_set_rules actions = bound_firewall.set_rules( [ FirewallRule( @@ -143,7 +115,7 @@ def test_set_rules(self, hetzner_client, bound_firewall, response_set_rules): ) ] ) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/firewalls/1/actions/set_rules", method="POST", json={ @@ -162,13 +134,17 @@ def test_set_rules(self, hetzner_client, bound_firewall, response_set_rules): assert actions[0].progress == 100 def test_apply_to_resources( - self, hetzner_client, bound_firewall, response_set_rules + self, + request_mock: mock.MagicMock, + client: Client, + bound_firewall, + response_set_rules, ): - hetzner_client.request.return_value = response_set_rules + request_mock.return_value = response_set_rules actions = bound_firewall.apply_to_resources( [FirewallResource(type=FirewallResource.TYPE_SERVER, server=Server(id=5))] ) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/firewalls/1/actions/apply_to_resources", method="POST", json={"apply_to": [{"type": "server", "server": {"id": 5}}]}, @@ -178,13 +154,17 @@ def test_apply_to_resources( assert actions[0].progress == 100 def test_remove_from_resources( - self, hetzner_client, bound_firewall, response_set_rules + self, + request_mock: mock.MagicMock, + client: Client, + bound_firewall, + response_set_rules, ): - hetzner_client.request.return_value = response_set_rules + request_mock.return_value = response_set_rules actions = bound_firewall.remove_from_resources( [FirewallResource(type=FirewallResource.TYPE_SERVER, server=Server(id=5))] ) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/firewalls/1/actions/remove_from_resources", method="POST", json={"remove_from": [{"type": "server", "server": {"id": 5}}]}, @@ -196,15 +176,15 @@ def test_remove_from_resources( class TestFirewallsClient: @pytest.fixture() - def firewalls_client(self): - return FirewallsClient(client=mock.MagicMock()) + def firewalls_client(self, client: Client): + return FirewallsClient(client) - def test_get_by_id(self, firewalls_client, firewall_response): - firewalls_client._client.request.return_value = firewall_response + def test_get_by_id( + self, request_mock: mock.MagicMock, firewalls_client, firewall_response + ): + request_mock.return_value = firewall_response firewall = firewalls_client.get_by_id(1) - firewalls_client._client.request.assert_called_with( - url="/firewalls/1", method="GET" - ) + request_mock.assert_called_with(url="/firewalls/1", method="GET") assert firewall._client is firewalls_client assert firewall.id == 38 assert firewall.name == "Corporate Intranet Protection" @@ -223,12 +203,16 @@ def test_get_by_id(self, firewalls_client, firewall_response): {}, ], ) - def test_get_list(self, firewalls_client, two_firewalls_response, params): - firewalls_client._client.request.return_value = two_firewalls_response + def test_get_list( + self, + request_mock: mock.MagicMock, + firewalls_client, + two_firewalls_response, + params, + ): + request_mock.return_value = two_firewalls_response result = firewalls_client.get_list(**params) - firewalls_client._client.request.assert_called_with( - url="/firewalls", method="GET", params=params - ) + request_mock.assert_called_with(url="/firewalls", method="GET", params=params) firewalls = result.firewalls assert result.meta is not None @@ -257,15 +241,19 @@ def test_get_list(self, firewalls_client, two_firewalls_response, params): {}, ], ) - def test_get_all(self, firewalls_client, two_firewalls_response, params): - firewalls_client._client.request.return_value = two_firewalls_response + def test_get_all( + self, + request_mock: mock.MagicMock, + firewalls_client, + two_firewalls_response, + params, + ): + request_mock.return_value = two_firewalls_response firewalls = firewalls_client.get_all(**params) params.update({"page": 1, "per_page": 50}) - firewalls_client._client.request.assert_called_with( - url="/firewalls", method="GET", params=params - ) + request_mock.assert_called_with(url="/firewalls", method="GET", params=params) assert len(firewalls) == 2 @@ -280,42 +268,24 @@ def test_get_all(self, firewalls_client, two_firewalls_response, params): assert firewalls2.id == 39 assert firewalls2.name == "Corporate Extranet Protection" - def test_get_by_name(self, firewalls_client, one_firewalls_response): - firewalls_client._client.request.return_value = one_firewalls_response + def test_get_by_name( + self, request_mock: mock.MagicMock, firewalls_client, one_firewalls_response + ): + request_mock.return_value = one_firewalls_response firewall = firewalls_client.get_by_name("Corporate Intranet Protection") params = {"name": "Corporate Intranet Protection"} - firewalls_client._client.request.assert_called_with( - url="/firewalls", method="GET", params=params - ) + request_mock.assert_called_with(url="/firewalls", method="GET", params=params) assert firewall._client is firewalls_client assert firewall.id == 38 assert firewall.name == "Corporate Intranet Protection" - @pytest.mark.parametrize( - "firewall", [Firewall(id=1), BoundFirewall(mock.MagicMock(), dict(id=1))] - ) - def test_get_actions_list(self, firewalls_client, firewall, response_get_actions): - firewalls_client._client.request.return_value = response_get_actions - result = firewalls_client.get_actions_list(firewall) - firewalls_client._client.request.assert_called_with( - url="/firewalls/1/actions", method="GET", params={} - ) - - actions = result.actions - assert result.meta is not None - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - - assert actions[0]._client == firewalls_client._client.actions - assert actions[0].id == 13 - assert actions[0].command == "set_firewall_rules" - - def test_create(self, firewalls_client, response_create_firewall): - firewalls_client._client.request.return_value = response_create_firewall + def test_create( + self, request_mock: mock.MagicMock, firewalls_client, response_create_firewall + ): + request_mock.return_value = response_create_firewall response = firewalls_client.create( "Corporate Intranet Protection", rules=[ @@ -335,7 +305,7 @@ def test_create(self, firewalls_client, response_create_firewall): ), ], ) - firewalls_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/firewalls", method="POST", json={ @@ -366,12 +336,18 @@ def test_create(self, firewalls_client, response_create_firewall): @pytest.mark.parametrize( "firewall", [Firewall(id=38), BoundFirewall(mock.MagicMock(), dict(id=38))] ) - def test_update(self, firewalls_client, firewall, response_update_firewall): - firewalls_client._client.request.return_value = response_update_firewall + def test_update( + self, + request_mock: mock.MagicMock, + firewalls_client, + firewall, + response_update_firewall, + ): + request_mock.return_value = response_update_firewall firewall = firewalls_client.update( firewall, name="New Corporate Intranet Protection", labels={} ) - firewalls_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/firewalls/38", method="PUT", json={"name": "New Corporate Intranet Protection", "labels": {}}, @@ -383,8 +359,14 @@ def test_update(self, firewalls_client, firewall, response_update_firewall): @pytest.mark.parametrize( "firewall", [Firewall(id=1), BoundFirewall(mock.MagicMock(), dict(id=1))] ) - def test_set_rules(self, firewalls_client, firewall, response_set_rules): - firewalls_client._client.request.return_value = response_set_rules + def test_set_rules( + self, + request_mock: mock.MagicMock, + firewalls_client, + firewall, + response_set_rules, + ): + request_mock.return_value = response_set_rules actions = firewalls_client.set_rules( firewall, [ @@ -395,7 +377,7 @@ def test_set_rules(self, firewalls_client, firewall, response_set_rules): ) ], ) - firewalls_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/firewalls/1/actions/set_rules", method="POST", json={ @@ -415,25 +397,29 @@ def test_set_rules(self, firewalls_client, firewall, response_set_rules): @pytest.mark.parametrize( "firewall", [Firewall(id=1), BoundFirewall(mock.MagicMock(), dict(id=1))] ) - def test_delete(self, firewalls_client, firewall): + def test_delete(self, request_mock: mock.MagicMock, firewalls_client, firewall): delete_success = firewalls_client.delete(firewall) - firewalls_client._client.request.assert_called_with( - url="/firewalls/1", method="DELETE" - ) + request_mock.assert_called_with(url="/firewalls/1", method="DELETE") assert delete_success is True @pytest.mark.parametrize( "firewall", [Firewall(id=1), BoundFirewall(mock.MagicMock(), dict(id=1))] ) - def test_apply_to_resources(self, firewalls_client, firewall, response_set_rules): - firewalls_client._client.request.return_value = response_set_rules + def test_apply_to_resources( + self, + request_mock: mock.MagicMock, + firewalls_client, + firewall, + response_set_rules, + ): + request_mock.return_value = response_set_rules actions = firewalls_client.apply_to_resources( firewall, [FirewallResource(type=FirewallResource.TYPE_SERVER, server=Server(id=5))], ) - firewalls_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/firewalls/1/actions/apply_to_resources", method="POST", json={"apply_to": [{"type": "server", "server": {"id": 5}}]}, @@ -446,15 +432,19 @@ def test_apply_to_resources(self, firewalls_client, firewall, response_set_rules "firewall", [Firewall(id=1), BoundFirewall(mock.MagicMock(), dict(id=1))] ) def test_remove_from_resources( - self, firewalls_client, firewall, response_set_rules + self, + request_mock: mock.MagicMock, + firewalls_client, + firewall, + response_set_rules, ): - firewalls_client._client.request.return_value = response_set_rules + request_mock.return_value = response_set_rules actions = firewalls_client.remove_from_resources( firewall, [FirewallResource(type=FirewallResource.TYPE_SERVER, server=Server(id=5))], ) - firewalls_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/firewalls/1/actions/remove_from_resources", method="POST", json={"remove_from": [{"type": "server", "server": {"id": 5}}]}, @@ -462,53 +452,3 @@ def test_remove_from_resources( assert actions[0].id == 13 assert actions[0].progress == 100 - - def test_actions_get_by_id(self, firewalls_client, response_get_actions): - firewalls_client._client.request.return_value = { - "action": response_get_actions["actions"][0] - } - action = firewalls_client.actions.get_by_id(13) - - firewalls_client._client.request.assert_called_with( - url="/firewalls/actions/13", method="GET" - ) - - assert isinstance(action, BoundAction) - assert action._client == firewalls_client._client.actions - assert action.id == 13 - assert action.command == "set_firewall_rules" - - def test_actions_get_list(self, firewalls_client, response_get_actions): - firewalls_client._client.request.return_value = response_get_actions - result = firewalls_client.actions.get_list() - - firewalls_client._client.request.assert_called_with( - url="/firewalls/actions", - method="GET", - params={}, - ) - - actions = result.actions - assert result.meta is not None - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - assert actions[0]._client == firewalls_client._client.actions - assert actions[0].id == 13 - assert actions[0].command == "set_firewall_rules" - - def test_actions_get_all(self, firewalls_client, response_get_actions): - firewalls_client._client.request.return_value = response_get_actions - actions = firewalls_client.actions.get_all() - - firewalls_client._client.request.assert_called_with( - url="/firewalls/actions", - method="GET", - params={"page": 1, "per_page": 50}, - ) - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - assert actions[0]._client == firewalls_client._client.actions - assert actions[0].id == 13 - assert actions[0].command == "set_firewall_rules" diff --git a/tests/unit/floating_ips/test_client.py b/tests/unit/floating_ips/test_client.py index 1f1160c6..38f009a0 100644 --- a/tests/unit/floating_ips/test_client.py +++ b/tests/unit/floating_ips/test_client.py @@ -4,7 +4,7 @@ import pytest -from hcloud.actions import BoundAction +from hcloud import Client from hcloud.floating_ips import BoundFloatingIP, FloatingIP, FloatingIPsClient from hcloud.locations import BoundLocation, Location from hcloud.servers import BoundServer, Server @@ -12,8 +12,8 @@ class TestBoundFloatingIP: @pytest.fixture() - def bound_floating_ip(self, hetzner_client): - return BoundFloatingIP(client=hetzner_client.floating_ips, data=dict(id=14)) + def bound_floating_ip(self, request_mock: mock.MagicMock, client: Client): + return BoundFloatingIP(client=client.floating_ips, data=dict(id=14)) def test_bound_floating_ip_init(self, floating_ip_response): bound_floating_ip = BoundFloatingIP( @@ -41,29 +41,18 @@ def test_bound_floating_ip_init(self, floating_ip_response): assert bound_floating_ip.home_location.latitude == 50.47612 assert bound_floating_ip.home_location.longitude == 12.370071 - def test_get_actions(self, hetzner_client, bound_floating_ip, response_get_actions): - hetzner_client.request.return_value = response_get_actions - actions = bound_floating_ip.get_actions(sort="id") - hetzner_client.request.assert_called_with( - url="/floating_ips/14/actions", - method="GET", - params={"sort": "id", "page": 1, "per_page": 50}, - ) - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - assert actions[0]._client == hetzner_client.actions - assert actions[0].id == 13 - assert actions[0].command == "assign_floating_ip" - def test_update( - self, hetzner_client, bound_floating_ip, response_update_floating_ip + self, + request_mock: mock.MagicMock, + client: Client, + bound_floating_ip, + response_update_floating_ip, ): - hetzner_client.request.return_value = response_update_floating_ip + request_mock.return_value = response_update_floating_ip floating_ip = bound_floating_ip.update( description="New description", name="New name" ) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/floating_ips/14", method="PUT", json={"description": "New description", "name": "New name"}, @@ -73,79 +62,112 @@ def test_update( assert floating_ip.description == "New description" assert floating_ip.name == "New name" - def test_delete(self, hetzner_client, bound_floating_ip, generic_action): - hetzner_client.request.return_value = generic_action + def test_delete( + self, + request_mock: mock.MagicMock, + bound_floating_ip, + action_response, + ): + request_mock.return_value = action_response delete_success = bound_floating_ip.delete() - hetzner_client.request.assert_called_with( - url="/floating_ips/14", method="DELETE" - ) + request_mock.assert_called_with(url="/floating_ips/14", method="DELETE") assert delete_success is True - def test_change_protection(self, hetzner_client, bound_floating_ip, generic_action): - hetzner_client.request.return_value = generic_action + def test_change_protection( + self, + request_mock: mock.MagicMock, + client: Client, + bound_floating_ip, + action_response, + ): + request_mock.return_value = action_response action = bound_floating_ip.change_protection(True) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/floating_ips/14/actions/change_protection", method="POST", json={"delete": True}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "server", (Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))) ) - def test_assign(self, hetzner_client, bound_floating_ip, server, generic_action): - hetzner_client.request.return_value = generic_action + def test_assign( + self, + request_mock: mock.MagicMock, + client: Client, + bound_floating_ip, + server, + action_response, + ): + request_mock.return_value = action_response action = bound_floating_ip.assign(server) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/floating_ips/14/actions/assign", method="POST", json={"server": 1} ) assert action.id == 1 - assert action.progress == 0 - - def test_unassign(self, hetzner_client, bound_floating_ip, generic_action): - hetzner_client.request.return_value = generic_action + assert action.progress == 20 + + def test_unassign( + self, + request_mock: mock.MagicMock, + client: Client, + bound_floating_ip, + action_response, + ): + request_mock.return_value = action_response action = bound_floating_ip.unassign() - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/floating_ips/14/actions/unassign", method="POST" ) assert action.id == 1 - assert action.progress == 0 - - def test_change_dns_ptr(self, hetzner_client, bound_floating_ip, generic_action): - hetzner_client.request.return_value = generic_action + assert action.progress == 20 + + def test_change_dns_ptr( + self, + request_mock: mock.MagicMock, + client: Client, + bound_floating_ip, + action_response, + ): + request_mock.return_value = action_response action = bound_floating_ip.change_dns_ptr("1.2.3.4", "server02.example.com") - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/floating_ips/14/actions/change_dns_ptr", method="POST", json={"ip": "1.2.3.4", "dns_ptr": "server02.example.com"}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 class TestFloatingIPsClient: @pytest.fixture() - def floating_ips_client(self): - return FloatingIPsClient(client=mock.MagicMock()) + def floating_ips_client(self, client: Client): + return FloatingIPsClient(client) - def test_get_by_id(self, floating_ips_client, floating_ip_response): - floating_ips_client._client.request.return_value = floating_ip_response + def test_get_by_id( + self, request_mock: mock.MagicMock, floating_ips_client, floating_ip_response + ): + request_mock.return_value = floating_ip_response bound_floating_ip = floating_ips_client.get_by_id(1) - floating_ips_client._client.request.assert_called_with( - url="/floating_ips/1", method="GET" - ) + request_mock.assert_called_with(url="/floating_ips/1", method="GET") assert bound_floating_ip._client is floating_ips_client assert bound_floating_ip.id == 4711 assert bound_floating_ip.description == "Web Frontend" - def test_get_by_name(self, floating_ips_client, one_floating_ips_response): - floating_ips_client._client.request.return_value = one_floating_ips_response + def test_get_by_name( + self, + request_mock: mock.MagicMock, + floating_ips_client, + one_floating_ips_response, + ): + request_mock.return_value = one_floating_ips_response bound_floating_ip = floating_ips_client.get_by_name("Web Frontend") - floating_ips_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/floating_ips", method="GET", params={"name": "Web Frontend"} ) assert bound_floating_ip._client is floating_ips_client @@ -157,10 +179,16 @@ def test_get_by_name(self, floating_ips_client, one_floating_ips_response): "params", [{"label_selector": "label1", "page": 1, "per_page": 10}, {"name": ""}, {}], ) - def test_get_list(self, floating_ips_client, two_floating_ips_response, params): - floating_ips_client._client.request.return_value = two_floating_ips_response + def test_get_list( + self, + request_mock: mock.MagicMock, + floating_ips_client, + two_floating_ips_response, + params, + ): + request_mock.return_value = two_floating_ips_response result = floating_ips_client.get_list(**params) - floating_ips_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/floating_ips", method="GET", params=params ) @@ -181,13 +209,19 @@ def test_get_list(self, floating_ips_client, two_floating_ips_response, params): assert bound_floating_ip2.description == "Web Backend" @pytest.mark.parametrize("params", [{"label_selector": "label1"}, {}]) - def test_get_all(self, floating_ips_client, two_floating_ips_response, params): - floating_ips_client._client.request.return_value = two_floating_ips_response + def test_get_all( + self, + request_mock: mock.MagicMock, + floating_ips_client, + two_floating_ips_response, + params, + ): + request_mock.return_value = two_floating_ips_response bound_floating_ips = floating_ips_client.get_all(**params) params.update({"page": 1, "per_page": 50}) - floating_ips_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/floating_ips", method="GET", params=params ) @@ -204,12 +238,14 @@ def test_get_all(self, floating_ips_client, two_floating_ips_response, params): assert bound_floating_ip2.id == 4712 assert bound_floating_ip2.description == "Web Backend" - def test_create_with_location(self, floating_ips_client, floating_ip_response): - floating_ips_client._client.request.return_value = floating_ip_response + def test_create_with_location( + self, request_mock: mock.MagicMock, floating_ips_client, floating_ip_response + ): + request_mock.return_value = floating_ip_response response = floating_ips_client.create( "ipv6", "Web Frontend", home_location=Location(name="location") ) - floating_ips_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/floating_ips", method="POST", json={ @@ -231,13 +267,17 @@ def test_create_with_location(self, floating_ips_client, floating_ip_response): "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))] ) def test_create_with_server( - self, floating_ips_client, server, floating_ip_create_response + self, + request_mock: mock.MagicMock, + floating_ips_client, + server, + floating_ip_create_response, ): - floating_ips_client._client.request.return_value = floating_ip_create_response + request_mock.return_value = floating_ip_create_response response = floating_ips_client.create( type="ipv6", description="Web Frontend", server=server ) - floating_ips_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/floating_ips", method="POST", json={"description": "Web Frontend", "type": "ipv6", "server": 1}, @@ -254,13 +294,17 @@ def test_create_with_server( "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))] ) def test_create_with_name( - self, floating_ips_client, server, floating_ip_create_response + self, + request_mock: mock.MagicMock, + floating_ips_client, + server, + floating_ip_create_response, ): - floating_ips_client._client.request.return_value = floating_ip_create_response + request_mock.return_value = floating_ip_create_response response = floating_ips_client.create( type="ipv6", description="Web Frontend", name="Web Frontend" ) - floating_ips_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/floating_ips", method="POST", json={ @@ -278,36 +322,21 @@ def test_create_with_name( assert bound_floating_ip.name == "Web Frontend" assert action.id == 13 - @pytest.mark.parametrize( - "floating_ip", [FloatingIP(id=1), BoundFloatingIP(mock.MagicMock(), dict(id=1))] - ) - def test_get_actions(self, floating_ips_client, floating_ip, response_get_actions): - floating_ips_client._client.request.return_value = response_get_actions - actions = floating_ips_client.get_actions(floating_ip) - floating_ips_client._client.request.assert_called_with( - url="/floating_ips/1/actions", - method="GET", - params={"page": 1, "per_page": 50}, - ) - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - - assert actions[0]._client == floating_ips_client._client.actions - assert actions[0].id == 13 - assert actions[0].command == "assign_floating_ip" - @pytest.mark.parametrize( "floating_ip", [FloatingIP(id=1), BoundFloatingIP(mock.MagicMock(), dict(id=1))] ) def test_update( - self, floating_ips_client, floating_ip, response_update_floating_ip + self, + request_mock: mock.MagicMock, + floating_ips_client, + floating_ip, + response_update_floating_ip, ): - floating_ips_client._client.request.return_value = response_update_floating_ip + request_mock.return_value = response_update_floating_ip floating_ip = floating_ips_client.update( floating_ip, description="New description", name="New name" ) - floating_ips_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/floating_ips/1", method="PUT", json={"description": "New description", "name": "New name"}, @@ -320,27 +349,37 @@ def test_update( @pytest.mark.parametrize( "floating_ip", [FloatingIP(id=1), BoundFloatingIP(mock.MagicMock(), dict(id=1))] ) - def test_change_protection(self, floating_ips_client, floating_ip, generic_action): - floating_ips_client._client.request.return_value = generic_action + def test_change_protection( + self, + request_mock: mock.MagicMock, + floating_ips_client, + floating_ip, + action_response, + ): + request_mock.return_value = action_response action = floating_ips_client.change_protection(floating_ip, True) - floating_ips_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/floating_ips/1/actions/change_protection", method="POST", json={"delete": True}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "floating_ip", [FloatingIP(id=1), BoundFloatingIP(mock.MagicMock(), dict(id=1))] ) - def test_delete(self, floating_ips_client, floating_ip, generic_action): - floating_ips_client._client.request.return_value = generic_action + def test_delete( + self, + request_mock: mock.MagicMock, + floating_ips_client, + floating_ip, + action_response, + ): + request_mock.return_value = action_response delete_success = floating_ips_client.delete(floating_ip) - floating_ips_client._client.request.assert_called_with( - url="/floating_ips/1", method="DELETE" - ) + request_mock.assert_called_with(url="/floating_ips/1", method="DELETE") assert delete_success is True @@ -354,91 +393,60 @@ def test_delete(self, floating_ips_client, floating_ip, generic_action): ), ], ) - def test_assign(self, floating_ips_client, server, floating_ip, generic_action): - floating_ips_client._client.request.return_value = generic_action + def test_assign( + self, + request_mock: mock.MagicMock, + floating_ips_client, + server, + floating_ip, + action_response, + ): + request_mock.return_value = action_response action = floating_ips_client.assign(floating_ip, server) - floating_ips_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/floating_ips/12/actions/assign", method="POST", json={"server": 1} ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "floating_ip", [FloatingIP(id=12), BoundFloatingIP(mock.MagicMock(), dict(id=12))], ) - def test_unassign(self, floating_ips_client, floating_ip, generic_action): - floating_ips_client._client.request.return_value = generic_action + def test_unassign( + self, + request_mock: mock.MagicMock, + floating_ips_client, + floating_ip, + action_response, + ): + request_mock.return_value = action_response action = floating_ips_client.unassign(floating_ip) - floating_ips_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/floating_ips/12/actions/unassign", method="POST" ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "floating_ip", [FloatingIP(id=12), BoundFloatingIP(mock.MagicMock(), dict(id=12))], ) - def test_change_dns_ptr(self, floating_ips_client, floating_ip, generic_action): - floating_ips_client._client.request.return_value = generic_action + def test_change_dns_ptr( + self, + request_mock: mock.MagicMock, + floating_ips_client, + floating_ip, + action_response, + ): + request_mock.return_value = action_response action = floating_ips_client.change_dns_ptr( floating_ip, "1.2.3.4", "server02.example.com" ) - floating_ips_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/floating_ips/12/actions/change_dns_ptr", method="POST", json={"ip": "1.2.3.4", "dns_ptr": "server02.example.com"}, ) assert action.id == 1 - assert action.progress == 0 - - def test_actions_get_by_id(self, floating_ips_client, response_get_actions): - floating_ips_client._client.request.return_value = { - "action": response_get_actions["actions"][0] - } - action = floating_ips_client.actions.get_by_id(13) - - floating_ips_client._client.request.assert_called_with( - url="/floating_ips/actions/13", method="GET" - ) - - assert isinstance(action, BoundAction) - assert action._client == floating_ips_client._client.actions - assert action.id == 13 - assert action.command == "assign_floating_ip" - - def test_actions_get_list(self, floating_ips_client, response_get_actions): - floating_ips_client._client.request.return_value = response_get_actions - result = floating_ips_client.actions.get_list() - - floating_ips_client._client.request.assert_called_with( - url="/floating_ips/actions", - method="GET", - params={}, - ) - - actions = result.actions - assert result.meta is not None - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - assert actions[0]._client == floating_ips_client._client.actions - assert actions[0].id == 13 - assert actions[0].command == "assign_floating_ip" - - def test_actions_get_all(self, floating_ips_client, response_get_actions): - floating_ips_client._client.request.return_value = response_get_actions - actions = floating_ips_client.actions.get_all() - - floating_ips_client._client.request.assert_called_with( - url="/floating_ips/actions", - method="GET", - params={"page": 1, "per_page": 50}, - ) - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - assert actions[0]._client == floating_ips_client._client.actions - assert actions[0].id == 13 - assert actions[0].command == "assign_floating_ip" + assert action.progress == 20 diff --git a/tests/unit/images/test_client.py b/tests/unit/images/test_client.py index cf6ff2f9..cd259f49 100644 --- a/tests/unit/images/test_client.py +++ b/tests/unit/images/test_client.py @@ -6,15 +6,15 @@ import pytest -from hcloud.actions import BoundAction +from hcloud import Client from hcloud.images import BoundImage, Image, ImagesClient from hcloud.servers import BoundServer class TestBoundImage: @pytest.fixture() - def bound_image(self, hetzner_client): - return BoundImage(client=hetzner_client.images, data=dict(id=14)) + def bound_image(self, client: Client): + return BoundImage(client=client.images, data=dict(id=14)) def test_bound_image_init(self, image_response): bound_image = BoundImage(client=mock.MagicMock(), data=image_response["image"]) @@ -46,52 +46,18 @@ def test_bound_image_init(self, image_response): assert bound_image.bound_to.id == 1 assert bound_image.bound_to.complete is False - @pytest.mark.parametrize( - "params", [{}, {"sort": ["status"], "page": 1, "per_page": 2}] - ) - def test_get_actions_list( - self, hetzner_client, bound_image, response_get_actions, params + def test_update( + self, + request_mock: mock.MagicMock, + client: Client, + bound_image, + response_update_image, ): - hetzner_client.request.return_value = response_get_actions - result = bound_image.get_actions_list(**params) - hetzner_client.request.assert_called_with( - url="/images/14/actions", method="GET", params=params - ) - - actions = result.actions - assert result.meta is not None - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - assert actions[0]._client == hetzner_client.actions - assert actions[0].id == 13 - assert actions[0].command == "change_protection" - - @pytest.mark.parametrize("params", [{}, {"sort": ["status"]}]) - def test_get_actions( - self, hetzner_client, bound_image, response_get_actions, params - ): - hetzner_client.request.return_value = response_get_actions - actions = bound_image.get_actions(**params) - - params.update({"page": 1, "per_page": 50}) - - hetzner_client.request.assert_called_with( - url="/images/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].id == 13 - assert actions[0].command == "change_protection" - - def test_update(self, hetzner_client, bound_image, response_update_image): - hetzner_client.request.return_value = response_update_image + request_mock.return_value = response_update_image image = bound_image.update( description="My new Image description", type="snapshot", labels={} ) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/images/14", method="PUT", json={ @@ -104,35 +70,49 @@ def test_update(self, hetzner_client, bound_image, response_update_image): assert image.id == 4711 assert image.description == "My new Image description" - def test_delete(self, hetzner_client, bound_image, generic_action): - hetzner_client.request.return_value = generic_action + def test_delete( + self, + request_mock: mock.MagicMock, + client: Client, + bound_image, + action_response, + ): + request_mock.return_value = action_response delete_success = bound_image.delete() - hetzner_client.request.assert_called_with(url="/images/14", method="DELETE") + request_mock.assert_called_with(url="/images/14", method="DELETE") assert delete_success is True - def test_change_protection(self, hetzner_client, bound_image, generic_action): - hetzner_client.request.return_value = generic_action + def test_change_protection( + self, + request_mock: mock.MagicMock, + client: Client, + bound_image, + action_response, + ): + request_mock.return_value = action_response action = bound_image.change_protection(True) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/images/14/actions/change_protection", method="POST", json={"delete": True}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 class TestImagesClient: @pytest.fixture() - def images_client(self): - return ImagesClient(client=mock.MagicMock()) + def images_client(self, client: Client): + return ImagesClient(client) - def test_get_by_id(self, images_client, image_response): - images_client._client.request.return_value = image_response + def test_get_by_id( + self, request_mock: mock.MagicMock, images_client, image_response + ): + request_mock.return_value = image_response image = images_client.get_by_id(1) - images_client._client.request.assert_called_with(url="/images/1", method="GET") + request_mock.assert_called_with(url="/images/1", method="GET") assert image._client is images_client assert image.id == 4711 assert image.name == "ubuntu-20.04" @@ -154,12 +134,12 @@ def test_get_by_id(self, images_client, image_response): {}, ], ) - def test_get_list(self, images_client, two_images_response, params): - images_client._client.request.return_value = two_images_response + def test_get_list( + self, request_mock: mock.MagicMock, images_client, two_images_response, params + ): + request_mock.return_value = two_images_response result = images_client.get_list(**params) - images_client._client.request.assert_called_with( - url="/images", method="GET", params=params - ) + request_mock.assert_called_with(url="/images", method="GET", params=params) images = result.images assert result.meta is not None @@ -191,15 +171,15 @@ def test_get_list(self, images_client, two_images_response, params): {}, ], ) - def test_get_all(self, images_client, two_images_response, params): - images_client._client.request.return_value = two_images_response + def test_get_all( + self, request_mock: mock.MagicMock, images_client, two_images_response, params + ): + request_mock.return_value = two_images_response images = images_client.get_all(**params) params.update({"page": 1, "per_page": 50}) - images_client._client.request.assert_called_with( - url="/images", method="GET", params=params - ) + request_mock.assert_called_with(url="/images", method="GET", params=params) assert len(images) == 2 @@ -214,30 +194,30 @@ def test_get_all(self, images_client, two_images_response, params): assert images2.id == 4712 assert images2.name == "ubuntu-18.10" - def test_get_by_name(self, images_client, one_images_response): - images_client._client.request.return_value = one_images_response + def test_get_by_name( + self, request_mock: mock.MagicMock, images_client, one_images_response + ): + request_mock.return_value = one_images_response with pytest.deprecated_call(): image = images_client.get_by_name("ubuntu-20.04") params = {"name": "ubuntu-20.04"} - images_client._client.request.assert_called_with( - url="/images", method="GET", params=params - ) + request_mock.assert_called_with(url="/images", method="GET", params=params) assert image._client is images_client assert image.id == 4711 assert image.name == "ubuntu-20.04" - def test_get_by_name_and_architecture(self, images_client, one_images_response): - images_client._client.request.return_value = one_images_response + def test_get_by_name_and_architecture( + self, request_mock: mock.MagicMock, images_client, one_images_response + ): + request_mock.return_value = one_images_response image = images_client.get_by_name_and_architecture("ubuntu-20.04", "x86") params = {"name": "ubuntu-20.04", "architecture": ["x86"]} - images_client._client.request.assert_called_with( - url="/images", method="GET", params=params - ) + request_mock.assert_called_with(url="/images", method="GET", params=params) assert image._client is images_client assert image.id == 4711 @@ -247,32 +227,14 @@ def test_get_by_name_and_architecture(self, images_client, one_images_response): @pytest.mark.parametrize( "image", [Image(id=1), BoundImage(mock.MagicMock(), dict(id=1))] ) - def test_get_actions_list(self, images_client, image, response_get_actions): - images_client._client.request.return_value = response_get_actions - result = images_client.get_actions_list(image) - images_client._client.request.assert_called_with( - url="/images/1/actions", method="GET", params={} - ) - - actions = result.actions - assert result.meta is not None - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - - assert actions[0]._client == images_client._client.actions - assert actions[0].id == 13 - assert actions[0].command == "change_protection" - - @pytest.mark.parametrize( - "image", [Image(id=1), BoundImage(mock.MagicMock(), dict(id=1))] - ) - def test_update(self, images_client, image, response_update_image): - images_client._client.request.return_value = response_update_image + def test_update( + self, request_mock: mock.MagicMock, images_client, image, response_update_image + ): + request_mock.return_value = response_update_image image = images_client.update( image, description="My new Image description", type="snapshot", labels={} ) - images_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/images/1", method="PUT", json={ @@ -288,76 +250,28 @@ def test_update(self, images_client, image, response_update_image): @pytest.mark.parametrize( "image", [Image(id=1), BoundImage(mock.MagicMock(), dict(id=1))] ) - def test_change_protection(self, images_client, image, generic_action): - images_client._client.request.return_value = generic_action + def test_change_protection( + self, request_mock: mock.MagicMock, images_client, image, action_response + ): + request_mock.return_value = action_response action = images_client.change_protection(image, True) - images_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/images/1/actions/change_protection", method="POST", json={"delete": True}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "image", [Image(id=1), BoundImage(mock.MagicMock(), dict(id=1))] ) - def test_delete(self, images_client, image, generic_action): - images_client._client.request.return_value = generic_action + def test_delete( + self, request_mock: mock.MagicMock, images_client, image, action_response + ): + request_mock.return_value = action_response delete_success = images_client.delete(image) - images_client._client.request.assert_called_with( - url="/images/1", method="DELETE" - ) + request_mock.assert_called_with(url="/images/1", method="DELETE") assert delete_success is True - - def test_actions_get_by_id(self, images_client, response_get_actions): - images_client._client.request.return_value = { - "action": response_get_actions["actions"][0] - } - action = images_client.actions.get_by_id(13) - - images_client._client.request.assert_called_with( - url="/images/actions/13", method="GET" - ) - - assert isinstance(action, BoundAction) - assert action._client == images_client._client.actions - assert action.id == 13 - assert action.command == "change_protection" - - def test_actions_get_list(self, images_client, response_get_actions): - images_client._client.request.return_value = response_get_actions - result = images_client.actions.get_list() - - images_client._client.request.assert_called_with( - url="/images/actions", - method="GET", - params={}, - ) - - actions = result.actions - assert result.meta is not None - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - assert actions[0]._client == images_client._client.actions - assert actions[0].id == 13 - assert actions[0].command == "change_protection" - - def test_actions_get_all(self, images_client, response_get_actions): - images_client._client.request.return_value = response_get_actions - actions = images_client.actions.get_all() - - images_client._client.request.assert_called_with( - url="/images/actions", - method="GET", - params={"page": 1, "per_page": 50}, - ) - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - assert actions[0]._client == images_client._client.actions - assert actions[0].id == 13 - assert actions[0].command == "change_protection" diff --git a/tests/unit/isos/test_client.py b/tests/unit/isos/test_client.py index 7e71f8dc..4f29f219 100644 --- a/tests/unit/isos/test_client.py +++ b/tests/unit/isos/test_client.py @@ -6,13 +6,14 @@ import pytest +from hcloud import Client from hcloud.isos import BoundIso, IsosClient class TestBoundIso: @pytest.fixture() - def bound_iso(self, hetzner_client): - return BoundIso(client=hetzner_client.isos, data=dict(id=14)) + def bound_iso(self, request_mock: mock.MagicMock, client: Client): + return BoundIso(client=client.isos, data=dict(id=14)) def test_bound_iso_init(self, iso_response): bound_iso = BoundIso(client=mock.MagicMock(), data=iso_response["iso"]) @@ -36,13 +37,13 @@ def test_bound_iso_init(self, iso_response): class TestIsosClient: @pytest.fixture() - def isos_client(self): - return IsosClient(client=mock.MagicMock()) + def isos_client(self, client: Client): + return IsosClient(client) - def test_get_by_id(self, isos_client, iso_response): - isos_client._client.request.return_value = iso_response + def test_get_by_id(self, request_mock: mock.MagicMock, isos_client, iso_response): + request_mock.return_value = iso_response iso = isos_client.get_by_id(1) - isos_client._client.request.assert_called_with(url="/isos/1", method="GET") + request_mock.assert_called_with(url="/isos/1", method="GET") assert iso._client is isos_client assert iso.id == 4711 assert iso.name == "FreeBSD-11.0-RELEASE-amd64-dvd1" @@ -55,12 +56,12 @@ def test_get_by_id(self, isos_client, iso_response): {"name": "FreeBSD-11.0-RELEASE-amd64-dvd1", "page": 1, "per_page": 2}, ], ) - def test_get_list(self, isos_client, two_isos_response, params): - isos_client._client.request.return_value = two_isos_response + def test_get_list( + self, request_mock: mock.MagicMock, isos_client, two_isos_response, params + ): + request_mock.return_value = two_isos_response result = isos_client.get_list(**params) - isos_client._client.request.assert_called_with( - url="/isos", method="GET", params=params - ) + request_mock.assert_called_with(url="/isos", method="GET", params=params) isos = result.isos assert result.meta is not None @@ -81,15 +82,15 @@ def test_get_list(self, isos_client, two_isos_response, params): @pytest.mark.parametrize( "params", [{}, {"name": "FreeBSD-11.0-RELEASE-amd64-dvd1"}] ) - def test_get_all(self, isos_client, two_isos_response, params): - isos_client._client.request.return_value = two_isos_response + def test_get_all( + self, request_mock: mock.MagicMock, isos_client, two_isos_response, params + ): + request_mock.return_value = two_isos_response isos = isos_client.get_all(**params) params.update({"page": 1, "per_page": 50}) - isos_client._client.request.assert_called_with( - url="/isos", method="GET", params=params - ) + request_mock.assert_called_with(url="/isos", method="GET", params=params) assert len(isos) == 2 @@ -104,15 +105,15 @@ def test_get_all(self, isos_client, two_isos_response, params): assert isos2.id == 4712 assert isos2.name == "FreeBSD-11.0-RELEASE-amd64-dvd1" - def test_get_by_name(self, isos_client, one_isos_response): - isos_client._client.request.return_value = one_isos_response + def test_get_by_name( + self, request_mock: mock.MagicMock, isos_client, one_isos_response + ): + request_mock.return_value = one_isos_response iso = isos_client.get_by_name("FreeBSD-11.0-RELEASE-amd64-dvd1") params = {"name": "FreeBSD-11.0-RELEASE-amd64-dvd1"} - isos_client._client.request.assert_called_with( - url="/isos", method="GET", params=params - ) + request_mock.assert_called_with(url="/isos", method="GET", params=params) assert iso._client is isos_client assert iso.id == 4711 diff --git a/tests/unit/load_balancer_types/test_client.py b/tests/unit/load_balancer_types/test_client.py index f0a4c12e..4fadd11e 100644 --- a/tests/unit/load_balancer_types/test_client.py +++ b/tests/unit/load_balancer_types/test_client.py @@ -4,22 +4,24 @@ import pytest +from hcloud import Client from hcloud.load_balancer_types import LoadBalancerTypesClient class TestLoadBalancerTypesClient: @pytest.fixture() - def load_balancer_types_client(self): - return LoadBalancerTypesClient(client=mock.MagicMock()) - - def test_get_by_id(self, load_balancer_types_client, load_balancer_type_response): - load_balancer_types_client._client.request.return_value = ( - load_balancer_type_response - ) + def load_balancer_types_client(self, client: Client): + return LoadBalancerTypesClient(client) + + def test_get_by_id( + self, + request_mock: mock.MagicMock, + load_balancer_types_client, + load_balancer_type_response, + ): + request_mock.return_value = load_balancer_type_response load_balancer_type = load_balancer_types_client.get_by_id(1) - load_balancer_types_client._client.request.assert_called_with( - url="/load_balancer_types/1", method="GET" - ) + request_mock.assert_called_with(url="/load_balancer_types/1", method="GET") assert load_balancer_type._client is load_balancer_types_client assert load_balancer_type.id == 1 assert load_balancer_type.name == "LB11" @@ -28,13 +30,15 @@ def test_get_by_id(self, load_balancer_types_client, load_balancer_type_response "params", [{"name": "LB11", "page": 1, "per_page": 10}, {"name": ""}, {}] ) def test_get_list( - self, load_balancer_types_client, two_load_balancer_types_response, params + self, + request_mock: mock.MagicMock, + load_balancer_types_client, + two_load_balancer_types_response, + params, ): - load_balancer_types_client._client.request.return_value = ( - two_load_balancer_types_response - ) + request_mock.return_value = two_load_balancer_types_response result = load_balancer_types_client.get_list(**params) - load_balancer_types_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/load_balancer_types", method="GET", params=params ) @@ -56,16 +60,18 @@ def test_get_list( @pytest.mark.parametrize("params", [{"name": "LB21"}]) def test_get_all( - self, load_balancer_types_client, two_load_balancer_types_response, params + self, + request_mock: mock.MagicMock, + load_balancer_types_client, + two_load_balancer_types_response, + params, ): - load_balancer_types_client._client.request.return_value = ( - two_load_balancer_types_response - ) + request_mock.return_value = two_load_balancer_types_response load_balancer_types = load_balancer_types_client.get_all(**params) params.update({"page": 1, "per_page": 50}) - load_balancer_types_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/load_balancer_types", method="GET", params=params ) @@ -83,16 +89,17 @@ def test_get_all( assert load_balancer_types2.name == "LB21" def test_get_by_name( - self, load_balancer_types_client, one_load_balancer_types_response + self, + request_mock: mock.MagicMock, + load_balancer_types_client, + one_load_balancer_types_response, ): - load_balancer_types_client._client.request.return_value = ( - one_load_balancer_types_response - ) + request_mock.return_value = one_load_balancer_types_response load_balancer_type = load_balancer_types_client.get_by_name("LB21") params = {"name": "LB21"} - load_balancer_types_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/load_balancer_types", method="GET", params=params ) diff --git a/tests/unit/load_balancers/test_client.py b/tests/unit/load_balancers/test_client.py index 02ce1e50..0a53da96 100644 --- a/tests/unit/load_balancers/test_client.py +++ b/tests/unit/load_balancers/test_client.py @@ -4,7 +4,7 @@ import pytest -from hcloud.actions import BoundAction +from hcloud import Client from hcloud.load_balancer_types import LoadBalancerType from hcloud.load_balancers import ( BoundLoadBalancer, @@ -24,8 +24,8 @@ class TestBoundLoadBalancer: @pytest.fixture() - def bound_load_balancer(self, hetzner_client): - return BoundLoadBalancer(client=hetzner_client.load_balancers, data=dict(id=14)) + def bound_load_balancer(self, request_mock: mock.MagicMock, client: Client): + return BoundLoadBalancer(client=client.load_balancers, data=dict(id=14)) def test_bound_load_balancer_init(self, response_load_balancer): bound_load_balancer = BoundLoadBalancer( @@ -35,50 +35,16 @@ def test_bound_load_balancer_init(self, response_load_balancer): assert bound_load_balancer.id == 4711 assert bound_load_balancer.name == "Web Frontend" - @pytest.mark.parametrize("params", [{"page": 1, "per_page": 10}, {}]) - def test_get_actions_list( - self, hetzner_client, bound_load_balancer, response_get_actions, params - ): - hetzner_client.request.return_value = response_get_actions - result = bound_load_balancer.get_actions_list(**params) - hetzner_client.request.assert_called_with( - url="/load_balancers/14/actions", method="GET", params=params - ) - - actions = result.actions - assert result.meta is not None - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - assert actions[0]._client == hetzner_client.actions - assert actions[0].id == 13 - assert actions[0].command == "change_protection" - - @pytest.mark.parametrize("params", [{}]) - def test_get_actions( - self, hetzner_client, bound_load_balancer, response_get_actions, params - ): - hetzner_client.request.return_value = response_get_actions - actions = bound_load_balancer.get_actions(**params) - - params.update({"page": 1, "per_page": 50}) - - hetzner_client.request.assert_called_with( - url="/load_balancers/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].id == 13 - assert actions[0].command == "change_protection" - def test_update( - self, hetzner_client, bound_load_balancer, response_update_load_balancer + self, + request_mock: mock.MagicMock, + client: Client, + bound_load_balancer, + response_update_load_balancer, ): - hetzner_client.request.return_value = response_update_load_balancer + request_mock.return_value = response_update_load_balancer load_balancer = bound_load_balancer.update(name="new-name", labels={}) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/load_balancers/14", method="PUT", json={"name": "new-name", "labels": {}}, @@ -87,28 +53,32 @@ def test_update( assert load_balancer.id == 4711 assert load_balancer.name == "new-name" - def test_delete(self, hetzner_client, generic_action, bound_load_balancer): - hetzner_client.request.return_value = generic_action + def test_delete( + self, + request_mock: mock.MagicMock, + client: Client, + action_response, + bound_load_balancer, + ): + request_mock.return_value = action_response delete_success = bound_load_balancer.delete() - hetzner_client.request.assert_called_with( - url="/load_balancers/14", method="DELETE" - ) + request_mock.assert_called_with(url="/load_balancers/14", method="DELETE") assert delete_success is True def test_get_metrics( self, - hetzner_client, + request_mock: mock.MagicMock, response_get_metrics, bound_load_balancer: BoundLoadBalancer, ): - hetzner_client.request.return_value = response_get_metrics + request_mock.return_value = response_get_metrics response = bound_load_balancer.get_metrics( type=["requests_per_second"], start="2023-12-14T16:55:32+01:00", end="2023-12-14T16:55:32+01:00", ) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/load_balancers/14/metrics", method="GET", params={ @@ -121,12 +91,16 @@ def test_get_metrics( assert len(response.metrics.time_series["requests_per_second"]["values"]) == 3 def test_add_service( - self, hetzner_client, response_add_service, bound_load_balancer + self, + request_mock: mock.MagicMock, + client: Client, + response_add_service, + bound_load_balancer, ): - hetzner_client.request.return_value = response_add_service + request_mock.return_value = response_add_service service = LoadBalancerService(listen_port=80, protocol="http") action = bound_load_balancer.add_service(service) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( json={"protocol": "http", "listen_port": 80}, url="/load_balancers/14/actions/add_service", method="POST", @@ -137,12 +111,16 @@ def test_add_service( assert action.command == "add_service" def test_delete_service( - self, hetzner_client, response_delete_service, bound_load_balancer + self, + request_mock: mock.MagicMock, + client: Client, + response_delete_service, + bound_load_balancer, ): - hetzner_client.request.return_value = response_delete_service + request_mock.return_value = response_delete_service service = LoadBalancerService(listen_port=12) action = bound_load_balancer.delete_service(service) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( json={"listen_port": 12}, url="/load_balancers/14/actions/delete_service", method="POST", @@ -175,12 +153,18 @@ def test_delete_service( ], ) def test_add_target( - self, hetzner_client, response_add_target, bound_load_balancer, target, params + self, + request_mock: mock.MagicMock, + client: Client, + response_add_target, + bound_load_balancer, + target, + params, ): - hetzner_client.request.return_value = response_add_target + request_mock.return_value = response_add_target action = bound_load_balancer.add_target(target) params.update({"type": target.type}) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/load_balancers/14/actions/add_target", method="POST", json=params ) @@ -212,16 +196,16 @@ def test_add_target( ) def test_remove_target( self, - hetzner_client, + request_mock: mock.MagicMock, response_remove_target, bound_load_balancer, target, params, ): - hetzner_client.request.return_value = response_remove_target + request_mock.return_value = response_remove_target action = bound_load_balancer.remove_target(target) params.update({"type": target.type}) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/load_balancers/14/actions/remove_target", method="POST", json=params ) @@ -230,16 +214,20 @@ def test_remove_target( assert action.command == "remove_target" def test_update_service( - self, hetzner_client, response_update_service, bound_load_balancer + self, + request_mock: mock.MagicMock, + client: Client, + response_update_service, + bound_load_balancer, ): - hetzner_client.request.return_value = response_update_service + request_mock.return_value = response_update_service new_health_check = LoadBalancerHealthCheck( protocol="http", port=13, interval=1, timeout=1, retries=1 ) service = LoadBalancerService(listen_port=12, health_check=new_health_check) action = bound_load_balancer.update_service(service) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( json={ "listen_port": 12, "health_check": { @@ -259,12 +247,16 @@ def test_update_service( assert action.command == "update_service" def test_change_algorithm( - self, hetzner_client, response_change_algorithm, bound_load_balancer + self, + request_mock: mock.MagicMock, + client: Client, + response_change_algorithm, + bound_load_balancer, ): - hetzner_client.request.return_value = response_change_algorithm + request_mock.return_value = response_change_algorithm algorithm = LoadBalancerAlgorithm(type="round_robin") action = bound_load_balancer.change_algorithm(algorithm) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( json={"type": "round_robin"}, url="/load_balancers/14/actions/change_algorithm", method="POST", @@ -275,13 +267,16 @@ def test_change_algorithm( assert action.command == "change_algorithm" def test_change_dns_ptr( - self, hetzner_client, response_change_reverse_dns_entry, bound_load_balancer + self, + request_mock: mock.MagicMock, + response_change_reverse_dns_entry, + bound_load_balancer, ): - hetzner_client.request.return_value = response_change_reverse_dns_entry + request_mock.return_value = response_change_reverse_dns_entry action = bound_load_balancer.change_dns_ptr( ip="1.2.3.4", dns_ptr="lb1.example.com" ) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( json={"dns_ptr": "lb1.example.com", "ip": "1.2.3.4"}, url="/load_balancers/14/actions/change_dns_ptr", method="POST", @@ -292,11 +287,15 @@ def test_change_dns_ptr( assert action.command == "change_dns_ptr" def test_change_protection( - self, hetzner_client, response_change_protection, bound_load_balancer + self, + request_mock: mock.MagicMock, + client: Client, + response_change_protection, + bound_load_balancer, ): - hetzner_client.request.return_value = response_change_protection + request_mock.return_value = response_change_protection action = bound_load_balancer.change_protection(delete=True) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( json={"delete": True}, url="/load_balancers/14/actions/change_protection", method="POST", @@ -307,11 +306,14 @@ def test_change_protection( assert action.command == "change_protection" def test_enable_public_interface( - self, response_enable_public_interface, hetzner_client, bound_load_balancer + self, + request_mock: mock.MagicMock, + response_enable_public_interface, + bound_load_balancer, ): - hetzner_client.request.return_value = response_enable_public_interface + request_mock.return_value = response_enable_public_interface action = bound_load_balancer.enable_public_interface() - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/load_balancers/14/actions/enable_public_interface", method="POST" ) @@ -320,11 +322,14 @@ def test_enable_public_interface( assert action.command == "enable_public_interface" def test_disable_public_interface( - self, response_disable_public_interface, hetzner_client, bound_load_balancer + self, + request_mock: mock.MagicMock, + response_disable_public_interface, + bound_load_balancer, ): - hetzner_client.request.return_value = response_disable_public_interface + request_mock.return_value = response_disable_public_interface action = bound_load_balancer.disable_public_interface() - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/load_balancers/14/actions/disable_public_interface", method="POST" ) @@ -334,61 +339,73 @@ def test_disable_public_interface( def test_attach_to_network( self, - response_attach_load_balancer_to_network, - hetzner_client, + request_mock: mock.MagicMock, + action_response, bound_load_balancer, ): - hetzner_client.request.return_value = response_attach_load_balancer_to_network + request_mock.return_value = action_response action = bound_load_balancer.attach_to_network(Network(id=1)) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( json={"network": 1}, url="/load_balancers/14/actions/attach_to_network", method="POST", ) - assert action.id == 13 - assert action.progress == 100 - assert action.command == "attach_to_network" + assert action.id == 1 + assert action.progress == 20 + assert action.command == "command" def test_detach_from_network( - self, response_detach_from_network, hetzner_client, bound_load_balancer + self, + request_mock: mock.MagicMock, + action_response, + bound_load_balancer, ): - hetzner_client.request.return_value = response_detach_from_network + request_mock.return_value = action_response action = bound_load_balancer.detach_from_network(Network(id=1)) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( json={"network": 1}, url="/load_balancers/14/actions/detach_from_network", method="POST", ) - assert action.id == 13 - assert action.progress == 100 - assert action.command == "detach_from_network" + assert action.id == 1 + assert action.progress == 20 + assert action.command == "command" - def test_change_type(self, hetzner_client, bound_load_balancer, generic_action): - hetzner_client.request.return_value = generic_action + def test_change_type( + self, + request_mock: mock.MagicMock, + client: Client, + bound_load_balancer, + action_response, + ): + request_mock.return_value = action_response action = bound_load_balancer.change_type(LoadBalancerType(name="lb21")) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/load_balancers/14/actions/change_type", method="POST", json={"load_balancer_type": "lb21"}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 class TestLoadBalancerslient: @pytest.fixture() - def load_balancers_client(self): - return LoadBalancersClient(client=mock.MagicMock()) + def load_balancers_client(self, client: Client): + return LoadBalancersClient(client) - def test_get_by_id(self, load_balancers_client, response_load_balancer): - load_balancers_client._client.request.return_value = response_load_balancer + def test_get_by_id( + self, + request_mock: mock.MagicMock, + load_balancers_client, + response_load_balancer, + ): + request_mock.return_value = response_load_balancer bound_load_balancer = load_balancers_client.get_by_id(1) - load_balancers_client._client.request.assert_called_with( - url="/load_balancers/1", method="GET" - ) + request_mock.assert_called_with(url="/load_balancers/1", method="GET") assert bound_load_balancer._client is load_balancers_client assert bound_load_balancer.id == 4711 assert bound_load_balancer.name == "Web Frontend" @@ -410,13 +427,15 @@ def test_get_by_id(self, load_balancers_client, response_load_balancer): ], ) def test_get_list( - self, load_balancers_client, response_simple_load_balancers, params + self, + request_mock: mock.MagicMock, + load_balancers_client, + response_simple_load_balancers, + params, ): - load_balancers_client._client.request.return_value = ( - response_simple_load_balancers - ) + request_mock.return_value = response_simple_load_balancers result = load_balancers_client.get_list(**params) - load_balancers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/load_balancers", method="GET", params=params ) @@ -440,16 +459,18 @@ def test_get_list( "params", [{"name": "loadbalancer1", "label_selector": "label1"}, {}] ) def test_get_all( - self, load_balancers_client, response_simple_load_balancers, params + self, + request_mock: mock.MagicMock, + load_balancers_client, + response_simple_load_balancers, + params, ): - load_balancers_client._client.request.return_value = ( - response_simple_load_balancers - ) + request_mock.return_value = response_simple_load_balancers bound_load_balancers = load_balancers_client.get_all(**params) params.update({"page": 1, "per_page": 50}) - load_balancers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/load_balancers", method="GET", params=params ) @@ -466,15 +487,18 @@ def test_get_all( assert bound_load_balancer2.id == 4712 assert bound_load_balancer2.name == "Web Frontend2" - def test_get_by_name(self, load_balancers_client, response_simple_load_balancers): - load_balancers_client._client.request.return_value = ( - response_simple_load_balancers - ) + def test_get_by_name( + self, + request_mock: mock.MagicMock, + load_balancers_client, + response_simple_load_balancers, + ): + request_mock.return_value = response_simple_load_balancers bound_load_balancer = load_balancers_client.get_by_name("Web Frontend") params = {"name": "Web Frontend"} - load_balancers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/load_balancers", method="GET", params=params ) @@ -482,16 +506,19 @@ def test_get_by_name(self, load_balancers_client, response_simple_load_balancers assert bound_load_balancer.id == 4711 assert bound_load_balancer.name == "Web Frontend" - def test_create(self, load_balancers_client, response_create_load_balancer): - load_balancers_client._client.request.return_value = ( - response_create_load_balancer - ) + def test_create( + self, + request_mock: mock.MagicMock, + load_balancers_client, + response_create_load_balancer, + ): + request_mock.return_value = response_create_load_balancer response = load_balancers_client.create( "my-balancer", load_balancer_type=LoadBalancerType(name="lb11"), location=Location(id=1), ) - load_balancers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/load_balancers", method="POST", json={"name": "my-balancer", "load_balancer_type": "lb11", "location": 1}, @@ -508,87 +535,45 @@ def test_create(self, load_balancers_client, response_create_load_balancer): [LoadBalancer(id=1), BoundLoadBalancer(mock.MagicMock(), dict(id=1))], ) def test_change_type_with_load_balancer_type_name( - self, load_balancers_client, load_balancer, generic_action + self, + request_mock: mock.MagicMock, + load_balancers_client, + load_balancer, + action_response, ): - load_balancers_client._client.request.return_value = generic_action + request_mock.return_value = action_response action = load_balancers_client.change_type( load_balancer, LoadBalancerType(name="lb11") ) - load_balancers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/load_balancers/1/actions/change_type", method="POST", json={"load_balancer_type": "lb11"}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "load_balancer", [LoadBalancer(id=1), BoundLoadBalancer(mock.MagicMock(), dict(id=1))], ) def test_change_type_with_load_balancer_type_id( - self, load_balancers_client, load_balancer, generic_action + self, + request_mock: mock.MagicMock, + load_balancers_client, + load_balancer, + action_response, ): - load_balancers_client._client.request.return_value = generic_action + request_mock.return_value = action_response action = load_balancers_client.change_type( load_balancer, LoadBalancerType(id=1) ) - load_balancers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/load_balancers/1/actions/change_type", method="POST", json={"load_balancer_type": 1}, ) assert action.id == 1 - assert action.progress == 0 - - def test_actions_get_by_id(self, load_balancers_client, response_get_actions): - load_balancers_client._client.request.return_value = { - "action": response_get_actions["actions"][0] - } - action = load_balancers_client.actions.get_by_id(13) - - load_balancers_client._client.request.assert_called_with( - url="/load_balancers/actions/13", method="GET" - ) - - assert isinstance(action, BoundAction) - assert action._client == load_balancers_client._client.actions - assert action.id == 13 - assert action.command == "change_protection" - - def test_actions_get_list(self, load_balancers_client, response_get_actions): - load_balancers_client._client.request.return_value = response_get_actions - result = load_balancers_client.actions.get_list() - - load_balancers_client._client.request.assert_called_with( - url="/load_balancers/actions", - method="GET", - params={}, - ) - - actions = result.actions - assert result.meta is not None - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - assert actions[0]._client == load_balancers_client._client.actions - assert actions[0].id == 13 - assert actions[0].command == "change_protection" - - def test_actions_get_all(self, load_balancers_client, response_get_actions): - load_balancers_client._client.request.return_value = response_get_actions - actions = load_balancers_client.actions.get_all() - - load_balancers_client._client.request.assert_called_with( - url="/load_balancers/actions", - method="GET", - params={"page": 1, "per_page": 50}, - ) - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - assert actions[0]._client == load_balancers_client._client.actions - assert actions[0].id == 13 - assert actions[0].command == "change_protection" + assert action.progress == 20 diff --git a/tests/unit/locations/test_client.py b/tests/unit/locations/test_client.py index c288230a..68f3640b 100644 --- a/tests/unit/locations/test_client.py +++ b/tests/unit/locations/test_client.py @@ -4,20 +4,21 @@ import pytest # noqa: F401 +from hcloud import Client from hcloud.locations import LocationsClient class TestLocationsClient: @pytest.fixture() - def locations_client(self): - return LocationsClient(client=mock.MagicMock()) + def locations_client(self, client: Client): + return LocationsClient(client) - def test_get_by_id(self, locations_client, location_response): - locations_client._client.request.return_value = location_response + def test_get_by_id( + self, request_mock: mock.MagicMock, locations_client, location_response + ): + request_mock.return_value = location_response location = locations_client.get_by_id(1) - locations_client._client.request.assert_called_with( - url="/locations/1", method="GET" - ) + request_mock.assert_called_with(url="/locations/1", method="GET") assert location._client is locations_client assert location.id == 1 assert location.name == "fsn1" @@ -26,12 +27,16 @@ def test_get_by_id(self, locations_client, location_response): @pytest.mark.parametrize( "params", [{"name": "fsn1", "page": 1, "per_page": 10}, {"name": ""}, {}] ) - def test_get_list(self, locations_client, two_locations_response, params): - locations_client._client.request.return_value = two_locations_response + def test_get_list( + self, + request_mock: mock.MagicMock, + locations_client, + two_locations_response, + params, + ): + request_mock.return_value = two_locations_response result = locations_client.get_list(**params) - locations_client._client.request.assert_called_with( - url="/locations", method="GET", params=params - ) + request_mock.assert_called_with(url="/locations", method="GET", params=params) locations = result.locations assert result.meta is not None @@ -52,15 +57,19 @@ def test_get_list(self, locations_client, two_locations_response, params): assert location2.network_zone == "eu-central" @pytest.mark.parametrize("params", [{"name": "fsn1"}, {}]) - def test_get_all(self, locations_client, two_locations_response, params): - locations_client._client.request.return_value = two_locations_response + def test_get_all( + self, + request_mock: mock.MagicMock, + locations_client, + two_locations_response, + params, + ): + request_mock.return_value = two_locations_response locations = locations_client.get_all(**params) params.update({"page": 1, "per_page": 50}) - locations_client._client.request.assert_called_with( - url="/locations", method="GET", params=params - ) + request_mock.assert_called_with(url="/locations", method="GET", params=params) assert len(locations) == 2 @@ -77,15 +86,15 @@ def test_get_all(self, locations_client, two_locations_response, params): assert location2.name == "nbg1" assert location2.network_zone == "eu-central" - def test_get_by_name(self, locations_client, one_locations_response): - locations_client._client.request.return_value = one_locations_response + def test_get_by_name( + self, request_mock: mock.MagicMock, locations_client, one_locations_response + ): + request_mock.return_value = one_locations_response location = locations_client.get_by_name("fsn1") params = {"name": "fsn1"} - locations_client._client.request.assert_called_with( - url="/locations", method="GET", params=params - ) + request_mock.assert_called_with(url="/locations", method="GET", params=params) assert location._client is locations_client assert location.id == 1 diff --git a/tests/unit/networks/test_client.py b/tests/unit/networks/test_client.py index 4e986414..ba762820 100644 --- a/tests/unit/networks/test_client.py +++ b/tests/unit/networks/test_client.py @@ -5,7 +5,7 @@ import pytest from dateutil.parser import isoparse -from hcloud.actions import BoundAction +from hcloud import Client from hcloud.networks import ( BoundNetwork, Network, @@ -18,8 +18,8 @@ class TestBoundNetwork: @pytest.fixture() - def bound_network(self, hetzner_client): - return BoundNetwork(client=hetzner_client.networks, data=dict(id=14)) + def bound_network(self, request_mock: mock.MagicMock, client: Client): + return BoundNetwork(client=client.networks, data=dict(id=14)) def test_bound_network_init(self, network_response): bound_network = BoundNetwork( @@ -49,59 +49,68 @@ def test_bound_network_init(self, network_response): assert bound_network.routes[0].destination == "10.100.1.0/24" assert bound_network.routes[0].gateway == "10.0.1.1" - def test_get_actions(self, hetzner_client, bound_network, response_get_actions): - hetzner_client.request.return_value = response_get_actions - actions = bound_network.get_actions(sort="id") - hetzner_client.request.assert_called_with( - url="/networks/14/actions", - method="GET", - params={"page": 1, "per_page": 50, "sort": "id"}, - ) - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - assert actions[0]._client == hetzner_client.actions - assert actions[0].id == 13 - assert actions[0].command == "add_subnet" - - def test_update(self, hetzner_client, bound_network, response_update_network): - hetzner_client.request.return_value = response_update_network + def test_update( + self, + request_mock: mock.MagicMock, + client: Client, + bound_network, + response_update_network, + ): + request_mock.return_value = response_update_network network = bound_network.update(name="new-name") - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/networks/14", method="PUT", json={"name": "new-name"} ) assert network.id == 4711 assert network.name == "new-name" - def test_delete(self, hetzner_client, bound_network, generic_action): - hetzner_client.request.return_value = generic_action + def test_delete( + self, + request_mock: mock.MagicMock, + client: Client, + bound_network, + action_response, + ): + request_mock.return_value = action_response delete_success = bound_network.delete() - hetzner_client.request.assert_called_with(url="/networks/14", method="DELETE") + request_mock.assert_called_with(url="/networks/14", method="DELETE") assert delete_success is True - def test_change_protection(self, hetzner_client, bound_network, generic_action): - hetzner_client.request.return_value = generic_action + def test_change_protection( + self, + request_mock: mock.MagicMock, + client: Client, + bound_network, + action_response, + ): + request_mock.return_value = action_response action = bound_network.change_protection(True) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/networks/14/actions/change_protection", method="POST", json={"delete": True}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 - def test_add_subnet(self, hetzner_client, bound_network, generic_action): - hetzner_client.request.return_value = generic_action + def test_add_subnet( + self, + request_mock: mock.MagicMock, + client: Client, + bound_network, + action_response, + ): + request_mock.return_value = action_response subnet = NetworkSubnet( type=NetworkSubnet.TYPE_CLOUD, ip_range="10.0.1.0/24", network_zone="eu-central", ) action = bound_network.add_subnet(subnet) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/networks/14/actions/add_subnet", method="POST", json={ @@ -112,64 +121,88 @@ def test_add_subnet(self, hetzner_client, bound_network, generic_action): ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 - def test_delete_subnet(self, hetzner_client, bound_network, generic_action): - hetzner_client.request.return_value = generic_action + def test_delete_subnet( + self, + request_mock: mock.MagicMock, + client: Client, + bound_network, + action_response, + ): + request_mock.return_value = action_response subnet = NetworkSubnet(ip_range="10.0.1.0/24") action = bound_network.delete_subnet(subnet) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/networks/14/actions/delete_subnet", method="POST", json={"ip_range": "10.0.1.0/24"}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 - def test_add_route(self, hetzner_client, bound_network, generic_action): - hetzner_client.request.return_value = generic_action + def test_add_route( + self, + request_mock: mock.MagicMock, + client: Client, + bound_network, + action_response, + ): + request_mock.return_value = action_response route = NetworkRoute(destination="10.100.1.0/24", gateway="10.0.1.1") action = bound_network.add_route(route) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/networks/14/actions/add_route", method="POST", json={"destination": "10.100.1.0/24", "gateway": "10.0.1.1"}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 - def test_delete_route(self, hetzner_client, bound_network, generic_action): - hetzner_client.request.return_value = generic_action + def test_delete_route( + self, + request_mock: mock.MagicMock, + client: Client, + bound_network, + action_response, + ): + request_mock.return_value = action_response route = NetworkRoute(destination="10.100.1.0/24", gateway="10.0.1.1") action = bound_network.delete_route(route) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/networks/14/actions/delete_route", method="POST", json={"destination": "10.100.1.0/24", "gateway": "10.0.1.1"}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 - def test_change_ip(self, hetzner_client, bound_network, generic_action): - hetzner_client.request.return_value = generic_action + def test_change_ip( + self, + request_mock: mock.MagicMock, + client: Client, + bound_network, + action_response, + ): + request_mock.return_value = action_response action = bound_network.change_ip_range("10.0.0.0/12") - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/networks/14/actions/change_ip_range", method="POST", json={"ip_range": "10.0.0.0/12"}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 class TestNetworksClient: @pytest.fixture() - def networks_client(self): - return NetworksClient(client=mock.MagicMock()) + def networks_client(self, client: Client): + return NetworksClient(client) @pytest.fixture() def network_subnet(self): @@ -192,12 +225,12 @@ def network_vswitch_subnet(self): def network_route(self): return NetworkRoute(destination="10.100.1.0/24", gateway="10.0.1.1") - def test_get_by_id(self, networks_client, network_response): - networks_client._client.request.return_value = network_response + def test_get_by_id( + self, request_mock: mock.MagicMock, networks_client, network_response + ): + request_mock.return_value = network_response bound_network = networks_client.get_by_id(1) - networks_client._client.request.assert_called_with( - url="/networks/1", method="GET" - ) + request_mock.assert_called_with(url="/networks/1", method="GET") assert bound_network._client is networks_client assert bound_network.id == 1 assert bound_network.name == "mynet" @@ -206,12 +239,16 @@ def test_get_by_id(self, networks_client, network_response): "params", [{"label_selector": "label1", "page": 1, "per_page": 10}, {"name": ""}, {}], ) - def test_get_list(self, networks_client, two_networks_response, params): - networks_client._client.request.return_value = two_networks_response + def test_get_list( + self, + request_mock: mock.MagicMock, + networks_client, + two_networks_response, + params, + ): + request_mock.return_value = two_networks_response result = networks_client.get_list(**params) - networks_client._client.request.assert_called_with( - url="/networks", method="GET", params=params - ) + request_mock.assert_called_with(url="/networks", method="GET", params=params) bound_networks = result.networks assert result.meta is not None @@ -230,15 +267,19 @@ def test_get_list(self, networks_client, two_networks_response, params): assert bound_network2.name == "myanothernet" @pytest.mark.parametrize("params", [{"label_selector": "label1"}]) - def test_get_all(self, networks_client, two_networks_response, params): - networks_client._client.request.return_value = two_networks_response + def test_get_all( + self, + request_mock: mock.MagicMock, + networks_client, + two_networks_response, + params, + ): + request_mock.return_value = two_networks_response bound_networks = networks_client.get_all(**params) params.update({"page": 1, "per_page": 50}) - networks_client._client.request.assert_called_with( - url="/networks", method="GET", params=params - ) + request_mock.assert_called_with(url="/networks", method="GET", params=params) assert len(bound_networks) == 2 @@ -253,39 +294,44 @@ def test_get_all(self, networks_client, two_networks_response, params): assert bound_network2.id == 2 assert bound_network2.name == "myanothernet" - def test_get_by_name(self, networks_client, one_network_response): - networks_client._client.request.return_value = one_network_response + def test_get_by_name( + self, request_mock: mock.MagicMock, networks_client, one_network_response + ): + request_mock.return_value = one_network_response bound_network = networks_client.get_by_name("mynet") params = {"name": "mynet"} - networks_client._client.request.assert_called_with( - url="/networks", method="GET", params=params - ) + request_mock.assert_called_with(url="/networks", method="GET", params=params) assert bound_network._client is networks_client assert bound_network.id == 1 assert bound_network.name == "mynet" - def test_create(self, networks_client, network_create_response): - networks_client._client.request.return_value = network_create_response + def test_create( + self, request_mock: mock.MagicMock, networks_client, network_create_response + ): + request_mock.return_value = network_create_response networks_client.create(name="mynet", ip_range="10.0.0.0/8") - networks_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/networks", method="POST", json={"name": "mynet", "ip_range": "10.0.0.0/8"}, ) def test_create_with_expose_routes_to_vswitch( - self, networks_client, network_create_response_with_expose_routes_to_vswitch + self, + request_mock: mock.MagicMock, + networks_client, + network_create_response_with_expose_routes_to_vswitch, ): - networks_client._client.request.return_value = ( + request_mock.return_value = ( network_create_response_with_expose_routes_to_vswitch ) networks_client.create( name="mynet", ip_range="10.0.0.0/8", expose_routes_to_vswitch=True ) - networks_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/networks", method="POST", json={ @@ -296,13 +342,17 @@ def test_create_with_expose_routes_to_vswitch( ) def test_create_with_subnet( - self, networks_client, network_subnet, network_create_response + self, + request_mock: mock.MagicMock, + networks_client, + network_subnet, + network_create_response, ): - networks_client._client.request.return_value = network_create_response + request_mock.return_value = network_create_response networks_client.create( name="mynet", ip_range="10.0.0.0/8", subnets=[network_subnet] ) - networks_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/networks", method="POST", json={ @@ -319,15 +369,19 @@ def test_create_with_subnet( ) def test_create_with_subnet_vswitch( - self, networks_client, network_subnet, network_create_response + self, + request_mock: mock.MagicMock, + networks_client, + network_subnet, + network_create_response, ): - networks_client._client.request.return_value = network_create_response + request_mock.return_value = network_create_response network_subnet.type = NetworkSubnet.TYPE_VSWITCH network_subnet.vswitch_id = 1000 networks_client.create( name="mynet", ip_range="10.0.0.0/8", subnets=[network_subnet] ) - networks_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/networks", method="POST", json={ @@ -345,13 +399,17 @@ def test_create_with_subnet_vswitch( ) def test_create_with_route( - self, networks_client, network_route, network_create_response + self, + request_mock: mock.MagicMock, + networks_client, + network_route, + network_create_response, ): - networks_client._client.request.return_value = network_create_response + request_mock.return_value = network_create_response networks_client.create( name="mynet", ip_range="10.0.0.0/8", routes=[network_route] ) - networks_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/networks", method="POST", json={ @@ -363,11 +421,12 @@ def test_create_with_route( def test_create_with_route_and_expose_routes_to_vswitch( self, + request_mock: mock.MagicMock, networks_client, network_route, network_create_response_with_expose_routes_to_vswitch, ): - networks_client._client.request.return_value = ( + request_mock.return_value = ( network_create_response_with_expose_routes_to_vswitch ) networks_client.create( @@ -376,7 +435,7 @@ def test_create_with_route_and_expose_routes_to_vswitch( routes=[network_route], expose_routes_to_vswitch=True, ) - networks_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/networks", method="POST", json={ @@ -388,16 +447,21 @@ def test_create_with_route_and_expose_routes_to_vswitch( ) def test_create_with_route_and_subnet( - self, networks_client, network_subnet, network_route, network_create_response + self, + request_mock: mock.MagicMock, + networks_client, + network_subnet, + network_route, + network_create_response, ): - networks_client._client.request.return_value = network_create_response + request_mock.return_value = network_create_response networks_client.create( name="mynet", ip_range="10.0.0.0/8", subnets=[network_subnet], routes=[network_route], ) - networks_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/networks", method="POST", json={ @@ -417,30 +481,18 @@ def test_create_with_route_and_subnet( @pytest.mark.parametrize( "network", [Network(id=1), BoundNetwork(mock.MagicMock(), dict(id=1))] ) - def test_get_actions_list(self, networks_client, network, response_get_actions): - networks_client._client.request.return_value = response_get_actions - result = networks_client.get_actions_list(network, sort="id") - networks_client._client.request.assert_called_with( - url="/networks/1/actions", method="GET", params={"sort": "id"} - ) - - actions = result.actions - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - - assert actions[0]._client == networks_client._client.actions - assert actions[0].id == 13 - assert actions[0].command == "add_subnet" - - @pytest.mark.parametrize( - "network", [Network(id=1), BoundNetwork(mock.MagicMock(), dict(id=1))] - ) - def test_update(self, networks_client, network, response_update_network): - networks_client._client.request.return_value = response_update_network + def test_update( + self, + request_mock: mock.MagicMock, + networks_client, + network, + response_update_network, + ): + request_mock.return_value = response_update_network network = networks_client.update( network, name="new-name", expose_routes_to_vswitch=True ) - networks_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/networks/1", method="PUT", json={"name": "new-name", "expose_routes_to_vswitch": True}, @@ -453,38 +505,55 @@ def test_update(self, networks_client, network, response_update_network): @pytest.mark.parametrize( "network", [Network(id=1), BoundNetwork(mock.MagicMock(), dict(id=1))] ) - def test_change_protection(self, networks_client, network, generic_action): - networks_client._client.request.return_value = generic_action + def test_change_protection( + self, + request_mock: mock.MagicMock, + networks_client, + network, + action_response, + ): + request_mock.return_value = action_response action = networks_client.change_protection(network, True) - networks_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/networks/1/actions/change_protection", method="POST", json={"delete": True}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "network", [Network(id=1), BoundNetwork(mock.MagicMock(), dict(id=1))] ) - def test_delete(self, networks_client, network, generic_action): - networks_client._client.request.return_value = generic_action + def test_delete( + self, + request_mock: mock.MagicMock, + networks_client, + network, + action_response, + ): + request_mock.return_value = action_response delete_success = networks_client.delete(network) - networks_client._client.request.assert_called_with( - url="/networks/1", method="DELETE" - ) + request_mock.assert_called_with(url="/networks/1", method="DELETE") assert delete_success is True @pytest.mark.parametrize( "network", [Network(id=1), BoundNetwork(mock.MagicMock(), dict(id=1))] ) - def test_add_subnet(self, networks_client, network, generic_action, network_subnet): - networks_client._client.request.return_value = generic_action + def test_add_subnet( + self, + request_mock: mock.MagicMock, + networks_client, + network, + action_response, + network_subnet, + ): + request_mock.return_value = action_response action = networks_client.add_subnet(network, network_subnet) - networks_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/networks/1/actions/add_subnet", method="POST", json={ @@ -495,18 +564,23 @@ def test_add_subnet(self, networks_client, network, generic_action, network_subn ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "network", [Network(id=1), BoundNetwork(mock.MagicMock(), dict(id=1))] ) def test_add_subnet_vswitch( - self, networks_client, network, generic_action, network_vswitch_subnet + self, + request_mock: mock.MagicMock, + networks_client, + network, + action_response, + network_vswitch_subnet, ): - networks_client._client.request.return_value = generic_action + request_mock.return_value = action_response action = networks_client.add_subnet(network, network_vswitch_subnet) - networks_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/networks/1/actions/add_subnet", method="POST", json={ @@ -518,121 +592,94 @@ def test_add_subnet_vswitch( ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "network", [Network(id=1), BoundNetwork(mock.MagicMock(), dict(id=1))] ) def test_delete_subnet( - self, networks_client, network, generic_action, network_subnet + self, + request_mock: mock.MagicMock, + networks_client, + network, + action_response, + network_subnet, ): - networks_client._client.request.return_value = generic_action + request_mock.return_value = action_response action = networks_client.delete_subnet(network, network_subnet) - networks_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/networks/1/actions/delete_subnet", method="POST", json={"ip_range": "10.0.1.0/24"}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "network", [Network(id=1), BoundNetwork(mock.MagicMock(), dict(id=1))] ) - def test_add_route(self, networks_client, network, generic_action, network_route): - networks_client._client.request.return_value = generic_action + def test_add_route( + self, + request_mock: mock.MagicMock, + networks_client, + network, + action_response, + network_route, + ): + request_mock.return_value = action_response action = networks_client.add_route(network, network_route) - networks_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/networks/1/actions/add_route", method="POST", json={"destination": "10.100.1.0/24", "gateway": "10.0.1.1"}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "network", [Network(id=1), BoundNetwork(mock.MagicMock(), dict(id=1))] ) def test_delete_route( - self, networks_client, network, generic_action, network_route + self, + request_mock: mock.MagicMock, + networks_client, + network, + action_response, + network_route, ): - networks_client._client.request.return_value = generic_action + request_mock.return_value = action_response action = networks_client.delete_route(network, network_route) - networks_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/networks/1/actions/delete_route", method="POST", json={"destination": "10.100.1.0/24", "gateway": "10.0.1.1"}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "network", [Network(id=1), BoundNetwork(mock.MagicMock(), dict(id=1))] ) - def test_change_ip_range(self, networks_client, network, generic_action): - networks_client._client.request.return_value = generic_action + def test_change_ip_range( + self, + request_mock: mock.MagicMock, + networks_client, + network, + action_response, + ): + request_mock.return_value = action_response action = networks_client.change_ip_range(network, "10.0.0.0/12") - networks_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/networks/1/actions/change_ip_range", method="POST", json={"ip_range": "10.0.0.0/12"}, ) assert action.id == 1 - assert action.progress == 0 - - def test_actions_get_by_id(self, networks_client, response_get_actions): - networks_client._client.request.return_value = { - "action": response_get_actions["actions"][0] - } - action = networks_client.actions.get_by_id(13) - - networks_client._client.request.assert_called_with( - url="/networks/actions/13", method="GET" - ) - - assert isinstance(action, BoundAction) - assert action._client == networks_client._client.actions - assert action.id == 13 - assert action.command == "add_subnet" - - def test_actions_get_list(self, networks_client, response_get_actions): - networks_client._client.request.return_value = response_get_actions - result = networks_client.actions.get_list() - - networks_client._client.request.assert_called_with( - url="/networks/actions", - method="GET", - params={}, - ) - - actions = result.actions - assert result.meta is not None - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - assert actions[0]._client == networks_client._client.actions - assert actions[0].id == 13 - assert actions[0].command == "add_subnet" - - def test_actions_get_all(self, networks_client, response_get_actions): - networks_client._client.request.return_value = response_get_actions - actions = networks_client.actions.get_all() - - networks_client._client.request.assert_called_with( - url="/networks/actions", - method="GET", - params={"page": 1, "per_page": 50}, - ) - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - assert actions[0]._client == networks_client._client.actions - assert actions[0].id == 13 - assert actions[0].command == "add_subnet" + assert action.progress == 20 diff --git a/tests/unit/placement_groups/test_client.py b/tests/unit/placement_groups/test_client.py index 27410cf9..bd208897 100644 --- a/tests/unit/placement_groups/test_client.py +++ b/tests/unit/placement_groups/test_client.py @@ -4,6 +4,7 @@ import pytest +from hcloud import Client from hcloud.placement_groups import BoundPlacementGroup, PlacementGroupsClient @@ -17,10 +18,8 @@ def check_variables(placement_group, expected): class TestBoundPlacementGroup: @pytest.fixture() - def bound_placement_group(self, hetzner_client): - return BoundPlacementGroup( - client=hetzner_client.placement_groups, data=dict(id=897) - ) + def bound_placement_group(self, client: Client): + return BoundPlacementGroup(client=client.placement_groups, data=dict(id=897)) def test_bound_placement_group_init(self, placement_group_response): bound_placement_group = BoundPlacementGroup( @@ -32,14 +31,18 @@ def test_bound_placement_group_init(self, placement_group_response): ) def test_update( - self, hetzner_client, bound_placement_group, placement_group_response + self, + request_mock: mock.MagicMock, + client: Client, + bound_placement_group, + placement_group_response, ): - hetzner_client.request.return_value = placement_group_response + request_mock.return_value = placement_group_response placement_group = bound_placement_group.update( name=placement_group_response["placement_group"]["name"], labels=placement_group_response["placement_group"]["labels"], ) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/placement_groups/{placement_group_id}".format( placement_group_id=placement_group_response["placement_group"]["id"] ), @@ -52,26 +55,31 @@ def test_update( check_variables(placement_group, placement_group_response["placement_group"]) - def test_delete(self, hetzner_client, bound_placement_group): + def test_delete( + self, request_mock: mock.MagicMock, client: Client, bound_placement_group + ): delete_success = bound_placement_group.delete() - hetzner_client.request.assert_called_with( - url="/placement_groups/897", method="DELETE" - ) + request_mock.assert_called_with(url="/placement_groups/897", method="DELETE") assert delete_success is True class TestPlacementGroupsClient: @pytest.fixture() - def placement_groups_client(self): - return PlacementGroupsClient(client=mock.MagicMock()) - - def test_get_by_id(self, placement_groups_client, placement_group_response): - placement_groups_client._client.request.return_value = placement_group_response + def placement_groups_client(self, client: Client): + return PlacementGroupsClient(client) + + def test_get_by_id( + self, + request_mock: mock.MagicMock, + placement_groups_client, + placement_group_response, + ): + request_mock.return_value = placement_group_response placement_group = placement_groups_client.get_by_id( placement_group_response["placement_group"]["id"] ) - placement_groups_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/placement_groups/{placement_group_id}".format( placement_group_id=placement_group_response["placement_group"]["id"] ), @@ -97,13 +105,15 @@ def test_get_by_id(self, placement_groups_client, placement_group_response): ], ) def test_get_list( - self, placement_groups_client, two_placement_groups_response, params + self, + request_mock: mock.MagicMock, + placement_groups_client, + two_placement_groups_response, + params, ): - placement_groups_client._client.request.return_value = ( - two_placement_groups_response - ) + request_mock.return_value = two_placement_groups_response result = placement_groups_client.get_list(**params) - placement_groups_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/placement_groups", method="GET", params=params ) @@ -133,15 +143,17 @@ def test_get_list( ], ) def test_get_all( - self, placement_groups_client, two_placement_groups_response, params + self, + request_mock: mock.MagicMock, + placement_groups_client, + two_placement_groups_response, + params, ): - placement_groups_client._client.request.return_value = ( - two_placement_groups_response - ) + request_mock.return_value = two_placement_groups_response placement_groups = placement_groups_client.get_all(**params) params.update({"page": 1, "per_page": 50}) - placement_groups_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/placement_groups", method="GET", params=params ) @@ -156,16 +168,19 @@ def test_get_all( check_variables(placement_group, expected) - def test_get_by_name(self, placement_groups_client, one_placement_group_response): - placement_groups_client._client.request.return_value = ( - one_placement_group_response - ) + def test_get_by_name( + self, + request_mock: mock.MagicMock, + placement_groups_client, + one_placement_group_response, + ): + request_mock.return_value = one_placement_group_response placement_group = placement_groups_client.get_by_name( one_placement_group_response["placement_groups"][0]["name"] ) params = {"name": one_placement_group_response["placement_groups"][0]["name"]} - placement_groups_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/placement_groups", method="GET", params=params ) @@ -173,10 +188,13 @@ def test_get_by_name(self, placement_groups_client, one_placement_group_response placement_group, one_placement_group_response["placement_groups"][0] ) - def test_create(self, placement_groups_client, response_create_placement_group): - placement_groups_client._client.request.return_value = ( - response_create_placement_group - ) + def test_create( + self, + request_mock: mock.MagicMock, + placement_groups_client, + response_create_placement_group, + ): + request_mock.return_value = response_create_placement_group response = placement_groups_client.create( name=response_create_placement_group["placement_group"]["name"], type=response_create_placement_group["placement_group"]["type"], @@ -188,7 +206,7 @@ def test_create(self, placement_groups_client, response_create_placement_group): "labels": response_create_placement_group["placement_group"]["labels"], "type": response_create_placement_group["placement_group"]["type"], } - placement_groups_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/placement_groups", method="POST", json=json ) diff --git a/tests/unit/primary_ips/test_client.py b/tests/unit/primary_ips/test_client.py index 65a19be9..8366bec7 100644 --- a/tests/unit/primary_ips/test_client.py +++ b/tests/unit/primary_ips/test_client.py @@ -4,15 +4,15 @@ import pytest -from hcloud.actions import BoundAction +from hcloud import Client from hcloud.datacenters import BoundDatacenter, Datacenter from hcloud.primary_ips import BoundPrimaryIP, PrimaryIP, PrimaryIPsClient class TestBoundPrimaryIP: @pytest.fixture() - def bound_primary_ip(self, hetzner_client): - return BoundPrimaryIP(client=hetzner_client.primary_ips, data=dict(id=14)) + def bound_primary_ip(self, client: Client): + return BoundPrimaryIP(client=client.primary_ips, data=dict(id=14)) def test_bound_primary_ip_init(self, primary_ip_response): bound_primary_ip = BoundPrimaryIP( @@ -39,10 +39,16 @@ def test_bound_primary_ip_init(self, primary_ip_response): assert bound_primary_ip.datacenter.location.latitude == 50.47612 assert bound_primary_ip.datacenter.location.longitude == 12.370071 - def test_update(self, hetzner_client, bound_primary_ip, response_update_primary_ip): - hetzner_client.request.return_value = response_update_primary_ip + def test_update( + self, + request_mock: mock.MagicMock, + client: Client, + bound_primary_ip, + response_update_primary_ip, + ): + request_mock.return_value = response_update_primary_ip primary_ip = bound_primary_ip.update(auto_delete=True, name="my-resource") - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/primary_ips/14", method="PUT", json={"auto_delete": True, "name": "my-resource"}, @@ -51,77 +57,107 @@ def test_update(self, hetzner_client, bound_primary_ip, response_update_primary_ assert primary_ip.id == 42 assert primary_ip.auto_delete is True - def test_delete(self, hetzner_client, bound_primary_ip, generic_action): - hetzner_client.request.return_value = generic_action + def test_delete( + self, + request_mock: mock.MagicMock, + client: Client, + bound_primary_ip, + action_response, + ): + request_mock.return_value = action_response delete_success = bound_primary_ip.delete() - hetzner_client.request.assert_called_with( - url="/primary_ips/14", method="DELETE" - ) + request_mock.assert_called_with(url="/primary_ips/14", method="DELETE") assert delete_success is True - def test_change_protection(self, hetzner_client, bound_primary_ip, generic_action): - hetzner_client.request.return_value = generic_action + def test_change_protection( + self, + request_mock: mock.MagicMock, + client: Client, + bound_primary_ip, + action_response, + ): + request_mock.return_value = action_response action = bound_primary_ip.change_protection(True) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/primary_ips/14/actions/change_protection", method="POST", json={"delete": True}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 - def test_assign(self, hetzner_client, bound_primary_ip, generic_action): - hetzner_client.request.return_value = generic_action + def test_assign( + self, + request_mock: mock.MagicMock, + client: Client, + bound_primary_ip, + action_response, + ): + request_mock.return_value = action_response action = bound_primary_ip.assign(assignee_id=12, assignee_type="server") - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/primary_ips/14/actions/assign", method="POST", json={"assignee_id": 12, "assignee_type": "server"}, ) assert action.id == 1 - assert action.progress == 0 - - def test_unassign(self, hetzner_client, bound_primary_ip, generic_action): - hetzner_client.request.return_value = generic_action + assert action.progress == 20 + + def test_unassign( + self, + request_mock: mock.MagicMock, + client: Client, + bound_primary_ip, + action_response, + ): + request_mock.return_value = action_response action = bound_primary_ip.unassign() - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/primary_ips/14/actions/unassign", method="POST" ) assert action.id == 1 - assert action.progress == 0 - - def test_change_dns_ptr(self, hetzner_client, bound_primary_ip, generic_action): - hetzner_client.request.return_value = generic_action + assert action.progress == 20 + + def test_change_dns_ptr( + self, + request_mock: mock.MagicMock, + client: Client, + bound_primary_ip, + action_response, + ): + request_mock.return_value = action_response action = bound_primary_ip.change_dns_ptr("1.2.3.4", "server02.example.com") - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/primary_ips/14/actions/change_dns_ptr", method="POST", json={"ip": "1.2.3.4", "dns_ptr": "server02.example.com"}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 class TestPrimaryIPsClient: @pytest.fixture() - def primary_ips_client(self): - return PrimaryIPsClient(client=mock.MagicMock()) + def primary_ips_client(self, client: Client): + return PrimaryIPsClient(client) - def test_get_by_id(self, primary_ips_client, primary_ip_response): - primary_ips_client._client.request.return_value = primary_ip_response + def test_get_by_id( + self, request_mock: mock.MagicMock, primary_ips_client, primary_ip_response + ): + request_mock.return_value = primary_ip_response bound_primary_ip = primary_ips_client.get_by_id(1) - primary_ips_client._client.request.assert_called_with( - url="/primary_ips/1", method="GET" - ) + request_mock.assert_called_with(url="/primary_ips/1", method="GET") assert bound_primary_ip._client is primary_ips_client assert bound_primary_ip.id == 42 - def test_get_by_name(self, primary_ips_client, one_primary_ips_response): - primary_ips_client._client.request.return_value = one_primary_ips_response + def test_get_by_name( + self, request_mock: mock.MagicMock, primary_ips_client, one_primary_ips_response + ): + request_mock.return_value = one_primary_ips_response bound_primary_ip = primary_ips_client.get_by_name("my-resource") - primary_ips_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/primary_ips", method="GET", params={"name": "my-resource"} ) assert bound_primary_ip._client is primary_ips_client @@ -129,15 +165,19 @@ def test_get_by_name(self, primary_ips_client, one_primary_ips_response): assert bound_primary_ip.name == "my-resource" @pytest.mark.parametrize("params", [{"label_selector": "label1"}]) - def test_get_all(self, primary_ips_client, all_primary_ips_response, params): - primary_ips_client._client.request.return_value = all_primary_ips_response + def test_get_all( + self, + request_mock: mock.MagicMock, + primary_ips_client, + all_primary_ips_response, + params, + ): + request_mock.return_value = all_primary_ips_response bound_primary_ips = primary_ips_client.get_all(**params) params.update({"page": 1, "per_page": 50}) - primary_ips_client._client.request.assert_called_with( - url="/primary_ips", method="GET", params=params - ) + request_mock.assert_called_with(url="/primary_ips", method="GET", params=params) assert len(bound_primary_ips) == 1 @@ -147,12 +187,14 @@ def test_get_all(self, primary_ips_client, all_primary_ips_response, params): assert bound_primary_ip1.id == 42 assert bound_primary_ip1.name == "my-resource" - def test_create_with_datacenter(self, primary_ips_client, primary_ip_response): - primary_ips_client._client.request.return_value = primary_ip_response + def test_create_with_datacenter( + self, request_mock: mock.MagicMock, primary_ips_client, primary_ip_response + ): + request_mock.return_value = primary_ip_response response = primary_ips_client.create( type="ipv6", name="my-resource", datacenter=Datacenter(name="datacenter") ) - primary_ips_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/primary_ips", method="POST", json={ @@ -173,16 +215,19 @@ def test_create_with_datacenter(self, primary_ips_client, primary_ip_response): assert action is None def test_create_with_assignee_id( - self, primary_ips_client, primary_ip_create_response + self, + request_mock: mock.MagicMock, + primary_ips_client, + primary_ip_create_response, ): - primary_ips_client._client.request.return_value = primary_ip_create_response + request_mock.return_value = primary_ip_create_response response = primary_ips_client.create( type="ipv6", name="my-ip", assignee_id=17, assignee_type="server", ) - primary_ips_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/primary_ips", method="POST", json={ @@ -205,12 +250,18 @@ def test_create_with_assignee_id( @pytest.mark.parametrize( "primary_ip", [PrimaryIP(id=1), BoundPrimaryIP(mock.MagicMock(), dict(id=1))] ) - def test_update(self, primary_ips_client, primary_ip, response_update_primary_ip): - primary_ips_client._client.request.return_value = response_update_primary_ip + def test_update( + self, + request_mock: mock.MagicMock, + primary_ips_client, + primary_ip, + response_update_primary_ip, + ): + request_mock.return_value = response_update_primary_ip primary_ip = primary_ips_client.update( primary_ip, auto_delete=True, name="my-resource" ) - primary_ips_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/primary_ips/1", method="PUT", json={"auto_delete": True, "name": "my-resource"}, @@ -223,27 +274,37 @@ def test_update(self, primary_ips_client, primary_ip, response_update_primary_ip @pytest.mark.parametrize( "primary_ip", [PrimaryIP(id=1), BoundPrimaryIP(mock.MagicMock(), dict(id=1))] ) - def test_change_protection(self, primary_ips_client, primary_ip, generic_action): - primary_ips_client._client.request.return_value = generic_action + def test_change_protection( + self, + request_mock: mock.MagicMock, + primary_ips_client, + primary_ip, + action_response, + ): + request_mock.return_value = action_response action = primary_ips_client.change_protection(primary_ip, True) - primary_ips_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/primary_ips/1/actions/change_protection", method="POST", json={"delete": True}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "primary_ip", [PrimaryIP(id=1), BoundPrimaryIP(mock.MagicMock(), dict(id=1))] ) - def test_delete(self, primary_ips_client, primary_ip, generic_action): - primary_ips_client._client.request.return_value = generic_action + def test_delete( + self, + request_mock: mock.MagicMock, + primary_ips_client, + primary_ip, + action_response, + ): + request_mock.return_value = action_response delete_success = primary_ips_client.delete(primary_ip) - primary_ips_client._client.request.assert_called_with( - url="/primary_ips/1", method="DELETE" - ) + request_mock.assert_called_with(url="/primary_ips/1", method="DELETE") assert delete_success is True @@ -255,92 +316,60 @@ def test_delete(self, primary_ips_client, primary_ip, generic_action): ], ) def test_assign( - self, primary_ips_client, assignee_id, assignee_type, primary_ip, generic_action + self, + request_mock: mock.MagicMock, + primary_ips_client, + assignee_id, + assignee_type, + primary_ip, + action_response, ): - primary_ips_client._client.request.return_value = generic_action + request_mock.return_value = action_response action = primary_ips_client.assign(primary_ip, assignee_id, assignee_type) - primary_ips_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/primary_ips/12/actions/assign", method="POST", json={"assignee_id": 1, "assignee_type": "server"}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "primary_ip", [PrimaryIP(id=12), BoundPrimaryIP(mock.MagicMock(), dict(id=12))] ) - def test_unassign(self, primary_ips_client, primary_ip, generic_action): - primary_ips_client._client.request.return_value = generic_action + def test_unassign( + self, + request_mock: mock.MagicMock, + primary_ips_client, + primary_ip, + action_response, + ): + request_mock.return_value = action_response action = primary_ips_client.unassign(primary_ip) - primary_ips_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/primary_ips/12/actions/unassign", method="POST" ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "primary_ip", [PrimaryIP(id=12), BoundPrimaryIP(mock.MagicMock(), dict(id=12))] ) - def test_change_dns_ptr(self, primary_ips_client, primary_ip, generic_action): - primary_ips_client._client.request.return_value = generic_action + def test_change_dns_ptr( + self, + request_mock: mock.MagicMock, + primary_ips_client, + primary_ip, + action_response, + ): + request_mock.return_value = action_response action = primary_ips_client.change_dns_ptr( primary_ip, "1.2.3.4", "server02.example.com" ) - primary_ips_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/primary_ips/12/actions/change_dns_ptr", method="POST", json={"ip": "1.2.3.4", "dns_ptr": "server02.example.com"}, ) assert action.id == 1 - assert action.progress == 0 - - def test_actions_get_by_id(self, primary_ips_client, response_get_actions): - primary_ips_client._client.request.return_value = { - "action": response_get_actions["actions"][0] - } - action = primary_ips_client.actions.get_by_id(13) - - primary_ips_client._client.request.assert_called_with( - url="/primary_ips/actions/13", method="GET" - ) - - assert isinstance(action, BoundAction) - assert action._client == primary_ips_client._client.actions - assert action.id == 13 - assert action.command == "assign_primary_ip" - - def test_actions_get_list(self, primary_ips_client, response_get_actions): - primary_ips_client._client.request.return_value = response_get_actions - result = primary_ips_client.actions.get_list() - - primary_ips_client._client.request.assert_called_with( - url="/primary_ips/actions", - method="GET", - params={}, - ) - - actions = result.actions - assert result.meta is not None - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - assert actions[0]._client == primary_ips_client._client.actions - assert actions[0].id == 13 - assert actions[0].command == "assign_primary_ip" - - def test_actions_get_all(self, primary_ips_client, response_get_actions): - primary_ips_client._client.request.return_value = response_get_actions - actions = primary_ips_client.actions.get_all() - - primary_ips_client._client.request.assert_called_with( - url="/primary_ips/actions", - method="GET", - params={"page": 1, "per_page": 50}, - ) - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - assert actions[0]._client == primary_ips_client._client.actions - assert actions[0].id == 13 - assert actions[0].command == "assign_primary_ip" + assert action.progress == 20 diff --git a/tests/unit/server_types/test_client.py b/tests/unit/server_types/test_client.py index 6021a563..4b7e9056 100644 --- a/tests/unit/server_types/test_client.py +++ b/tests/unit/server_types/test_client.py @@ -5,13 +5,14 @@ import pytest +from hcloud import Client from hcloud.server_types import BoundServerType, ServerTypesClient class TestBoundServerType: @pytest.fixture() - def bound_server_type(self, hetzner_client): - return BoundServerType(client=hetzner_client.server_types, data=dict(id=14)) + def bound_server_type(self, client: Client): + return BoundServerType(client=client.server_types, data=dict(id=14)) def test_bound_server_type_init(self, server_type_response): bound_server_type = BoundServerType( @@ -41,15 +42,18 @@ def test_bound_server_type_init(self, server_type_response): class TestServerTypesClient: @pytest.fixture() - def server_types_client(self): - return ServerTypesClient(client=mock.MagicMock()) - - def test_get_by_id(self, server_types_client, server_type_response): - server_types_client._client.request.return_value = server_type_response + def server_types_client(self, client: Client): + return ServerTypesClient(client) + + def test_get_by_id( + self, + request_mock: mock.MagicMock, + server_types_client, + server_type_response, + ): + request_mock.return_value = server_type_response server_type = server_types_client.get_by_id(1) - server_types_client._client.request.assert_called_with( - url="/server_types/1", method="GET" - ) + request_mock.assert_called_with(url="/server_types/1", method="GET") assert server_type._client is server_types_client assert server_type.id == 1 assert server_type.name == "cx11" @@ -57,10 +61,16 @@ def test_get_by_id(self, server_types_client, server_type_response): @pytest.mark.parametrize( "params", [{"name": "cx11", "page": 1, "per_page": 10}, {"name": ""}, {}] ) - def test_get_list(self, server_types_client, two_server_types_response, params): - server_types_client._client.request.return_value = two_server_types_response + def test_get_list( + self, + request_mock: mock.MagicMock, + server_types_client, + two_server_types_response, + params, + ): + request_mock.return_value = two_server_types_response result = server_types_client.get_list(**params) - server_types_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/server_types", method="GET", params=params ) @@ -81,13 +91,19 @@ def test_get_list(self, server_types_client, two_server_types_response, params): assert server_types2.name == "cx21" @pytest.mark.parametrize("params", [{"name": "cx11"}]) - def test_get_all(self, server_types_client, two_server_types_response, params): - server_types_client._client.request.return_value = two_server_types_response + def test_get_all( + self, + request_mock: mock.MagicMock, + server_types_client, + two_server_types_response, + params, + ): + request_mock.return_value = two_server_types_response server_types = server_types_client.get_all(**params) params.update({"page": 1, "per_page": 50}) - server_types_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/server_types", method="GET", params=params ) @@ -104,13 +120,18 @@ def test_get_all(self, server_types_client, two_server_types_response, params): assert server_types2.id == 2 assert server_types2.name == "cx21" - def test_get_by_name(self, server_types_client, one_server_types_response): - server_types_client._client.request.return_value = one_server_types_response + def test_get_by_name( + self, + request_mock: mock.MagicMock, + server_types_client, + one_server_types_response, + ): + request_mock.return_value = one_server_types_response server_type = server_types_client.get_by_name("cx11") params = {"name": "cx11"} - server_types_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/server_types", method="GET", params=params ) diff --git a/tests/unit/servers/conftest.py b/tests/unit/servers/conftest.py index 01649320..caa95a1c 100644 --- a/tests/unit/servers/conftest.py +++ b/tests/unit/servers/conftest.py @@ -708,110 +708,6 @@ def response_full_server(): } -@pytest.fixture() -def response_server_reset_password(): - return { - "action": { - "id": 1, - "command": "reset_password", - "status": "running", - "progress": 0, - "started": "2016-01-30T23:50+00:00", - "finished": None, - "resources": [{"id": 42, "type": "server"}], - "error": {"code": "action_failed", "message": "Action failed"}, - }, - "root_password": "YItygq1v3GYjjMomLaKc", - } - - -@pytest.fixture() -def response_server_enable_rescue(): - return { - "action": { - "id": 1, - "command": "enable_rescue", - "status": "running", - "progress": 0, - "started": "2016-01-30T23:50+00:00", - "finished": None, - "resources": [{"id": 42, "type": "server"}], - "error": {"code": "action_failed", "message": "Action failed"}, - }, - "root_password": "YItygq1v3GYjjMomLaKc", - } - - -@pytest.fixture() -def response_server_create_image(): - return { - "image": { - "id": 4711, - "type": "snapshot", - "status": "creating", - "name": None, - "description": "my image", - "image_size": 2.3, - "disk_size": 10, - "created": "2016-01-30T23:50+00:00", - "created_from": {"id": 1, "name": "Server"}, - "bound_to": None, - "os_flavor": "ubuntu", - "os_version": "16.04", - "rapid_deploy": False, - "protection": {"delete": False}, - "deprecated": "2018-02-28T00:00:00+00:00", - "labels": {}, - }, - "action": { - "id": 1, - "command": "enable_rescue", - "status": "running", - "progress": 0, - "started": "2016-01-30T23:50+00:00", - "finished": None, - "resources": [{"id": 42, "type": "server"}], - "error": {"code": "action_failed", "message": "Action failed"}, - }, - } - - -@pytest.fixture() -def response_server_request_console(): - return { - "wss_url": "wss://console.hetzner.cloud/?server_id=1&token=3db32d15-af2f-459c-8bf8-dee1fd05f49c", - "password": "9MQaTg2VAGI0FIpc10k3UpRXcHj2wQ6x", - "action": { - "id": 1, - "command": "request_console", - "status": "success", - "progress": 0, - "started": "2016-01-30T23:55:00+00:00", - "finished": "2016-01-30T23:56:00+00:00", - "resources": [{"id": 42, "type": "server"}], - "error": {"code": "action_failed", "message": "Action failed"}, - }, - } - - -@pytest.fixture() -def response_get_actions(): - return { - "actions": [ - { - "id": 13, - "command": "start_server", - "status": "success", - "progress": 100, - "started": "2016-01-30T23:55:00+00:00", - "finished": "2016-01-30T23:56:00+00:00", - "resources": [{"id": 42, "type": "server"}], - "error": {"code": "action_failed", "message": "Action failed"}, - } - ] - } - - @pytest.fixture() def response_attach_to_network(): return { diff --git a/tests/unit/servers/test_client.py b/tests/unit/servers/test_client.py index cb69f4f6..b8cf318d 100644 --- a/tests/unit/servers/test_client.py +++ b/tests/unit/servers/test_client.py @@ -4,6 +4,7 @@ import pytest +from hcloud import Client from hcloud.actions import BoundAction from hcloud.datacenters import BoundDatacenter, Datacenter from hcloud.firewalls import BoundFirewall, Firewall @@ -29,8 +30,8 @@ class TestBoundServer: @pytest.fixture() - def bound_server(self, hetzner_client): - return BoundServer(client=hetzner_client.servers, data=dict(id=14)) + def bound_server(self, client: Client): + return BoundServer(client=client.servers, data=dict(id=14)) def test_bound_server_init(self, response_full_server): bound_server = BoundServer( @@ -121,88 +122,49 @@ def test_bound_server_init(self, response_full_server): assert bound_server.placement_group.name == "my Placement Group" assert bound_server.placement_group.complete is True - @pytest.mark.parametrize( - "params", - [ - { - "status": [Server.STATUS_RUNNING], - "sort": "status", - "page": 1, - "per_page": 10, - }, - {}, - ], - ) - def test_get_actions_list( - self, hetzner_client, bound_server, response_get_actions, params - ): - hetzner_client.request.return_value = response_get_actions - result = bound_server.get_actions_list(**params) - hetzner_client.request.assert_called_with( - url="/servers/14/actions", method="GET", params=params - ) - - actions = result.actions - assert result.meta is not None - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - assert actions[0]._client == hetzner_client.actions - assert actions[0].id == 13 - assert actions[0].command == "start_server" - - @pytest.mark.parametrize( - "params", [{"status": [Server.STATUS_RUNNING], "sort": "status"}, {}] - ) - def test_get_actions( - self, hetzner_client, bound_server, response_get_actions, params + def test_update( + self, + request_mock: mock.MagicMock, + client: Client, + bound_server, + response_update_server, ): - hetzner_client.request.return_value = response_get_actions - actions = bound_server.get_actions(**params) - - params.update({"page": 1, "per_page": 50}) - - hetzner_client.request.assert_called_with( - url="/servers/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].id == 13 - assert actions[0].command == "start_server" - - def test_update(self, hetzner_client, bound_server, response_update_server): - hetzner_client.request.return_value = response_update_server + request_mock.return_value = response_update_server server = bound_server.update(name="new-name", labels={}) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/14", method="PUT", json={"name": "new-name", "labels": {}} ) assert server.id == 14 assert server.name == "new-name" - def test_delete(self, hetzner_client, bound_server, generic_action): - hetzner_client.request.return_value = generic_action + def test_delete( + self, + request_mock: mock.MagicMock, + client: Client, + bound_server, + action_response, + ): + request_mock.return_value = action_response action = bound_server.delete() - hetzner_client.request.assert_called_with(url="/servers/14", method="DELETE") + request_mock.assert_called_with(url="/servers/14", method="DELETE") assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 def test_get_metrics( self, - hetzner_client, + request_mock: mock.MagicMock, bound_server: BoundServer, response_get_metrics, ): - hetzner_client.request.return_value = response_get_metrics + request_mock.return_value = response_get_metrics response = bound_server.get_metrics( type=["cpu", "disk"], start="2023-12-14T17:40:00+01:00", end="2023-12-14T17:50:00+01:00", ) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/14/metrics", method="GET", params={ @@ -216,214 +178,326 @@ def test_get_metrics( assert "disk.0.iops.read" in response.metrics.time_series assert len(response.metrics.time_series["disk.0.iops.read"]["values"]) == 3 - def test_power_off(self, hetzner_client, bound_server, generic_action): - hetzner_client.request.return_value = generic_action + def test_power_off( + self, + request_mock: mock.MagicMock, + client: Client, + bound_server, + action_response, + ): + request_mock.return_value = action_response action = bound_server.power_off() - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/14/actions/poweroff", method="POST" ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 - def test_power_on(self, hetzner_client, bound_server, generic_action): - hetzner_client.request.return_value = generic_action + def test_power_on( + self, + request_mock: mock.MagicMock, + client: Client, + bound_server, + action_response, + ): + request_mock.return_value = action_response action = bound_server.power_on() - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/14/actions/poweron", method="POST" ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 - def test_reboot(self, hetzner_client, bound_server, generic_action): - hetzner_client.request.return_value = generic_action + def test_reboot( + self, + request_mock: mock.MagicMock, + client: Client, + bound_server, + action_response, + ): + request_mock.return_value = action_response action = bound_server.reboot() - hetzner_client.request.assert_called_with( - url="/servers/14/actions/reboot", method="POST" - ) + request_mock.assert_called_with(url="/servers/14/actions/reboot", method="POST") assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 - def test_reset(self, hetzner_client, bound_server, generic_action): - hetzner_client.request.return_value = generic_action + def test_reset( + self, + request_mock: mock.MagicMock, + client: Client, + bound_server, + action_response, + ): + request_mock.return_value = action_response action = bound_server.reset() - hetzner_client.request.assert_called_with( - url="/servers/14/actions/reset", method="POST" - ) + request_mock.assert_called_with(url="/servers/14/actions/reset", method="POST") assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 - def test_shutdown(self, hetzner_client, bound_server, generic_action): - hetzner_client.request.return_value = generic_action + def test_shutdown( + self, + request_mock: mock.MagicMock, + client: Client, + bound_server, + action_response, + ): + request_mock.return_value = action_response action = bound_server.shutdown() - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/14/actions/shutdown", method="POST" ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 def test_reset_password( - self, hetzner_client, bound_server, response_server_reset_password + self, + request_mock: mock.MagicMock, + client: Client, + bound_server, + action_response, ): - hetzner_client.request.return_value = response_server_reset_password + request_mock.return_value = { + **action_response, + "root_password": "YItygq1v3GYjjMomLaKc", + } response = bound_server.reset_password() - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/14/actions/reset_password", method="POST" ) assert response.action.id == 1 - assert response.action.progress == 0 + assert response.action.progress == 20 assert response.root_password == "YItygq1v3GYjjMomLaKc" - def test_change_type(self, hetzner_client, bound_server, generic_action): - hetzner_client.request.return_value = generic_action + def test_change_type( + self, + request_mock: mock.MagicMock, + client: Client, + bound_server, + action_response, + ): + request_mock.return_value = action_response action = bound_server.change_type(ServerType(name="cx11"), upgrade_disk=True) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/14/actions/change_type", method="POST", json={"server_type": "cx11", "upgrade_disk": True}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 def test_enable_rescue( - self, hetzner_client, bound_server, response_server_enable_rescue + self, + request_mock: mock.MagicMock, + client: Client, + bound_server, + action_response, ): - hetzner_client.request.return_value = response_server_enable_rescue + request_mock.return_value = { + **action_response, + "root_password": "YItygq1v3GYjjMomLaKc", + } response = bound_server.enable_rescue(type="linux64") - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/14/actions/enable_rescue", method="POST", json={"type": "linux64"}, ) assert response.action.id == 1 - assert response.action.progress == 0 + assert response.action.progress == 20 assert response.root_password == "YItygq1v3GYjjMomLaKc" - def test_disable_rescue(self, hetzner_client, bound_server, generic_action): - hetzner_client.request.return_value = generic_action + def test_disable_rescue( + self, + request_mock: mock.MagicMock, + client: Client, + bound_server, + action_response, + ): + request_mock.return_value = action_response action = bound_server.disable_rescue() - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/14/actions/disable_rescue", method="POST" ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 def test_create_image( - self, hetzner_client, bound_server, response_server_create_image + self, + request_mock: mock.MagicMock, + bound_server, + action_response, ): - hetzner_client.request.return_value = response_server_create_image + request_mock.return_value = { + **action_response, + "image": { + "id": 4711, + "type": "snapshot", + "description": "my image", + }, + } response = bound_server.create_image(description="my image", type="snapshot") - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/14/actions/create_image", method="POST", json={"description": "my image", "type": "snapshot"}, ) assert response.action.id == 1 - assert response.action.progress == 0 + assert response.action.progress == 20 assert response.image.description == "my image" - def test_rebuild(self, hetzner_client, bound_server, generic_action): - hetzner_client.request.return_value = generic_action + def test_rebuild( + self, + request_mock: mock.MagicMock, + client: Client, + bound_server, + action_response, + ): + request_mock.return_value = action_response response = bound_server.rebuild( Image(name="ubuntu-20.04"), return_response=True, ) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/14/actions/rebuild", method="POST", json={"image": "ubuntu-20.04"}, ) assert response.action.id == 1 - assert response.action.progress == 0 + assert response.action.progress == 20 assert response.root_password is None or isinstance(response.root_password, str) - def test_enable_backup(self, hetzner_client, bound_server, generic_action): - hetzner_client.request.return_value = generic_action + def test_enable_backup( + self, + request_mock: mock.MagicMock, + client: Client, + bound_server, + action_response, + ): + request_mock.return_value = action_response action = bound_server.enable_backup() - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/14/actions/enable_backup", method="POST" ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 - def test_disable_backup(self, hetzner_client, bound_server, generic_action): - hetzner_client.request.return_value = generic_action + def test_disable_backup( + self, + request_mock: mock.MagicMock, + client: Client, + bound_server, + action_response, + ): + request_mock.return_value = action_response action = bound_server.disable_backup() - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/14/actions/disable_backup", method="POST" ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 - def test_attach_iso(self, hetzner_client, bound_server, generic_action): - hetzner_client.request.return_value = generic_action + def test_attach_iso( + self, + request_mock: mock.MagicMock, + client: Client, + bound_server, + action_response, + ): + request_mock.return_value = action_response action = bound_server.attach_iso(Iso(name="FreeBSD-11.0-RELEASE-amd64-dvd1")) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/14/actions/attach_iso", method="POST", json={"iso": "FreeBSD-11.0-RELEASE-amd64-dvd1"}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 - def test_detach_iso(self, hetzner_client, bound_server, generic_action): - hetzner_client.request.return_value = generic_action + def test_detach_iso( + self, + request_mock: mock.MagicMock, + client: Client, + bound_server, + action_response, + ): + request_mock.return_value = action_response action = bound_server.detach_iso() - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/14/actions/detach_iso", method="POST" ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 - def test_change_dns_ptr(self, hetzner_client, bound_server, generic_action): - hetzner_client.request.return_value = generic_action + def test_change_dns_ptr( + self, + request_mock: mock.MagicMock, + client: Client, + bound_server, + action_response, + ): + request_mock.return_value = action_response action = bound_server.change_dns_ptr("1.2.3.4", "example.com") - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/14/actions/change_dns_ptr", method="POST", json={"ip": "1.2.3.4", "dns_ptr": "example.com"}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 - def test_change_protection(self, hetzner_client, bound_server, generic_action): - hetzner_client.request.return_value = generic_action + def test_change_protection( + self, + request_mock: mock.MagicMock, + client: Client, + bound_server, + action_response, + ): + request_mock.return_value = action_response action = bound_server.change_protection(True, True) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/14/actions/change_protection", method="POST", json={"delete": True, "rebuild": True}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 def test_request_console( - self, hetzner_client, bound_server, response_server_request_console + self, + request_mock: mock.MagicMock, + client: Client, + bound_server, + action_response, ): - hetzner_client.request.return_value = response_server_request_console + request_mock.return_value = { + **action_response, + "wss_url": "wss://console.hetzner.cloud/?server_id=1&token=3db32d15-af2f-459c-8bf8-dee1fd05f49c", + "password": "9MQaTg2VAGI0FIpc10k3UpRXcHj2wQ6x", + } response = bound_server.request_console() - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/14/actions/request_console", method="POST" ) assert response.action.id == 1 - assert response.action.progress == 0 + assert response.action.progress == 20 assert ( response.wss_url == "wss://console.hetzner.cloud/?server_id=1&token=3db32d15-af2f-459c-8bf8-dee1fd05f49c" @@ -434,13 +508,19 @@ def test_request_console( "network", [Network(id=4711), BoundNetwork(mock.MagicMock(), dict(id=4711))] ) def test_attach_to_network( - self, hetzner_client, bound_server, network, response_attach_to_network + self, + request_mock: mock.MagicMock, + client: Client, + bound_server, + network, + action_response, ): - hetzner_client.request.return_value = response_attach_to_network + request_mock.return_value = action_response + action = bound_server.attach_to_network( network, "10.0.1.1", ["10.0.1.2", "10.0.1.3"] ) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/14/actions/attach_to_network", method="POST", json={ @@ -451,44 +531,54 @@ def test_attach_to_network( ) assert action.id == 1 - assert action.progress == 0 - assert action.command == "attach_to_network" + assert action.progress == 20 + assert action.command == "command" @pytest.mark.parametrize( "network", [Network(id=4711), BoundNetwork(mock.MagicMock(), dict(id=4711))] ) def test_detach_from_network( - self, hetzner_client, bound_server, network, response_detach_from_network + self, + request_mock: mock.MagicMock, + client: Client, + bound_server, + network, + action_response, ): - hetzner_client.request.return_value = response_detach_from_network + request_mock.return_value = action_response action = bound_server.detach_from_network(network) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/14/actions/detach_from_network", method="POST", json={"network": 4711}, ) assert action.id == 1 - assert action.progress == 0 - assert action.command == "detach_from_network" + assert action.progress == 20 + assert action.command == "command" @pytest.mark.parametrize( "network", [Network(id=4711), BoundNetwork(mock.MagicMock(), dict(id=4711))] ) def test_change_alias_ips( - self, hetzner_client, bound_server, network, response_change_alias_ips + self, + request_mock: mock.MagicMock, + client: Client, + bound_server, + network, + action_response, ): - hetzner_client.request.return_value = response_change_alias_ips + request_mock.return_value = action_response action = bound_server.change_alias_ips(network, ["10.0.1.2", "10.0.1.3"]) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/14/actions/change_alias_ips", method="POST", json={"network": 4711, "alias_ips": ["10.0.1.2", "10.0.1.3"]}, ) assert action.id == 1 - assert action.progress == 0 - assert action.command == "change_alias_ips" + assert action.progress == 20 + assert action.command == "command" @pytest.mark.parametrize( "placement_group", @@ -496,29 +586,32 @@ def test_change_alias_ips( ) def test_add_to_placement_group( self, - hetzner_client, + request_mock: mock.MagicMock, bound_server, placement_group, - response_add_to_placement_group, + action_response, ): - hetzner_client.request.return_value = response_add_to_placement_group + request_mock.return_value = action_response action = bound_server.add_to_placement_group(placement_group) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/14/actions/add_to_placement_group", method="POST", json={"placement_group": 897}, ) - assert action.id == 13 - assert action.progress == 0 - assert action.command == "add_to_placement_group" + assert action.id == 1 + assert action.progress == 20 + assert action.command == "command" def test_remove_from_placement_group( - self, hetzner_client, bound_server, response_remove_from_placement_group + self, + request_mock: mock.MagicMock, + bound_server, + response_remove_from_placement_group, ): - hetzner_client.request.return_value = response_remove_from_placement_group + request_mock.return_value = response_remove_from_placement_group action = bound_server.remove_from_placement_group() - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/14/actions/remove_from_placement_group", method="POST" ) @@ -529,15 +622,15 @@ def test_remove_from_placement_group( class TestServersClient: @pytest.fixture() - def servers_client(self): - return ServersClient(client=mock.MagicMock()) + def servers_client(self, client: Client): + return ServersClient(client) - def test_get_by_id(self, servers_client, response_simple_server): - servers_client._client.request.return_value = response_simple_server + def test_get_by_id( + self, request_mock: mock.MagicMock, servers_client, response_simple_server + ): + request_mock.return_value = response_simple_server bound_server = servers_client.get_by_id(1) - servers_client._client.request.assert_called_with( - url="/servers/1", method="GET" - ) + request_mock.assert_called_with(url="/servers/1", method="GET") assert bound_server._client is servers_client assert bound_server.id == 1 assert bound_server.name == "my-server" @@ -550,12 +643,16 @@ def test_get_by_id(self, servers_client, response_simple_server): {}, ], ) - def test_get_list(self, servers_client, response_simple_servers, params): - servers_client._client.request.return_value = response_simple_servers + def test_get_list( + self, + request_mock: mock.MagicMock, + servers_client, + response_simple_servers, + params, + ): + request_mock.return_value = response_simple_servers result = servers_client.get_list(**params) - servers_client._client.request.assert_called_with( - url="/servers", method="GET", params=params - ) + request_mock.assert_called_with(url="/servers", method="GET", params=params) bound_servers = result.servers assert result.meta is not None @@ -576,15 +673,19 @@ def test_get_list(self, servers_client, response_simple_servers, params): @pytest.mark.parametrize( "params", [{"name": "server1", "label_selector": "label1"}, {}] ) - def test_get_all(self, servers_client, response_simple_servers, params): - servers_client._client.request.return_value = response_simple_servers + def test_get_all( + self, + request_mock: mock.MagicMock, + servers_client, + response_simple_servers, + params, + ): + request_mock.return_value = response_simple_servers bound_servers = servers_client.get_all(**params) params.update({"page": 1, "per_page": 50}) - servers_client._client.request.assert_called_with( - url="/servers", method="GET", params=params - ) + request_mock.assert_called_with(url="/servers", method="GET", params=params) assert len(bound_servers) == 2 @@ -599,31 +700,34 @@ def test_get_all(self, servers_client, response_simple_servers, params): assert bound_server2.id == 2 assert bound_server2.name == "my-server2" - def test_get_by_name(self, servers_client, response_simple_servers): - servers_client._client.request.return_value = response_simple_servers + def test_get_by_name( + self, request_mock: mock.MagicMock, servers_client, response_simple_servers + ): + request_mock.return_value = response_simple_servers bound_server = servers_client.get_by_name("my-server") params = {"name": "my-server"} - servers_client._client.request.assert_called_with( - url="/servers", method="GET", params=params - ) + request_mock.assert_called_with(url="/servers", method="GET", params=params) assert bound_server._client is servers_client assert bound_server.id == 1 assert bound_server.name == "my-server" def test_create_with_datacenter( - self, servers_client, response_create_simple_server + self, + request_mock: mock.MagicMock, + servers_client, + response_create_simple_server, ): - servers_client._client.request.return_value = response_create_simple_server + request_mock.return_value = response_create_simple_server response = servers_client.create( "my-server", server_type=ServerType(name="cx11"), image=Image(id=4711), datacenter=Datacenter(id=1), ) - servers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/servers", method="POST", json={ @@ -647,15 +751,20 @@ def test_create_with_datacenter( assert bound_action.id == 1 assert bound_action.command == "create_server" - def test_create_with_location(self, servers_client, response_create_simple_server): - servers_client._client.request.return_value = response_create_simple_server + def test_create_with_location( + self, + request_mock: mock.MagicMock, + servers_client, + response_create_simple_server, + ): + request_mock.return_value = response_create_simple_server response = servers_client.create( "my-server", server_type=ServerType(name="cx11"), image=Image(name="ubuntu-20.04"), location=Location(name="fsn1"), ) - servers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/servers", method="POST", json={ @@ -679,8 +788,13 @@ def test_create_with_location(self, servers_client, response_create_simple_serve assert bound_action.id == 1 assert bound_action.command == "create_server" - def test_create_with_volumes(self, servers_client, response_create_simple_server): - servers_client._client.request.return_value = response_create_simple_server + def test_create_with_volumes( + self, + request_mock: mock.MagicMock, + servers_client, + response_create_simple_server, + ): + request_mock.return_value = response_create_simple_server volumes = [Volume(id=1), BoundVolume(mock.MagicMock(), dict(id=2))] response = servers_client.create( "my-server", @@ -689,7 +803,7 @@ def test_create_with_volumes(self, servers_client, response_create_simple_server volumes=volumes, start_after_create=False, ) - servers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/servers", method="POST", json={ @@ -719,8 +833,13 @@ def test_create_with_volumes(self, servers_client, response_create_simple_server assert next_actions[0].id == 13 - def test_create_with_networks(self, servers_client, response_create_simple_server): - servers_client._client.request.return_value = response_create_simple_server + def test_create_with_networks( + self, + request_mock: mock.MagicMock, + servers_client, + response_create_simple_server, + ): + request_mock.return_value = response_create_simple_server networks = [Network(id=1), BoundNetwork(mock.MagicMock(), dict(id=2))] response = servers_client.create( "my-server", @@ -729,7 +848,7 @@ def test_create_with_networks(self, servers_client, response_create_simple_serve networks=networks, start_after_create=False, ) - servers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/servers", method="POST", json={ @@ -759,8 +878,13 @@ def test_create_with_networks(self, servers_client, response_create_simple_serve assert next_actions[0].id == 13 - def test_create_with_firewalls(self, servers_client, response_create_simple_server): - servers_client._client.request.return_value = response_create_simple_server + def test_create_with_firewalls( + self, + request_mock: mock.MagicMock, + servers_client, + response_create_simple_server, + ): + request_mock.return_value = response_create_simple_server firewalls = [Firewall(id=1), BoundFirewall(mock.MagicMock(), dict(id=2))] response = servers_client.create( "my-server", @@ -769,7 +893,7 @@ def test_create_with_firewalls(self, servers_client, response_create_simple_serv firewalls=firewalls, start_after_create=False, ) - servers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/servers", method="POST", json={ @@ -800,9 +924,12 @@ def test_create_with_firewalls(self, servers_client, response_create_simple_serv assert next_actions[0].id == 13 def test_create_with_placement_group( - self, servers_client, response_create_simple_server + self, + request_mock: mock.MagicMock, + servers_client, + response_create_simple_server, ): - servers_client._client.request.return_value = response_create_simple_server + request_mock.return_value = response_create_simple_server placement_group = PlacementGroup(id=1) response = servers_client.create( "my-server", @@ -812,7 +939,7 @@ def test_create_with_placement_group( placement_group=placement_group, ) - servers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/servers", method="POST", json={ @@ -845,30 +972,16 @@ def test_create_with_placement_group( @pytest.mark.parametrize( "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))] ) - def test_get_actions_list(self, servers_client, server, response_get_actions): - servers_client._client.request.return_value = response_get_actions - result = servers_client.get_actions_list(server) - servers_client._client.request.assert_called_with( - url="/servers/1/actions", method="GET", params={} - ) - - actions = result.actions - assert result.meta is not None - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - - assert actions[0]._client == servers_client._client.actions - assert actions[0].id == 13 - assert actions[0].command == "start_server" - - @pytest.mark.parametrize( - "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))] - ) - def test_update(self, servers_client, server, response_update_server): - servers_client._client.request.return_value = response_update_server + def test_update( + self, + request_mock: mock.MagicMock, + servers_client, + server, + response_update_server, + ): + request_mock.return_value = response_update_server server = servers_client.update(server, name="new-name", labels={}) - servers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/1", method="PUT", json={"name": "new-name", "labels": {}} ) @@ -878,180 +991,253 @@ def test_update(self, servers_client, server, response_update_server): @pytest.mark.parametrize( "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))] ) - def test_delete(self, servers_client, server, generic_action): - servers_client._client.request.return_value = generic_action + def test_delete( + self, + request_mock: mock.MagicMock, + servers_client, + server, + action_response, + ): + request_mock.return_value = action_response action = servers_client.delete(server) - servers_client._client.request.assert_called_with( - url="/servers/1", method="DELETE" - ) + request_mock.assert_called_with(url="/servers/1", method="DELETE") assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))] ) - def test_power_off(self, servers_client, server, generic_action): - servers_client._client.request.return_value = generic_action + def test_power_off( + self, + request_mock: mock.MagicMock, + servers_client, + server, + action_response, + ): + request_mock.return_value = action_response action = servers_client.power_off(server) - servers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/1/actions/poweroff", method="POST" ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))] ) - def test_power_on(self, servers_client, server, generic_action): - servers_client._client.request.return_value = generic_action + def test_power_on( + self, + request_mock: mock.MagicMock, + servers_client, + server, + action_response, + ): + request_mock.return_value = action_response action = servers_client.power_on(server) - servers_client._client.request.assert_called_with( - url="/servers/1/actions/poweron", method="POST" - ) + request_mock.assert_called_with(url="/servers/1/actions/poweron", method="POST") assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))] ) - def test_reboot(self, servers_client, server, generic_action): - servers_client._client.request.return_value = generic_action + def test_reboot( + self, + request_mock: mock.MagicMock, + servers_client, + server, + action_response, + ): + request_mock.return_value = action_response action = servers_client.reboot(server) - servers_client._client.request.assert_called_with( - url="/servers/1/actions/reboot", method="POST" - ) + request_mock.assert_called_with(url="/servers/1/actions/reboot", method="POST") assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))] ) - def test_reset(self, servers_client, server, generic_action): - servers_client._client.request.return_value = generic_action + def test_reset( + self, + request_mock: mock.MagicMock, + servers_client, + server, + action_response, + ): + request_mock.return_value = action_response action = servers_client.reset(server) - servers_client._client.request.assert_called_with( - url="/servers/1/actions/reset", method="POST" - ) + request_mock.assert_called_with(url="/servers/1/actions/reset", method="POST") assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))] ) - def test_shutdown(self, servers_client, server, generic_action): - servers_client._client.request.return_value = generic_action + def test_shutdown( + self, + request_mock: mock.MagicMock, + servers_client, + server, + action_response, + ): + request_mock.return_value = action_response action = servers_client.shutdown(server) - servers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/1/actions/shutdown", method="POST" ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))] ) def test_reset_password( - self, servers_client, server, response_server_reset_password + self, + request_mock: mock.MagicMock, + servers_client, + server, + action_response, ): - servers_client._client.request.return_value = response_server_reset_password + request_mock.return_value = { + **action_response, + "root_password": "YItygq1v3GYjjMomLaKc", + } response = servers_client.reset_password(server) - servers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/1/actions/reset_password", method="POST" ) assert response.action.id == 1 - assert response.action.progress == 0 + assert response.action.progress == 20 assert response.root_password == "YItygq1v3GYjjMomLaKc" @pytest.mark.parametrize( "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))] ) def test_change_type_with_server_type_name( - self, servers_client, server, generic_action + self, + request_mock: mock.MagicMock, + servers_client, + server, + action_response, ): - servers_client._client.request.return_value = generic_action + request_mock.return_value = action_response action = servers_client.change_type( server, ServerType(name="cx11"), upgrade_disk=True ) - servers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/1/actions/change_type", method="POST", json={"server_type": "cx11", "upgrade_disk": True}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))] ) def test_change_type_with_server_type_id( - self, servers_client, server, generic_action + self, + request_mock: mock.MagicMock, + servers_client, + server, + action_response, ): - servers_client._client.request.return_value = generic_action + request_mock.return_value = action_response action = servers_client.change_type(server, ServerType(id=1), upgrade_disk=True) - servers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/1/actions/change_type", method="POST", json={"server_type": 1, "upgrade_disk": True}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))] ) - def test_change_type_with_blank_server_type(self, servers_client, server): + def test_change_type_with_blank_server_type( + self, request_mock: mock.MagicMock, servers_client, server + ): with pytest.raises(ValueError) as e: servers_client.change_type(server, ServerType(), upgrade_disk=True) assert str(e.value) == "id or name must be set" - servers_client._client.request.assert_not_called() + request_mock.assert_not_called() @pytest.mark.parametrize( "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))] ) - def test_enable_rescue(self, servers_client, server, response_server_enable_rescue): - servers_client._client.request.return_value = response_server_enable_rescue + def test_enable_rescue( + self, + request_mock: mock.MagicMock, + servers_client, + server, + action_response, + ): + request_mock.return_value = { + **action_response, + "root_password": "YItygq1v3GYjjMomLaKc", + } response = servers_client.enable_rescue(server, "linux64", [2323]) - servers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/1/actions/enable_rescue", method="POST", json={"type": "linux64", "ssh_keys": [2323]}, ) assert response.action.id == 1 - assert response.action.progress == 0 + assert response.action.progress == 20 assert response.root_password == "YItygq1v3GYjjMomLaKc" @pytest.mark.parametrize( "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))] ) - def test_disable_rescue(self, servers_client, server, generic_action): - servers_client._client.request.return_value = generic_action + def test_disable_rescue( + self, + request_mock: mock.MagicMock, + servers_client, + server, + action_response, + ): + request_mock.return_value = action_response action = servers_client.disable_rescue(server) - servers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/1/actions/disable_rescue", method="POST" ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))] ) - def test_create_image(self, servers_client, server, response_server_create_image): - servers_client._client.request.return_value = response_server_create_image + def test_create_image( + self, + request_mock: mock.MagicMock, + servers_client, + server, + action_response, + ): + request_mock.return_value = { + **action_response, + "image": { + "id": 4711, + "type": "snapshot", + "description": "my image", + }, + } response = servers_client.create_image( server, description="my image", type="snapshot", labels={"key": "value"} ) - servers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/1/actions/create_image", method="POST", json={ @@ -1062,129 +1248,179 @@ def test_create_image(self, servers_client, server, response_server_create_image ) assert response.action.id == 1 - assert response.action.progress == 0 + assert response.action.progress == 20 assert response.image.description == "my image" @pytest.mark.parametrize( "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))] ) - def test_rebuild(self, servers_client, server, generic_action): - servers_client._client.request.return_value = generic_action + def test_rebuild( + self, + request_mock: mock.MagicMock, + servers_client, + server, + action_response, + ): + request_mock.return_value = action_response response = servers_client.rebuild( server, Image(name="ubuntu-20.04"), return_response=True, ) - servers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/1/actions/rebuild", method="POST", json={"image": "ubuntu-20.04"}, ) assert response.action.id == 1 - assert response.action.progress == 0 + assert response.action.progress == 20 assert response.root_password is None or isinstance(response.root_password, str) @pytest.mark.parametrize( "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))] ) - def test_enable_backup(self, servers_client, server, generic_action): - servers_client._client.request.return_value = generic_action + def test_enable_backup( + self, + request_mock: mock.MagicMock, + servers_client, + server, + action_response, + ): + request_mock.return_value = action_response action = servers_client.enable_backup(server) - servers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/1/actions/enable_backup", method="POST" ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))] ) - def test_disable_backup(self, servers_client, server, generic_action): - servers_client._client.request.return_value = generic_action + def test_disable_backup( + self, + request_mock: mock.MagicMock, + servers_client, + server, + action_response, + ): + request_mock.return_value = action_response action = servers_client.disable_backup(server) - servers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/1/actions/disable_backup", method="POST" ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))] ) - def test_attach_iso(self, servers_client, server, generic_action): - servers_client._client.request.return_value = generic_action + def test_attach_iso( + self, + request_mock: mock.MagicMock, + servers_client, + server, + action_response, + ): + request_mock.return_value = action_response action = servers_client.attach_iso( server, Iso(name="FreeBSD-11.0-RELEASE-amd64-dvd1") ) - servers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/1/actions/attach_iso", method="POST", json={"iso": "FreeBSD-11.0-RELEASE-amd64-dvd1"}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))] ) - def test_detach_iso(self, servers_client, server, generic_action): - servers_client._client.request.return_value = generic_action + def test_detach_iso( + self, + request_mock: mock.MagicMock, + servers_client, + server, + action_response, + ): + request_mock.return_value = action_response action = servers_client.detach_iso(server) - servers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/1/actions/detach_iso", method="POST" ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))] ) - def test_change_dns_ptr(self, servers_client, server, generic_action): - servers_client._client.request.return_value = generic_action + def test_change_dns_ptr( + self, + request_mock: mock.MagicMock, + servers_client, + server, + action_response, + ): + request_mock.return_value = action_response action = servers_client.change_dns_ptr(server, "1.2.3.4", "example.com") - servers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/1/actions/change_dns_ptr", method="POST", json={"ip": "1.2.3.4", "dns_ptr": "example.com"}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))] ) - def test_change_protection(self, servers_client, server, generic_action): - servers_client._client.request.return_value = generic_action + def test_change_protection( + self, + request_mock: mock.MagicMock, + servers_client, + server, + action_response, + ): + request_mock.return_value = action_response action = servers_client.change_protection(server, True, True) - servers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/1/actions/change_protection", method="POST", json={"delete": True, "rebuild": True}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))] ) def test_request_console( - self, servers_client, server, response_server_request_console + self, + request_mock: mock.MagicMock, + servers_client, + server, + action_response, ): - servers_client._client.request.return_value = response_server_request_console + request_mock.return_value = { + **action_response, + "wss_url": "wss://console.hetzner.cloud/?server_id=1&token=3db32d15-af2f-459c-8bf8-dee1fd05f49c", + "password": "9MQaTg2VAGI0FIpc10k3UpRXcHj2wQ6x", + } response = servers_client.request_console(server) - servers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/1/actions/request_console", method="POST" ) assert response.action.id == 1 - assert response.action.progress == 0 + assert response.action.progress == 20 assert ( response.wss_url == "wss://console.hetzner.cloud/?server_id=1&token=3db32d15-af2f-459c-8bf8-dee1fd05f49c" @@ -1198,13 +1434,18 @@ def test_request_console( "network", [Network(id=4711), BoundNetwork(mock.MagicMock(), dict(id=4711))] ) def test_attach_to_network( - self, servers_client, server, network, response_attach_to_network + self, + request_mock: mock.MagicMock, + servers_client, + server, + network, + action_response, ): - servers_client._client.request.return_value = response_attach_to_network + request_mock.return_value = action_response action = servers_client.attach_to_network( server, network, "10.0.1.1", ["10.0.1.2", "10.0.1.3"] ) - servers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/1/actions/attach_to_network", method="POST", json={ @@ -1215,8 +1456,8 @@ def test_attach_to_network( ) assert action.id == 1 - assert action.progress == 0 - assert action.command == "attach_to_network" + assert action.progress == 20 + assert action.command == "command" @pytest.mark.parametrize( "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))] @@ -1225,19 +1466,24 @@ def test_attach_to_network( "network", [Network(id=4711), BoundNetwork(mock.MagicMock(), dict(id=4711))] ) def test_detach_from_network( - self, servers_client, server, network, response_detach_from_network + self, + request_mock: mock.MagicMock, + servers_client, + server, + network, + action_response, ): - servers_client._client.request.return_value = response_detach_from_network + request_mock.return_value = action_response action = servers_client.detach_from_network(server, network) - servers_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/servers/1/actions/detach_from_network", method="POST", json={"network": 4711}, ) assert action.id == 1 - assert action.progress == 0 - assert action.command == "detach_from_network" + assert action.progress == 20 + assert action.command == "command" @pytest.mark.parametrize( "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))] @@ -1246,68 +1492,24 @@ def test_detach_from_network( "network", [Network(id=4711), BoundNetwork(mock.MagicMock(), dict(id=4711))] ) def test_change_alias_ips( - self, servers_client, server, network, response_change_alias_ips + self, + request_mock: mock.MagicMock, + servers_client, + server, + network, + action_response, ): - servers_client._client.request.return_value = response_change_alias_ips + request_mock.return_value = action_response action = servers_client.change_alias_ips( server, network, ["10.0.1.2", "10.0.1.3"] ) - servers_client._client.request.assert_called_with( + + request_mock.assert_called_with( url="/servers/1/actions/change_alias_ips", method="POST", json={"network": 4711, "alias_ips": ["10.0.1.2", "10.0.1.3"]}, ) assert action.id == 1 - assert action.progress == 0 - assert action.command == "change_alias_ips" - - def test_actions_get_by_id(self, servers_client, response_get_actions): - servers_client._client.request.return_value = { - "action": response_get_actions["actions"][0] - } - action = servers_client.actions.get_by_id(13) - - servers_client._client.request.assert_called_with( - url="/servers/actions/13", method="GET" - ) - - assert isinstance(action, BoundAction) - assert action._client == servers_client._client.actions - assert action.id == 13 - assert action.command == "start_server" - - def test_actions_get_list(self, servers_client, response_get_actions): - servers_client._client.request.return_value = response_get_actions - result = servers_client.actions.get_list() - - servers_client._client.request.assert_called_with( - url="/servers/actions", - method="GET", - params={}, - ) - - actions = result.actions - assert result.meta is not None - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - assert actions[0]._client == servers_client._client.actions - assert actions[0].id == 13 - assert actions[0].command == "start_server" - - def test_actions_get_all(self, servers_client, response_get_actions): - servers_client._client.request.return_value = response_get_actions - actions = servers_client.actions.get_all() - - servers_client._client.request.assert_called_with( - url="/servers/actions", - method="GET", - params={"page": 1, "per_page": 50}, - ) - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - assert actions[0]._client == servers_client._client.actions - assert actions[0].id == 13 - assert actions[0].command == "start_server" + assert action.progress == 20 + assert action.command == "command" diff --git a/tests/unit/ssh_keys/test_client.py b/tests/unit/ssh_keys/test_client.py index 8a64a89f..9d061ff8 100644 --- a/tests/unit/ssh_keys/test_client.py +++ b/tests/unit/ssh_keys/test_client.py @@ -4,13 +4,14 @@ import pytest +from hcloud import Client from hcloud.ssh_keys import BoundSSHKey, SSHKey, SSHKeysClient class TestBoundSSHKey: @pytest.fixture() - def bound_ssh_key(self, hetzner_client): - return BoundSSHKey(client=hetzner_client.ssh_keys, data=dict(id=14)) + def bound_ssh_key(self, client: Client): + return BoundSSHKey(client=client.ssh_keys, data=dict(id=14)) def test_bound_ssh_key_init(self, ssh_key_response): bound_ssh_key = BoundSSHKey( @@ -25,35 +26,47 @@ def test_bound_ssh_key_init(self, ssh_key_response): ) assert bound_ssh_key.public_key == "ssh-rsa AAAjjk76kgf...Xt" - def test_update(self, hetzner_client, bound_ssh_key, response_update_ssh_key): - hetzner_client.request.return_value = response_update_ssh_key + def test_update( + self, + request_mock: mock.MagicMock, + client: Client, + bound_ssh_key, + response_update_ssh_key, + ): + request_mock.return_value = response_update_ssh_key ssh_key = bound_ssh_key.update(name="New name") - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/ssh_keys/14", method="PUT", json={"name": "New name"} ) assert ssh_key.id == 2323 assert ssh_key.name == "New name" - def test_delete(self, hetzner_client, bound_ssh_key, generic_action): - hetzner_client.request.return_value = generic_action + def test_delete( + self, + request_mock: mock.MagicMock, + client: Client, + bound_ssh_key, + action_response, + ): + request_mock.return_value = action_response delete_success = bound_ssh_key.delete() - hetzner_client.request.assert_called_with(url="/ssh_keys/14", method="DELETE") + request_mock.assert_called_with(url="/ssh_keys/14", method="DELETE") assert delete_success is True class TestSSHKeysClient: @pytest.fixture() - def ssh_keys_client(self): - return SSHKeysClient(client=mock.MagicMock()) + def ssh_keys_client(self, client: Client): + return SSHKeysClient(client) - def test_get_by_id(self, ssh_keys_client, ssh_key_response): - ssh_keys_client._client.request.return_value = ssh_key_response + def test_get_by_id( + self, request_mock: mock.MagicMock, ssh_keys_client, ssh_key_response + ): + request_mock.return_value = ssh_key_response ssh_key = ssh_keys_client.get_by_id(1) - ssh_keys_client._client.request.assert_called_with( - url="/ssh_keys/1", method="GET" - ) + request_mock.assert_called_with(url="/ssh_keys/1", method="GET") assert ssh_key._client is ssh_keys_client assert ssh_key.id == 2323 assert ssh_key.name == "My ssh key" @@ -72,12 +85,16 @@ def test_get_by_id(self, ssh_keys_client, ssh_key_response): {}, ], ) - def test_get_list(self, ssh_keys_client, two_ssh_keys_response, params): - ssh_keys_client._client.request.return_value = two_ssh_keys_response + def test_get_list( + self, + request_mock: mock.MagicMock, + ssh_keys_client, + two_ssh_keys_response, + params, + ): + request_mock.return_value = two_ssh_keys_response result = ssh_keys_client.get_list(**params) - ssh_keys_client._client.request.assert_called_with( - url="/ssh_keys", method="GET", params=params - ) + request_mock.assert_called_with(url="/ssh_keys", method="GET", params=params) ssh_keys = result.ssh_keys assert len(ssh_keys) == 2 @@ -96,14 +113,18 @@ def test_get_list(self, ssh_keys_client, two_ssh_keys_response, params): @pytest.mark.parametrize( "params", [{"name": "My ssh key", "label_selector": "label1"}, {}] ) - def test_get_all(self, ssh_keys_client, two_ssh_keys_response, params): - ssh_keys_client._client.request.return_value = two_ssh_keys_response + def test_get_all( + self, + request_mock: mock.MagicMock, + ssh_keys_client, + two_ssh_keys_response, + params, + ): + request_mock.return_value = two_ssh_keys_response ssh_keys = ssh_keys_client.get_all(**params) params.update({"page": 1, "per_page": 50}) - ssh_keys_client._client.request.assert_called_with( - url="/ssh_keys", method="GET", params=params - ) + request_mock.assert_called_with(url="/ssh_keys", method="GET", params=params) assert len(ssh_keys) == 2 @@ -118,40 +139,42 @@ def test_get_all(self, ssh_keys_client, two_ssh_keys_response, params): assert ssh_keys2.id == 2324 assert ssh_keys2.name == "SSH-Key" - def test_get_by_name(self, ssh_keys_client, one_ssh_keys_response): - ssh_keys_client._client.request.return_value = one_ssh_keys_response + def test_get_by_name( + self, request_mock: mock.MagicMock, ssh_keys_client, one_ssh_keys_response + ): + request_mock.return_value = one_ssh_keys_response ssh_keys = ssh_keys_client.get_by_name("SSH-Key") params = {"name": "SSH-Key"} - ssh_keys_client._client.request.assert_called_with( - url="/ssh_keys", method="GET", params=params - ) + request_mock.assert_called_with(url="/ssh_keys", method="GET", params=params) assert ssh_keys._client is ssh_keys_client assert ssh_keys.id == 2323 assert ssh_keys.name == "SSH-Key" - def test_get_by_fingerprint(self, ssh_keys_client, one_ssh_keys_response): - ssh_keys_client._client.request.return_value = one_ssh_keys_response + def test_get_by_fingerprint( + self, request_mock: mock.MagicMock, ssh_keys_client, one_ssh_keys_response + ): + request_mock.return_value = one_ssh_keys_response ssh_keys = ssh_keys_client.get_by_fingerprint( "b7:2f:30:a0:2f:6c:58:6c:21:04:58:61:ba:06:3b:2f" ) params = {"fingerprint": "b7:2f:30:a0:2f:6c:58:6c:21:04:58:61:ba:06:3b:2f"} - ssh_keys_client._client.request.assert_called_with( - url="/ssh_keys", method="GET", params=params - ) + request_mock.assert_called_with(url="/ssh_keys", method="GET", params=params) assert ssh_keys._client is ssh_keys_client assert ssh_keys.id == 2323 assert ssh_keys.name == "SSH-Key" - def test_create(self, ssh_keys_client, ssh_key_response): - ssh_keys_client._client.request.return_value = ssh_key_response + def test_create( + self, request_mock: mock.MagicMock, ssh_keys_client, ssh_key_response + ): + request_mock.return_value = ssh_key_response ssh_key = ssh_keys_client.create( name="My ssh key", public_key="ssh-rsa AAAjjk76kgf...Xt" ) - ssh_keys_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/ssh_keys", method="POST", json={"name": "My ssh key", "public_key": "ssh-rsa AAAjjk76kgf...Xt"}, @@ -163,10 +186,16 @@ def test_create(self, ssh_keys_client, ssh_key_response): @pytest.mark.parametrize( "ssh_key", [SSHKey(id=1), BoundSSHKey(mock.MagicMock(), dict(id=1))] ) - def test_update(self, ssh_keys_client, ssh_key, response_update_ssh_key): - ssh_keys_client._client.request.return_value = response_update_ssh_key + def test_update( + self, + request_mock: mock.MagicMock, + ssh_keys_client, + ssh_key, + response_update_ssh_key, + ): + request_mock.return_value = response_update_ssh_key ssh_key = ssh_keys_client.update(ssh_key, name="New name") - ssh_keys_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/ssh_keys/1", method="PUT", json={"name": "New name"} ) @@ -176,11 +205,15 @@ def test_update(self, ssh_keys_client, ssh_key, response_update_ssh_key): @pytest.mark.parametrize( "ssh_key", [SSHKey(id=1), BoundSSHKey(mock.MagicMock(), dict(id=1))] ) - def test_delete(self, ssh_keys_client, ssh_key, generic_action): - ssh_keys_client._client.request.return_value = generic_action + def test_delete( + self, + request_mock: mock.MagicMock, + ssh_keys_client, + ssh_key, + action_response, + ): + request_mock.return_value = action_response delete_success = ssh_keys_client.delete(ssh_key) - ssh_keys_client._client.request.assert_called_with( - url="/ssh_keys/1", method="DELETE" - ) + request_mock.assert_called_with(url="/ssh_keys/1", method="DELETE") assert delete_success is True diff --git a/tests/unit/volumes/test_client.py b/tests/unit/volumes/test_client.py index 1133a417..f7289cd4 100644 --- a/tests/unit/volumes/test_client.py +++ b/tests/unit/volumes/test_client.py @@ -5,7 +5,7 @@ import pytest from dateutil.parser import isoparse -from hcloud.actions import BoundAction +from hcloud import Client from hcloud.locations import BoundLocation, Location from hcloud.servers import BoundServer, Server from hcloud.volumes import BoundVolume, Volume, VolumesClient @@ -13,12 +13,13 @@ class TestBoundVolume: @pytest.fixture() - def bound_volume(self, hetzner_client): - return BoundVolume(client=hetzner_client.volumes, data=dict(id=14)) + def bound_volume(self, client: Client): + return BoundVolume(client=client.volumes, data=dict(id=14)) - def test_bound_volume_init(self, volume_response): + def test_bound_volume_init(self, client: Client, volume_response): bound_volume = BoundVolume( - client=mock.MagicMock(), data=volume_response["volume"] + client=client.volumes, + data=volume_response["volume"], ) assert bound_volume.id == 1 @@ -41,108 +42,131 @@ def test_bound_volume_init(self, volume_response): assert bound_volume.location.latitude == 50.47612 assert bound_volume.location.longitude == 12.370071 - def test_get_actions(self, hetzner_client, bound_volume, response_get_actions): - hetzner_client.request.return_value = response_get_actions - actions = bound_volume.get_actions(sort="id") - hetzner_client.request.assert_called_with( - url="/volumes/14/actions", - method="GET", - params={"page": 1, "per_page": 50, "sort": "id"}, - ) - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - assert actions[0]._client == hetzner_client.actions - assert actions[0].id == 13 - assert actions[0].command == "attach_volume" - - def test_update(self, hetzner_client, bound_volume, response_update_volume): - hetzner_client.request.return_value = response_update_volume + def test_update( + self, + request_mock: mock.MagicMock, + bound_volume, + response_update_volume, + ): + request_mock.return_value = response_update_volume volume = bound_volume.update(name="new-name") - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/volumes/14", method="PUT", json={"name": "new-name"} ) assert volume.id == 4711 assert volume.name == "new-name" - def test_delete(self, hetzner_client, bound_volume, generic_action): - hetzner_client.request.return_value = generic_action + def test_delete( + self, + request_mock: mock.MagicMock, + client: Client, + bound_volume, + action_response, + ): + request_mock.return_value = action_response delete_success = bound_volume.delete() - hetzner_client.request.assert_called_with(url="/volumes/14", method="DELETE") + request_mock.assert_called_with(url="/volumes/14", method="DELETE") assert delete_success is True - def test_change_protection(self, hetzner_client, bound_volume, generic_action): - hetzner_client.request.return_value = generic_action + def test_change_protection( + self, + request_mock: mock.MagicMock, + bound_volume, + action_response, + ): + request_mock.return_value = action_response action = bound_volume.change_protection(True) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/volumes/14/actions/change_protection", method="POST", json={"delete": True}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "server", (Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))) ) - def test_attach(self, hetzner_client, bound_volume, server, generic_action): - hetzner_client.request.return_value = generic_action + def test_attach( + self, + request_mock: mock.MagicMock, + client: Client, + bound_volume, + server, + action_response, + ): + request_mock.return_value = action_response action = bound_volume.attach(server) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/volumes/14/actions/attach", method="POST", json={"server": 1} ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "server", (Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))) ) def test_attach_with_automount( - self, hetzner_client, bound_volume, server, generic_action + self, + request_mock: mock.MagicMock, + client: Client, + bound_volume, + server, + action_response, ): - hetzner_client.request.return_value = generic_action + request_mock.return_value = action_response action = bound_volume.attach(server, False) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/volumes/14/actions/attach", method="POST", json={"server": 1, "automount": False}, ) assert action.id == 1 - assert action.progress == 0 - - def test_detach(self, hetzner_client, bound_volume, generic_action): - hetzner_client.request.return_value = generic_action + assert action.progress == 20 + + def test_detach( + self, + request_mock: mock.MagicMock, + client: Client, + bound_volume, + action_response, + ): + request_mock.return_value = action_response action = bound_volume.detach() - hetzner_client.request.assert_called_with( - url="/volumes/14/actions/detach", method="POST" - ) + request_mock.assert_called_with(url="/volumes/14/actions/detach", method="POST") assert action.id == 1 - assert action.progress == 0 - - def test_resize(self, hetzner_client, bound_volume, generic_action): - hetzner_client.request.return_value = generic_action + assert action.progress == 20 + + def test_resize( + self, + request_mock: mock.MagicMock, + client: Client, + bound_volume, + action_response, + ): + request_mock.return_value = action_response action = bound_volume.resize(50) - hetzner_client.request.assert_called_with( + request_mock.assert_called_with( url="/volumes/14/actions/resize", method="POST", json={"size": 50} ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 class TestVolumesClient: @pytest.fixture() - def volumes_client(self): - return VolumesClient(client=mock.MagicMock()) + def volumes_client(self, client: Client): + return VolumesClient(client) - def test_get_by_id(self, volumes_client, volume_response): - volumes_client._client.request.return_value = volume_response + def test_get_by_id( + self, request_mock: mock.MagicMock, volumes_client, volume_response + ): + request_mock.return_value = volume_response bound_volume = volumes_client.get_by_id(1) - volumes_client._client.request.assert_called_with( - url="/volumes/1", method="GET" - ) + request_mock.assert_called_with(url="/volumes/1", method="GET") assert bound_volume._client is volumes_client assert bound_volume.id == 1 assert bound_volume.name == "database-storage" @@ -151,12 +175,12 @@ def test_get_by_id(self, volumes_client, volume_response): "params", [{"label_selector": "label1", "page": 1, "per_page": 10}, {"name": ""}, {}], ) - def test_get_list(self, volumes_client, two_volumes_response, params): - volumes_client._client.request.return_value = two_volumes_response + def test_get_list( + self, request_mock: mock.MagicMock, volumes_client, two_volumes_response, params + ): + request_mock.return_value = two_volumes_response result = volumes_client.get_list(**params) - volumes_client._client.request.assert_called_with( - url="/volumes", method="GET", params=params - ) + request_mock.assert_called_with(url="/volumes", method="GET", params=params) bound_volumes = result.volumes assert result.meta is not None @@ -175,15 +199,15 @@ def test_get_list(self, volumes_client, two_volumes_response, params): assert bound_volume2.name == "vault-storage" @pytest.mark.parametrize("params", [{"label_selector": "label1"}]) - def test_get_all(self, volumes_client, two_volumes_response, params): - volumes_client._client.request.return_value = two_volumes_response + def test_get_all( + self, request_mock: mock.MagicMock, volumes_client, two_volumes_response, params + ): + request_mock.return_value = two_volumes_response bound_volumes = volumes_client.get_all(**params) params.update({"page": 1, "per_page": 50}) - volumes_client._client.request.assert_called_with( - url="/volumes", method="GET", params=params - ) + request_mock.assert_called_with(url="/volumes", method="GET", params=params) assert len(bound_volumes) == 2 @@ -198,22 +222,24 @@ def test_get_all(self, volumes_client, two_volumes_response, params): assert bound_volume2.id == 2 assert bound_volume2.name == "vault-storage" - def test_get_by_name(self, volumes_client, one_volumes_response): - volumes_client._client.request.return_value = one_volumes_response + def test_get_by_name( + self, request_mock: mock.MagicMock, volumes_client, one_volumes_response + ): + request_mock.return_value = one_volumes_response bound_volume = volumes_client.get_by_name("database-storage") params = {"name": "database-storage"} - volumes_client._client.request.assert_called_with( - url="/volumes", method="GET", params=params - ) + request_mock.assert_called_with(url="/volumes", method="GET", params=params) assert bound_volume._client is volumes_client assert bound_volume.id == 1 assert bound_volume.name == "database-storage" - def test_create_with_location(self, volumes_client, volume_create_response): - volumes_client._client.request.return_value = volume_create_response + def test_create_with_location( + self, request_mock: mock.MagicMock, volumes_client, volume_create_response + ): + request_mock.return_value = volume_create_response response = volumes_client.create( 100, "database-storage", @@ -221,7 +247,7 @@ def test_create_with_location(self, volumes_client, volume_create_response): automount=False, format="xfs", ) - volumes_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/volumes", method="POST", json={ @@ -247,12 +273,18 @@ def test_create_with_location(self, volumes_client, volume_create_response): @pytest.mark.parametrize( "server", [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))] ) - def test_create_with_server(self, volumes_client, server, volume_create_response): - volumes_client._client.request.return_value = volume_create_response + def test_create_with_server( + self, + request_mock: mock.MagicMock, + volumes_client, + server, + volume_create_response, + ): + request_mock.return_value = volume_create_response volumes_client.create( 100, "database-storage", server=server, automount=False, format="xfs" ) - volumes_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/volumes", method="POST", json={ @@ -264,52 +296,40 @@ def test_create_with_server(self, volumes_client, server, volume_create_response }, ) - def test_create_negative_size(self, volumes_client): + def test_create_negative_size(self, request_mock: mock.MagicMock, volumes_client): with pytest.raises(ValueError) as e: volumes_client.create( -100, "database-storage", location=Location(name="location") ) assert str(e.value) == "size must be greater than 0" - volumes_client._client.request.assert_not_called() + request_mock.assert_not_called() @pytest.mark.parametrize( "location,server", [(None, None), ("location", Server(id=1))] ) def test_create_wrong_location_server_combination( - self, volumes_client, location, server + self, request_mock: mock.MagicMock, volumes_client, location, server ): with pytest.raises(ValueError) as e: volumes_client.create( 100, "database-storage", location=location, server=server ) assert str(e.value) == "only one of server or location must be provided" - volumes_client._client.request.assert_not_called() - - @pytest.mark.parametrize( - "volume", [Volume(id=1), BoundVolume(mock.MagicMock(), dict(id=1))] - ) - def test_get_actions_list(self, volumes_client, volume, response_get_actions): - volumes_client._client.request.return_value = response_get_actions - result = volumes_client.get_actions_list(volume, sort="id") - volumes_client._client.request.assert_called_with( - url="/volumes/1/actions", method="GET", params={"sort": "id"} - ) - - actions = result.actions - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - - assert actions[0]._client == volumes_client._client.actions - assert actions[0].id == 13 - assert actions[0].command == "attach_volume" + request_mock.assert_not_called() @pytest.mark.parametrize( "volume", [Volume(id=1), BoundVolume(mock.MagicMock(), dict(id=1))] ) - def test_update(self, volumes_client, volume, response_update_volume): - volumes_client._client.request.return_value = response_update_volume + def test_update( + self, + request_mock: mock.MagicMock, + volumes_client, + volume, + response_update_volume, + ): + request_mock.return_value = response_update_volume volume = volumes_client.update(volume, name="new-name") - volumes_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/volumes/1", method="PUT", json={"name": "new-name"} ) @@ -319,27 +339,37 @@ def test_update(self, volumes_client, volume, response_update_volume): @pytest.mark.parametrize( "volume", [Volume(id=1), BoundVolume(mock.MagicMock(), dict(id=1))] ) - def test_change_protection(self, volumes_client, volume, generic_action): - volumes_client._client.request.return_value = generic_action + def test_change_protection( + self, + request_mock: mock.MagicMock, + volumes_client, + volume, + action_response, + ): + request_mock.return_value = action_response action = volumes_client.change_protection(volume, True) - volumes_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/volumes/1/actions/change_protection", method="POST", json={"delete": True}, ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "volume", [Volume(id=1), BoundVolume(mock.MagicMock(), dict(id=1))] ) - def test_delete(self, volumes_client, volume, generic_action): - volumes_client._client.request.return_value = generic_action + def test_delete( + self, + request_mock: mock.MagicMock, + volumes_client, + volume, + action_response, + ): + request_mock.return_value = action_response delete_success = volumes_client.delete(volume) - volumes_client._client.request.assert_called_with( - url="/volumes/1", method="DELETE" - ) + request_mock.assert_called_with(url="/volumes/1", method="DELETE") assert delete_success is True @@ -353,85 +383,52 @@ def test_delete(self, volumes_client, volume, generic_action): ), ], ) - def test_attach(self, volumes_client, server, volume, generic_action): - volumes_client._client.request.return_value = generic_action + def test_attach( + self, + request_mock: mock.MagicMock, + volumes_client, + server, + volume, + action_response, + ): + request_mock.return_value = action_response action = volumes_client.attach(volume, server) - volumes_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/volumes/12/actions/attach", method="POST", json={"server": 1} ) assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "volume", [Volume(id=12), BoundVolume(mock.MagicMock(), dict(id=12))] ) - def test_detach(self, volumes_client, volume, generic_action): - volumes_client._client.request.return_value = generic_action + def test_detach( + self, + request_mock: mock.MagicMock, + volumes_client, + volume, + action_response, + ): + request_mock.return_value = action_response action = volumes_client.detach(volume) - volumes_client._client.request.assert_called_with( - url="/volumes/12/actions/detach", method="POST" - ) + request_mock.assert_called_with(url="/volumes/12/actions/detach", method="POST") assert action.id == 1 - assert action.progress == 0 + assert action.progress == 20 @pytest.mark.parametrize( "volume", [Volume(id=12), BoundVolume(mock.MagicMock(), dict(id=12))] ) - def test_resize(self, volumes_client, volume, generic_action): - volumes_client._client.request.return_value = generic_action + def test_resize( + self, + request_mock: mock.MagicMock, + volumes_client, + volume, + action_response, + ): + request_mock.return_value = action_response action = volumes_client.resize(volume, 50) - volumes_client._client.request.assert_called_with( + request_mock.assert_called_with( url="/volumes/12/actions/resize", method="POST", json={"size": 50} ) assert action.id == 1 - assert action.progress == 0 - - def test_actions_get_by_id(self, volumes_client, response_get_actions): - volumes_client._client.request.return_value = { - "action": response_get_actions["actions"][0] - } - action = volumes_client.actions.get_by_id(13) - - volumes_client._client.request.assert_called_with( - url="/volumes/actions/13", method="GET" - ) - - assert isinstance(action, BoundAction) - assert action._client == volumes_client._client.actions - assert action.id == 13 - assert action.command == "attach_volume" - - def test_actions_get_list(self, volumes_client, response_get_actions): - volumes_client._client.request.return_value = response_get_actions - result = volumes_client.actions.get_list() - - volumes_client._client.request.assert_called_with( - url="/volumes/actions", - method="GET", - params={}, - ) - - actions = result.actions - assert result.meta is not None - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - assert actions[0]._client == volumes_client._client.actions - assert actions[0].id == 13 - assert actions[0].command == "attach_volume" - - def test_actions_get_all(self, volumes_client, response_get_actions): - volumes_client._client.request.return_value = response_get_actions - actions = volumes_client.actions.get_all() - - volumes_client._client.request.assert_called_with( - url="/volumes/actions", - method="GET", - params={"page": 1, "per_page": 50}, - ) - - assert len(actions) == 1 - assert isinstance(actions[0], BoundAction) - assert actions[0]._client == volumes_client._client.actions - assert actions[0].id == 13 - assert actions[0].command == "attach_volume" + assert action.progress == 20