diff --git a/src/pyrestresource/rest_request.py b/src/pyrestresource/rest_request.py index 80f223d..4549d0e 100644 --- a/src/pyrestresource/rest_request.py +++ b/src/pyrestresource/rest_request.py @@ -10,8 +10,9 @@ from re import sub from urllib.parse import urlparse, parse_qs from pydantic import BaseModel, Field +from typeguard import check_type -from .rest_types import rsrc_verb, T_SupportedRESTFields +from .rest_types import rsrc_verb, T_SupportedRESTFields, T_AllSupportedFields from .rest_request_opt import ( RestRequestParams_POST, @@ -129,6 +130,10 @@ class RestRequest(Generic[_T_RestRequestParams]): raise RuntimeError("url and verb and data must be set") self.url = url self.verb = verb + + if data != {} and not check_type(data, T_AllSupportedFields): + raise RuntimeError(f"Wrong data type received: {data}") + self.data = data # parse_qs returns list[] for all keys, the command convert list to single items so pydantic can eat them :) diff --git a/src/pyrestresource/rest_resource.py b/src/pyrestresource/rest_resource.py index 8a70a0e..cfad675 100644 --- a/src/pyrestresource/rest_resource.py +++ b/src/pyrestresource/rest_resource.py @@ -142,8 +142,8 @@ class RestResourceWalker_Sub_T_Dict__tree_init(RestResourceWalker_Sub_T_Dict): if "ACL" in self.resource.json_schema_extra: if isinstance(self.resource.json_schema_extra["ACL"], list): - print(f"found ACL (Dict): {self.resource.json_schema_extra['ACL']}") - self.parent.annotation._ACL_record_[self.resource_name] = self.resource.json_schema_extra["ACL"] + # print(f"found ACL (Dict): {self.resource.json_schema_extra['ACL']}") + self.parent.annotation._ACL_record_[self.resource_name] += self.resource.json_schema_extra["ACL"] else: raise RuntimeError("ACL must be a list()") @@ -174,6 +174,9 @@ class RestResourceWalker_Sub_RestFields__tree_init(RestResourceWalker_Sub_RestFi if self.parent.annotation._primary_key_ is not None: raise RuntimeError(f"Only one primary key is allowed {self.parent.resource_name}.{self.resource_name}") self.parent.annotation._primary_key_ = self.resource_name + self.parent.annotation._ACL_record_[self.resource_name] = [ + ACL_record(verbs=[rsrc_verb.PUT], target=ACL_target_group_Any(), rule=ACL_rule.DENY) + ] if "plugin" in self.resource.json_schema_extra: plugin_field: ResourcePlugin_field = self.resource.json_schema_extra["plugin"] @@ -184,8 +187,8 @@ class RestResourceWalker_Sub_RestFields__tree_init(RestResourceWalker_Sub_RestFi if "ACL" in self.resource.json_schema_extra: if isinstance(self.resource.json_schema_extra["ACL"], list): - print(f"found ACL (Field): {self.resource.json_schema_extra['ACL']}") - self.parent.annotation._ACL_record_[self.resource_name] = self.resource.json_schema_extra["ACL"] + # print(f"found ACL (Field): {self.resource.json_schema_extra['ACL']}") + self.parent.annotation._ACL_record_[self.resource_name] += self.resource.json_schema_extra["ACL"] else: raise RuntimeError("ACL must be a list()") @@ -223,8 +226,8 @@ class RestResourceWalker_Sub_RestResourceBase__tree_init(RestResourceWalker_Sub_ if "ACL" in self.resource.json_schema_extra: if isinstance(self.resource.json_schema_extra["ACL"], list): - print(f"found ACL (Resource): {self.resource.json_schema_extra['ACL']}") - self.parent.annotation._ACL_record_[self.resource_name] = self.resource.json_schema_extra["ACL"] + # print(f"found ACL (Resource): {self.resource.json_schema_extra['ACL']}") + self.parent.annotation._ACL_record_[self.resource_name] += self.resource.json_schema_extra["ACL"] else: raise RuntimeError("ACL must be a list()") @@ -261,35 +264,35 @@ class RestResourceBase(ABC, BaseModel, validate_assignment=True): ] ] = {} - def _check_acl(self, user: ACL_target_user, group: ACL_target_group, verb: rsrc_verb, field: str): - print(f"evaluate self ACLs rule: {self._ACL_record_}") - if verb is rsrc_verb.GET and self.model_fields[field].exclude is True: - print("ALLOWED (excluded field)") + def _check_acl(self, user: ACL_target_user, group: ACL_target_group, verb: rsrc_verb, field: str, is_self: bool = True): + # print(f"evaluate self ACLs rule: {self._ACL_record_}") + if is_self and verb is rsrc_verb.GET and self.model_fields[field].exclude is True: + # print("ALLOWED (excluded field)") return for acl in self._ACL_record_[field]: - print(f"evaluate ACL rule: {acl}") + # print(f"evaluate ACL rule: {acl}") if verb in acl.verbs: if isinstance(acl.target, ACL_target_user): if user == acl.target: if acl.rule is ACL_rule.ALLOW: - print("ALLOWED (user)") + # print("ALLOWED (user)") return raise RuntimeError(f"Not allowed access detected: {field}") elif isinstance(acl.target, ACL_target_group): if group == acl.target or acl.target == ACL_target_group_Any(): if acl.rule is ACL_rule.ALLOW: - print("ALLOWED (group)") + # print("ALLOWED (group)") return raise RuntimeError(f"Not allowed access detected: {field}") else: raise RuntimeError(f"Wrong ACL target type: {field}") - print("ALLOWED (Default)") + # print("ALLOWED (Default)") - def check_acl_access(self, request: RestRequest) -> None: + def check_acl_field(self, request: RestRequest, req_index: int = 0) -> None: """Check ACL on requested field access""" - self._check_acl(request.user, request.group, request.get_verb(), request.get_resource_origin(0)) + self._check_acl(request.user, request.group, request.get_verb(), request.get_resource_origin(req_index), False) - def check_acl_operation(self, request: RestRequest, new_data: Optional[dict[str, _T_SupportedRESTFields]]) -> None: + def check_acl_self(self, request: RestRequest, new_data: Optional[dict[str, _T_SupportedRESTFields]]) -> None: """Check ACL on requested field operation (involving checking sub-fields)""" if request.get_verb() is rsrc_verb.GET: for key in self.model_fields.keys(): @@ -401,5 +404,7 @@ class RestResourceBase(ABC, BaseModel, validate_assignment=True): request.set_result(json.dumps(result.model_dump(mode="json"))) elif result is not None: request.set_result(json.dumps(result, cls=_JSONEncoder)) + else: + request.set_result("null") return request diff --git a/src/pyrestresource/rest_resource_handler.py b/src/pyrestresource/rest_resource_handler.py index 5996cc6..01ecc0b 100644 --- a/src/pyrestresource/rest_resource_handler.py +++ b/src/pyrestresource/rest_resource_handler.py @@ -183,7 +183,7 @@ class ResourceHandler( # reveal_type(next_resource) _next_resource = cast(_T_Resource, next_resource) # reveal_type(_next_resource) - print(f"[DEBUG] next_resource = {type(next_resource).__name__}") + # print(f"[DEBUG] next_resource = {type(next_resource).__name__}") if ( isinstance(_next_resource, RestResourceBase) @@ -464,13 +464,13 @@ class ResourceHandler_RestResourceBase( def _check_access_rights(self) -> None: super()._check_access_rights() - print(f"{type(self).__name__}->_check_access_rights()") + # print(f"{type(self).__name__}->_check_access_rights()") if self.req.get_resource_origin(0) == "/": return - print("==================") - print(self.req.get_resource_origin(0)) + # print("==================") + # print(self.req.get_resource_origin(0)) # print(len(self.req.get_url_stack())) # print(self.resource._model_dump_excluded_) # print(type(self.resource)) @@ -479,7 +479,7 @@ class ResourceHandler_RestResourceBase( if self.req.get_resource_origin(0) not in self.resource.model_fields: raise RuntimeError(f"Unknown field access detected: {self.req.get_url_stack()}") - self.resource.check_acl_access(self.req) + self.resource.check_acl_field(self.req) if len(self.req.get_url_stack()) == 0: # destination reached if self.resource.model_fields[self.req.get_resource_origin(0)].exclude is True and self.req.get_verb() is rsrc_verb.GET: @@ -500,7 +500,7 @@ class ResourceHandler_RestResourceBase( # CASE 1: no more item in url_stack => we reached the endpoint (operation) # So we are in a RestResourceBase instance and must return the content if len(self.req.get_url_stack()) == 0: - self.resource.check_acl_operation(self.req) + self.resource.check_acl_self(self.req, None) for key, attr in self.resource.model_fields.items(): if key in self.resource._plugins_: if isinstance(self.resource._plugins_[key], ResourcePlugin_field): @@ -522,6 +522,7 @@ class ResourceHandler_RestResourceBase( return self.resource # CASE 3: in between (access) + self.resource.check_acl_field(self.req) value = getattr(self.resource, self.req.get_resource_origin(0)) key = self.req.get_resource_origin(0) @@ -546,7 +547,7 @@ class ResourceHandler_RestResourceBase( # print(f"{type(self).__name__}->_process_put()") # print(f"{type(self).__name__}->resource = {type(self.resource).__name__}") - self.resource.check_acl_operation(self.req, self.req.get_data()) + self.resource.check_acl_self(self.req, self.req.get_data()) # creating a copy of the current resource _new_resrc = self.resource.copy() @@ -564,9 +565,8 @@ class ResourceHandler_RestResourceBase( # applying plugins (from parent element) if self.prev_handler is not None: - # element is within a dict if ( - isinstance(self.prev_handler.resource, dict) + isinstance(self.prev_handler.resource, dict) # element is within a dict and self.prev_handler.prev_handler is not None and isinstance(self.prev_handler.prev_handler.resource, RestResourceBase) ): @@ -587,7 +587,7 @@ class ResourceHandler_RestResourceBase( ) _new_resrc = plugin_rsrc.handle_resource_put(_new_resrc, params) - self.resource.update(**_new_resrc.dict()) + self.resource.update(**_new_resrc.__dict__) return def _handle_process_delete(self, params) -> None: @@ -629,6 +629,8 @@ class ResourceHandler_simple( assert self.prev_handler is not None assert isinstance(self.prev_handler.resource, RestResourceBase) + self.prev_handler.resource.check_acl_field(self.req, 1) + if self.req.get_resource_origin(1) in self.prev_handler.resource._plugins_: plugin_simple: ResourcePlugin_field = cast( ResourcePlugin_field, @@ -645,6 +647,8 @@ class ResourceHandler_simple( assert self.prev_handler is not None assert isinstance(self.prev_handler.resource, RestResourceBase) + self.prev_handler.resource.check_acl_field(self.req, 1) + value = self.req.get_data() if self.req.get_resource_origin(1) in self.prev_handler.resource._plugins_: diff --git a/src/pyrestresource/rest_types.py b/src/pyrestresource/rest_types.py index 55e7c12..98edc7c 100644 --- a/src/pyrestresource/rest_types.py +++ b/src/pyrestresource/rest_types.py @@ -98,5 +98,4 @@ T_Dict = dict[T_DictKey, T_DictValues] _T_Dict = dict[_T_DictKey, _T_DictValues] T_AllSupportedFields = T_Dict | T_FieldValue -T_AllSupportedFiels = T_Dict | T_FieldValue T_AllSupportedContainers = Union[T_Dict, "RestResourceBase"] diff --git a/test/test_ACL.py b/test/test_ACL.py new file mode 100644 index 0000000..17859e3 --- /dev/null +++ b/test/test_ACL.py @@ -0,0 +1,180 @@ +from __future__ import annotations +import unittest +from os import chdir +from pathlib import Path +from typing import Optional +from pydantic import Field + + +print(__name__) +print(__package__) + + +from src.pyrestresource import ( + register_rest_rootpoint, + RestResourceBase, + rsrc_verb, + RestRequestParams_GET, + RestRequestParams_POST, + RestRequestParams_Dict_GET, + RestRequestParams_PUT, + T_SupportedRESTFields, + ResourcePlugin_field_default, + ResourcePlugin_RestResourceBase_default, + ACL_target_group_Any, + ACL_record, + ACL_rule, +) + + +testdir_path = Path(__file__).parent.resolve() +chdir(testdir_path.parent.resolve()) + + +# to allow mock-ing, all the tested classes are in a function +def init_classes(): + class TestResource(RestResourceBase): + username: Optional[str] = Field(None) + secret: Optional[str] = Field( + None, + exclude=True, + ACL=[ + ACL_record(verbs=[rsrc_verb.PUT], target=ACL_target_group_Any(), rule=ACL_rule.ALLOW), + ACL_record(verbs=[rsrc_verb.GET], target=ACL_target_group_Any(), rule=ACL_rule.DENY), + ], + ) + + class TestResource2(RestResourceBase): + version_ro: Optional[str] = Field( + "1.2.3", + ACL=[ + ACL_record(verbs=[rsrc_verb.PUT], target=ACL_target_group_Any(), rule=ACL_rule.DENY), + ], + ) + version: Optional[str] = Field("3.2.1") + + @register_rest_rootpoint + class RootApp(RestResourceBase): + resource_with_secret: TestResource = Field(default=TestResource()) + resource_with_secret_ACL: TestResource = Field( + default=TestResource(), ACL=[ACL_record(verbs=[rsrc_verb.PUT], target=ACL_target_group_Any(), rule=ACL_rule.DENY)] + ) + resource2: TestResource2 = Field(TestResource2()) + + # this add the classes to globals to allow using them later on + # => this is only for uinit-testing purpose and is not needed in real use + globals()[TestResource.__name__] = TestResource + globals()[RootApp.__name__] = RootApp + + +class Test_RestAPI_ACL(unittest.TestCase): + def setUp(self) -> None: + chdir(testdir_path.parent.resolve()) + init_classes() + self.testapp = RootApp() + + def test_subresource_readonly(self): + result = self.testapp.process_request("/", rsrc_verb.GET) + self.assertEqual(result.get_result(), "{}") + + result = self.testapp.process_request("/resource2", rsrc_verb.GET) + self.assertEqual(result.get_result(), '{"version_ro": "1.2.3", "version": "3.2.1"}') + + self.testapp.process_request("/resource2/version", rsrc_verb.PUT, '"6.6.6"') + + result = self.testapp.process_request("/resource2", rsrc_verb.GET) + self.assertEqual(result.get_result(), '{"version_ro": "1.2.3", "version": "6.6.6"}') + + with self.assertRaises(RuntimeError): # TODO: custom exception + self.testapp.process_request("/resource2/version_ro", rsrc_verb.PUT, '"6.6.6"') + + with self.assertRaises(RuntimeError): # TODO: custom exception + self.testapp.process_request("/resource2", rsrc_verb.PUT, '{"version_ro": "6.6.1", "version": "6.6.2"}') + + result = self.testapp.process_request("/resource2", rsrc_verb.GET) + self.assertEqual(result.get_result(), '{"version_ro": "1.2.3", "version": "6.6.6"}') + + def test_subresource(self): + result = self.testapp.process_request("/", rsrc_verb.GET) + self.assertEqual(result.get_result(), "{}") + + result = self.testapp.process_request("/resource_with_secret", rsrc_verb.GET) + self.assertEqual(result.get_result(), '{"username": null}') + + result = self.testapp.process_request("/resource_with_secret/username", rsrc_verb.GET) + self.assertEqual(result.get_result(), "null") + self.assertEqual(self.testapp.resource_with_secret.username, None) + + with self.assertRaises(RuntimeError): # TODO: custom exception + self.testapp.process_request("/resource_with_secret/secret", rsrc_verb.GET) + + self.assertEqual(self.testapp.resource_with_secret.secret, None) + + result = self.testapp.process_request("/resource_with_secret", rsrc_verb.PUT, '{"username":"chacha","secret":"123456"}') + self.assertEqual(result.get_result(), "null") + + result = self.testapp.process_request("/resource_with_secret", rsrc_verb.GET) + self.assertEqual(result.get_result(), '{"username": "chacha"}') + + result = self.testapp.process_request("/resource_with_secret/username", rsrc_verb.GET) + self.assertEqual(result.get_result(), '"chacha"') + self.assertEqual(self.testapp.resource_with_secret.username, "chacha") + + with self.assertRaises(RuntimeError): # TODO: custom exception + self.testapp.process_request("/resource_with_secret/secret", rsrc_verb.GET) + + self.assertEqual(self.testapp.resource_with_secret.secret, "123456") + + def test_subresource_field(self): + result = self.testapp.process_request("/resource_with_secret/username", rsrc_verb.PUT, '"chacha"') + self.assertEqual(result.get_result(), "null") + + result = self.testapp.process_request("/resource_with_secret", rsrc_verb.GET) + self.assertEqual(result.get_result(), '{"username": "chacha"}') + + result = self.testapp.process_request("/resource_with_secret/username", rsrc_verb.GET) + self.assertEqual(result.get_result(), '"chacha"') + self.assertEqual(self.testapp.resource_with_secret.username, "chacha") + + with self.assertRaises(RuntimeError): # TODO: custom exception + self.testapp.process_request("/resource_with_secret/secret", rsrc_verb.GET) + + result = self.testapp.process_request("/resource_with_secret/secret", rsrc_verb.PUT, '"123456"') + self.assertEqual(result.get_result(), "null") + + with self.assertRaises(RuntimeError): # TODO: custom exception + self.testapp.process_request("/resource_with_secret/secret", rsrc_verb.GET) + + self.assertEqual(self.testapp.resource_with_secret.secret, "123456") + + def test_subresource_ACL(self): + result = self.testapp.process_request("/", rsrc_verb.GET) + self.assertEqual(result.get_result(), "{}") + + result = self.testapp.process_request("/resource_with_secret_ACL", rsrc_verb.GET) + self.assertEqual(result.get_result(), '{"username": null}') + + result = self.testapp.process_request("/resource_with_secret_ACL/username", rsrc_verb.GET) + self.assertEqual(result.get_result(), "null") + self.assertEqual(self.testapp.resource_with_secret_ACL.username, None) + + with self.assertRaises(RuntimeError): # TODO: custom exception + self.testapp.process_request("/resource_with_secret_ACL/secret", rsrc_verb.GET) + + self.assertEqual(self.testapp.resource_with_secret_ACL.secret, None) + + with self.assertRaises(RuntimeError): # TODO: custom exception + self.testapp.process_request("/resource_with_secret_ACL", rsrc_verb.PUT, '{"username":"chacha","secret":"123456"}') + self.assertEqual(self.testapp.resource_with_secret_ACL.username, None) + self.assertEqual(self.testapp.resource_with_secret_ACL.secret, None) + + def test_subresource_ACL_field(self): + with self.assertRaises(RuntimeError): # TODO: custom exception + self.testapp.process_request("/resource_with_secret_ACL/username", rsrc_verb.PUT, '"chacha"') + self.assertEqual(self.testapp.resource_with_secret_ACL.username, None) + self.assertEqual(self.testapp.resource_with_secret_ACL.secret, None) + + with self.assertRaises(RuntimeError): # TODO: custom exception + self.testapp.process_request("/resource_with_secret_ACL/secret", rsrc_verb.PUT, '"123456"') + self.assertEqual(self.testapp.resource_with_secret_ACL.username, None) + self.assertEqual(self.testapp.resource_with_secret_ACL.secret, None) diff --git a/test/test_rest_login.py b/test/test_rest_login.py index 32d2b1f..ff71667 100644 --- a/test/test_rest_login.py +++ b/test/test_rest_login.py @@ -7,8 +7,6 @@ from typing import Optional, Annotated from pydantic import Field from uuid import UUID, uuid4 from time import time, sleep -from time import time -import json import uvicorn import socket import requests @@ -32,9 +30,11 @@ from src.pyrestresource import ( T_SupportedRESTFields, ResourcePlugin_field_default, ResourcePlugin_RestResourceBase_default, + ACL_target_group_Any, + ACL_record, + ACL_rule, ) -from src.pyrestresource import ACL_target_user, ACL_target_group, ACL_target_group_Any, ACL_record, ACL_rule -from pprint import pprint + testdir_path = Path(__file__).parent.resolve() chdir(testdir_path.parent.resolve()) @@ -83,7 +83,7 @@ def init_classes(): exclude=True, ACL=[ ACL_record(verbs=[rsrc_verb.PUT], target=ACL_target_group_Any(), rule=ACL_rule.ALLOW), - ACL_record(verbs=[rsrc_verb.GET, rsrc_verb.DELETE, rsrc_verb.POST], target=ACL_target_group_Any(), rule=ACL_rule.DENY), + ACL_record(verbs=[rsrc_verb.GET], target=ACL_target_group_Any(), rule=ACL_rule.DENY), ], ) @@ -101,8 +101,6 @@ def find_free_port(): with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s: s.bind(("", 0)) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - hostname = socket.gethostname() - IPAddr = socket.gethostbyname(hostname) return "localhost", s.getsockname()[1] @@ -119,7 +117,6 @@ class Test_RestAPI_LOGIN(unittest.TestCase): self.testapp = RootApp() def test_login(self): - """ result = self.testapp.process_request("/login", rsrc_verb.GET) print("*****************") print(result.get_result()) @@ -131,13 +128,11 @@ class Test_RestAPI_LOGIN(unittest.TestCase): # result = self.testapp.process_request("/login/secret", rsrc_verb.GET) # print("*****************") # print(result.get_result()) - """ result = self.testapp.process_request("/login", rsrc_verb.PUT, '{"username":"chacha","secret":"123456"}') print("*****************") print(result.get_result()) - """ result = self.testapp.process_request("/login", rsrc_verb.GET) print("*****************") print(result.get_result()) @@ -149,7 +144,6 @@ class Test_RestAPI_LOGIN(unittest.TestCase): # result = self.testapp.process_request("/login/secret", rsrc_verb.GET) # print("*****************") # print(result.get_result()) - """ class Test_RestAPI_LOGIN_Web(unittest.TestCase): diff --git a/test/test_rest_resource.py b/test/test_rest_resource.py index 5120150..f3b7c9d 100644 --- a/test/test_rest_resource.py +++ b/test/test_rest_resource.py @@ -21,6 +21,9 @@ from src.pyrestresource import ( RestRequestParams_POST, RestRequestParams_Dict_GET, T_SupportedRESTFields, + ACL_target_group_Any, + ACL_record, + ACL_rule, ) from pprint import pprint @@ -58,9 +61,19 @@ def init_classes(): Patch_2 = Patch(uuid="d385a1d2-65fa-11ee-8c99-0242ac120002", shortname="testPatch2") class User(RestResourceBase): - uuid: UUID = Field(default_factory=uuid4, primary_key=True) + uuid: UUID = Field( + default_factory=uuid4, + primary_key=True, + ) name: str - secret: str = Field(..., exclude=True) + secret: str = Field( + ..., + exclude=True, + ACL=[ + ACL_record(verbs=[rsrc_verb.PUT], target=ACL_target_group_Any(), rule=ACL_rule.ALLOW), + ACL_record(verbs=[rsrc_verb.GET], target=ACL_target_group_Any(), rule=ACL_rule.DENY), + ], + ) User1 = User( uuid="8da57a3c-661f-11ee-8c99-0242ac120002", @@ -68,8 +81,6 @@ def init_classes(): secret="la blanquette est bonne", ) - ext_patchs: dict[UUID, Patch] = {} - class Patch2(RestResourceBase): uuid: UUID = Field(default_factory=uuid4, primary_key=True) shortname: str @@ -117,100 +128,100 @@ class Test_RestAPI_GET(unittest.TestCase): def test_get_root(self): result = self.testapp.process_request("/", rsrc_verb.GET) - self.assertEqual(result, '{"testValueRoot": 3.14}') + self.assertEqual(result.get_result(), '{"testValueRoot": 3.14}') def test_get_root__multiple_slash(self): result = self.testapp.process_request("/////", rsrc_verb.GET) - self.assertEqual(result, '{"testValueRoot": 3.14}') + self.assertEqual(result.get_result(), '{"testValueRoot": 3.14}') result = self.testapp.process_request("////", rsrc_verb.GET) - self.assertEqual(result, '{"testValueRoot": 3.14}') + self.assertEqual(result.get_result(), '{"testValueRoot": 3.14}') def test_get_root__nested_value(self): result = self.testapp.process_request("/testValueRoot", rsrc_verb.GET) - self.assertEqual(result, "3.14") + self.assertEqual(result.get_result(), "3.14") def test_get_root__nested_value__trailing_slash(self): result = self.testapp.process_request("/testValueRoot/", rsrc_verb.GET) - self.assertEqual(result, "3.14") + self.assertEqual(result.get_result(), "3.14") result = self.testapp.process_request("/testValueRoot//", rsrc_verb.GET) - self.assertEqual(result, "3.14") + self.assertEqual(result.get_result(), "3.14") result = self.testapp.process_request("/testValueRoot///", rsrc_verb.GET) - self.assertEqual(result, "3.14") + self.assertEqual(result.get_result(), "3.14") def test_get_root__nested_value__multiple_slash(self): result = self.testapp.process_request("//testValueRoot", rsrc_verb.GET) - self.assertEqual(result, "3.14") + self.assertEqual(result.get_result(), "3.14") result = self.testapp.process_request("///testValueRoot", rsrc_verb.GET) - self.assertEqual(result, "3.14") + self.assertEqual(result.get_result(), "3.14") def test_get_version(self): result = self.testapp.process_request("/info", rsrc_verb.GET) - self.assertEqual(result, '{"version": "0.0.1", "api_version": "0.0.2"}') + self.assertEqual(result.get_result(), '{"version": "0.0.1", "api_version": "0.0.2"}') def test_get_version__trailing_slash(self): result = self.testapp.process_request("/info/", rsrc_verb.GET) - self.assertEqual(result, '{"version": "0.0.1", "api_version": "0.0.2"}') + self.assertEqual(result.get_result(), '{"version": "0.0.1", "api_version": "0.0.2"}') result = self.testapp.process_request("/info//", rsrc_verb.GET) - self.assertEqual(result, '{"version": "0.0.1", "api_version": "0.0.2"}') + self.assertEqual(result.get_result(), '{"version": "0.0.1", "api_version": "0.0.2"}') result = self.testapp.process_request("/info///", rsrc_verb.GET) - self.assertEqual(result, '{"version": "0.0.1", "api_version": "0.0.2"}') + self.assertEqual(result.get_result(), '{"version": "0.0.1", "api_version": "0.0.2"}') def test_get_version__multiple_slash(self): result = self.testapp.process_request("//info", rsrc_verb.GET) - self.assertEqual(result, '{"version": "0.0.1", "api_version": "0.0.2"}') + self.assertEqual(result.get_result(), '{"version": "0.0.1", "api_version": "0.0.2"}') result = self.testapp.process_request("///info", rsrc_verb.GET) - self.assertEqual(result, '{"version": "0.0.1", "api_version": "0.0.2"}') + self.assertEqual(result.get_result(), '{"version": "0.0.1", "api_version": "0.0.2"}') def test_get_version__nested_value(self): result = self.testapp.process_request("/info/api_version", rsrc_verb.GET) - self.assertEqual(result, '"0.0.2"') + self.assertEqual(result.get_result(), '"0.0.2"') result = self.testapp.process_request("/info/version", rsrc_verb.GET) - self.assertEqual(result, '"0.0.1"') + self.assertEqual(result.get_result(), '"0.0.1"') def test_get_dict_games(self): result = self.testapp.process_request("/games", rsrc_verb.GET) - self.assertEqual(result, '["9b0381d4-65f6-11ee-8c99-0242ac120002"]') + self.assertEqual(result.get_result(), '["9b0381d4-65f6-11ee-8c99-0242ac120002"]') def test_get_dict_patchs(self): result = self.testapp.process_request("/patchs", rsrc_verb.GET) self.assertEqual( - result, + result.get_result(), '["cee1e870-65fa-11ee-8c99-0242ac120002", "d385a1d2-65fa-11ee-8c99-0242ac120002"]', ) def test_get_dict_patch_element(self): result = self.testapp.process_request("/patchs/cee1e870-65fa-11ee-8c99-0242ac120002", rsrc_verb.GET) self.assertEqual( - result, + result.get_result(), '{"uuid": "cee1e870-65fa-11ee-8c99-0242ac120002", "shortname": "testPatch1", "name": null, "description": null}', ) def test_get_dict_game_element(self): result = self.testapp.process_request("/games/9b0381d4-65f6-11ee-8c99-0242ac120002", rsrc_verb.GET) expected = '{"uuid": "9b0381d4-65f6-11ee-8c99-0242ac120002", "shortname": "testGame", "name": null, "description": null}' - self.assertEqual(result, expected) + self.assertEqual(result.get_result(), expected) def test_get_dict_game_element__nested_value(self): result = self.testapp.process_request("/games/9b0381d4-65f6-11ee-8c99-0242ac120002/shortname", rsrc_verb.GET) expected = '"testGame"' - self.assertEqual(result, expected) + self.assertEqual(result.get_result(), expected) def test_get_dict_game_element__nested_value2(self): result = self.testapp.process_request("/games/9b0381d4-65f6-11ee-8c99-0242ac120002/uuid", rsrc_verb.GET) expected = '"9b0381d4-65f6-11ee-8c99-0242ac120002"' - self.assertEqual(result, expected) + self.assertEqual(result.get_result(), expected) def test_get_nested_dict_games_patchs(self): result = self.testapp.process_request("/games/9b0381d4-65f6-11ee-8c99-0242ac120002/patchs", rsrc_verb.GET) - self.assertEqual(result, '["cee1e870-65fa-11ee-8c99-0242ac120002"]') + self.assertEqual(result.get_result(), '["cee1e870-65fa-11ee-8c99-0242ac120002"]') def test_get_nested_dict_games_patch_element(self): result = self.testapp.process_request( @@ -218,28 +229,28 @@ class Test_RestAPI_GET(unittest.TestCase): rsrc_verb.GET, ) expected = '{"uuid": "cee1e870-65fa-11ee-8c99-0242ac120002", "shortname": "testPatch1", "name": null, "description": null}' - self.assertEqual(result, expected) + self.assertEqual(result.get_result(), expected) def test_get_nested_dict_games_patch_element__nested_value(self): result = self.testapp.process_request( "/games/9b0381d4-65f6-11ee-8c99-0242ac120002/patchs/cee1e870-65fa-11ee-8c99-0242ac120002/uuid", rsrc_verb.GET, ) - self.assertEqual(result, '"cee1e870-65fa-11ee-8c99-0242ac120002"') + self.assertEqual(result.get_result(), '"cee1e870-65fa-11ee-8c99-0242ac120002"') def test_get_dict_game_element__API_nested(self): result = self.testapp.process_request("/games/9b0381d4-65f6-11ee-8c99-0242ac120002?API_nested=True", rsrc_verb.GET) expected = '{"uuid": "9b0381d4-65f6-11ee-8c99-0242ac120002", "shortname": "testGame", "name": null, "description": null}' - self.assertEqual(result, expected) + self.assertEqual(result.get_result(), expected) def test_get_dict_users(self): result = self.testapp.process_request("/users", rsrc_verb.GET) - self.assertEqual(result, '["8da57a3c-661f-11ee-8c99-0242ac120002"]') + self.assertEqual(result.get_result(), '["8da57a3c-661f-11ee-8c99-0242ac120002"]') def test_get_dict_user_element(self): result = self.testapp.process_request("/users/8da57a3c-661f-11ee-8c99-0242ac120002", rsrc_verb.GET) self.assertEqual( - result, + result.get_result(), '{"uuid": "8da57a3c-661f-11ee-8c99-0242ac120002", "name": "chacha"}', "no secret seen", ) @@ -247,14 +258,14 @@ class Test_RestAPI_GET(unittest.TestCase): def test_get_dict_user_element2(self): result = self.testapp.process_request("/users/8da57a3c-661f-11ee-8c99-0242ac120002?API_nested=True", rsrc_verb.GET) self.assertEqual( - result, + result.get_result(), '{"uuid": "8da57a3c-661f-11ee-8c99-0242ac120002", "name": "chacha"}', "no secret seen", ) def test_get_dict_user_element__nested_value(self): result = self.testapp.process_request("/users/8da57a3c-661f-11ee-8c99-0242ac120002/name", rsrc_verb.GET) - self.assertEqual(result, '"chacha"') + self.assertEqual(result.get_result(), '"chacha"') def test_get_dict_user_element__nested_value__forbiden(self): with self.assertRaises(RuntimeError): # TODO: custom exception @@ -278,7 +289,7 @@ class Test_RestAPI_PUT(unittest.TestCase): self.testapp.process_request("/info", rsrc_verb.PUT, '{"version": "1.2.3", "api_version": "3.2.1"}') result = self.testapp.process_request("/info", rsrc_verb.GET) - self.assertEqual(result, '{"version": "1.2.3", "api_version": "3.2.1"}') + self.assertEqual(result.get_result(), '{"version": "1.2.3", "api_version": "3.2.1"}') def test_put_dict_user_nested_value(self): self.testapp.process_request( @@ -288,12 +299,12 @@ class Test_RestAPI_PUT(unittest.TestCase): ) result = self.testapp.process_request("/users/8da57a3c-661f-11ee-8c99-0242ac120002/name", rsrc_verb.GET) - self.assertEqual(result, '"chacha2"') + self.assertEqual(result.get_result(), '"chacha2"') def test_put_user_nested_value__forbiden(self): with self.assertRaises(RuntimeError): # TODO: custom exception self.testapp.process_request( - "/users/8da57a3c-661f-11ee-8c99-0242ac120002/secret", + "/users/8da57a3c-661f-11ee-8c99-0242ac120002/uuid", rsrc_verb.PUT, '"test"', ) @@ -307,11 +318,11 @@ class Test_RestAPI_PUT(unittest.TestCase): result = self.testapp.process_request("/users", rsrc_verb.GET) expected = '["8da57a3c-661f-11ee-8c99-0242ac120002"]' - self.assertEqual(result, expected) + self.assertEqual(result.get_result(), expected) result = self.testapp.process_request("/users/8da57a3c-661f-11ee-8c99-0242ac120002", rsrc_verb.GET) expected = '{"uuid": "8da57a3c-661f-11ee-8c99-0242ac120002", "name": "testUser4"}' - self.assertEqual(result, expected) + self.assertEqual(result.get_result(), expected) def test_put_dict_patch__nested(self): self.testapp.process_request( @@ -325,7 +336,7 @@ class Test_RestAPI_PUT(unittest.TestCase): rsrc_verb.GET, ) expected = '{"uuid": "cee1e870-65fa-11ee-8c99-0242ac120002", "shortname": "testPatch998", "name": "MyPatch", "description": "MyDescription123"}' - self.assertEqual(result, expected) + self.assertEqual(result.get_result(), expected) class Test_RestAPI_POST(unittest.TestCase): @@ -340,15 +351,15 @@ class Test_RestAPI_POST(unittest.TestCase): rsrc_verb.POST, '{"name": "testUser", "secret": "test"}', ) - self.assertEqual(result, '"e5e87d32-662b-11ee-8c99-0242ac120002"') + self.assertEqual(result.get_result(), '"e5e87d32-662b-11ee-8c99-0242ac120002"') result = self.testapp.process_request("/users", rsrc_verb.GET) expected = '["8da57a3c-661f-11ee-8c99-0242ac120002", "e5e87d32-662b-11ee-8c99-0242ac120002"]' - self.assertEqual(result, expected) + self.assertEqual(result.get_result(), expected) result = self.testapp.process_request("/users/e5e87d32-662b-11ee-8c99-0242ac120002", rsrc_verb.GET) expected = '{"uuid": "e5e87d32-662b-11ee-8c99-0242ac120002", "name": "testUser"}' - self.assertEqual(result, expected) + self.assertEqual(result.get_result(), expected) def test_post_dict_user__nested_key(self): result = self.testapp.process_request( @@ -356,15 +367,15 @@ class Test_RestAPI_POST(unittest.TestCase): rsrc_verb.POST, '{"name": "testUser2", "secret": "test", "uuid":"e7e86d32-662b-11ee-8c99-0242ac120002"}', ) - self.assertEqual(result, '"e7e86d32-662b-11ee-8c99-0242ac120002"') + self.assertEqual(result.get_result(), '"e7e86d32-662b-11ee-8c99-0242ac120002"') result = self.testapp.process_request("/users", rsrc_verb.GET) expected = '["8da57a3c-661f-11ee-8c99-0242ac120002", "e7e86d32-662b-11ee-8c99-0242ac120002"]' - self.assertEqual(result, expected) + self.assertEqual(result.get_result(), expected) result = self.testapp.process_request("/users/e7e86d32-662b-11ee-8c99-0242ac120002", rsrc_verb.GET) expected = '{"uuid": "e7e86d32-662b-11ee-8c99-0242ac120002", "name": "testUser2"}' - self.assertEqual(result, expected) + self.assertEqual(result.get_result(), expected) @patch(f"{__loader__.name }.uuid4") def test_post_dict_user__auto_key(self, mock_uuid4): @@ -375,15 +386,15 @@ class Test_RestAPI_POST(unittest.TestCase): self.testapp = RootApp() result = self.testapp.process_request("/users", rsrc_verb.POST, '{"name": "testUser3", "secret": "test"}') - self.assertEqual(result, '"5faccb2e-69aa-11ee-8c99-0242ac120002"') + self.assertEqual(result.get_result(), '"5faccb2e-69aa-11ee-8c99-0242ac120002"') result = self.testapp.process_request("/users", rsrc_verb.GET) expected = '["8da57a3c-661f-11ee-8c99-0242ac120002", "5faccb2e-69aa-11ee-8c99-0242ac120002"]' - self.assertEqual(result, expected) + self.assertEqual(result.get_result(), expected) result = self.testapp.process_request("/users/5faccb2e-69aa-11ee-8c99-0242ac120002", rsrc_verb.GET) expected = '{"uuid": "5faccb2e-69aa-11ee-8c99-0242ac120002", "name": "testUser3"}' - self.assertEqual(result, expected) + self.assertEqual(result.get_result(), expected) def test_post_dict_patch__nested_API_key(self): self.testapp.process_request( @@ -397,7 +408,7 @@ class Test_RestAPI_POST(unittest.TestCase): rsrc_verb.GET, ) expected = '{"uuid": "cee1e971-65fa-11ee-8c99-0242ac120002", "shortname": "testPatch99", "name": "MyPatch", "description": "MyDescription"}' - self.assertEqual(result, expected) + self.assertEqual(result.get_result(), expected) class Test_RestAPI_DELETE(unittest.TestCase): @@ -411,7 +422,7 @@ class Test_RestAPI_DELETE(unittest.TestCase): result = self.testapp.process_request("/users", rsrc_verb.GET) expected = "[]" - self.assertEqual(result, expected) + self.assertEqual(result.get_result(), expected) def test_delete_dict_user__All(self): result = self.testapp.process_request( @@ -419,24 +430,24 @@ class Test_RestAPI_DELETE(unittest.TestCase): rsrc_verb.POST, '{"name": "testUser", "secret": "test"}', ) - self.assertEqual(result, '"e5e87d32-662b-11ee-8c99-0242ac120002"') + self.assertEqual(result.get_result(), '"e5e87d32-662b-11ee-8c99-0242ac120002"') result = self.testapp.process_request("/users", rsrc_verb.GET) expected = '["8da57a3c-661f-11ee-8c99-0242ac120002", "e5e87d32-662b-11ee-8c99-0242ac120002"]' - self.assertEqual(result, expected) + self.assertEqual(result.get_result(), expected) self.testapp.process_request("/users", rsrc_verb.DELETE) result = self.testapp.process_request("/users", rsrc_verb.GET) expected = "[]" - self.assertEqual(result, expected) + self.assertEqual(result.get_result(), expected) def test_delete_dict_user_element(self): self.testapp.process_request("/users/8da57a3c-661f-11ee-8c99-0242ac120002", rsrc_verb.DELETE) result = self.testapp.process_request("/users", rsrc_verb.GET) expected = "[]" - self.assertEqual(result, expected) + self.assertEqual(result.get_result(), expected) def test_delete_nested_dict_games_patch_element(self): self.testapp.process_request( @@ -446,7 +457,7 @@ class Test_RestAPI_DELETE(unittest.TestCase): result = self.testapp.process_request("/games/9b0381d4-65f6-11ee-8c99-0242ac120002/patchs", rsrc_verb.GET) expected = "[]" - self.assertEqual(result, expected) + self.assertEqual(result.get_result(), expected) def test_delete_nested_dict_games_patch_API_key(self): self.testapp.process_request( @@ -456,14 +467,14 @@ class Test_RestAPI_DELETE(unittest.TestCase): result = self.testapp.process_request("/games/9b0381d4-65f6-11ee-8c99-0242ac120002/patchs", rsrc_verb.GET) expected = "[]" - self.assertEqual(result, expected) + self.assertEqual(result.get_result(), expected) def test_delete_nested_dict_games_patch_All(self): self.testapp.process_request("/games/9b0381d4-65f6-11ee-8c99-0242ac120002/patchs", rsrc_verb.DELETE) result = self.testapp.process_request("/games/9b0381d4-65f6-11ee-8c99-0242ac120002/patchs", rsrc_verb.GET) expected = "[]" - self.assertEqual(result, expected) + self.assertEqual(result.get_result(), expected) class Test_RestAPI_PERFO(unittest.TestCase): @@ -478,13 +489,13 @@ class Test_RestAPI_PERFO(unittest.TestCase): n_loop = 10000 start = time() - for i in range(n_loop): + for _ in range(n_loop): self.testapp.process_request(f"/users/8da57a3c-661f-11ee-8c99-0242ac120002", rsrc_verb.GET) end = time() print(f"GET 1st level dict: {int(n_loop/(end-start))} Req/s") start = time() - for i in range(n_loop): + for _ in range(n_loop): newUUID = uuid4() self.testapp.process_request( f"/users?API_key={newUUID}", @@ -495,7 +506,7 @@ class Test_RestAPI_PERFO(unittest.TestCase): print(f"POST 1st level dict (API_key): {int(n_loop/(end-start))} Req/s") start = time() - for i in range(n_loop): + for _ in range(n_loop): newUUID = uuid4() self.testapp.process_request( f"/users?API_key={newUUID}", @@ -507,14 +518,14 @@ class Test_RestAPI_PERFO(unittest.TestCase): print(f"POST/GET 1st level dict (API_key): {int(n_loop/(end-start))} Req/s") start = time() - for i in range(n_loop): + for _ in range(n_loop): result = self.testapp.process_request(f"/users", rsrc_verb.POST, '{"name": "testUser", "secret": "test"}') - self.testapp.process_request(f"/users/{json.loads(result)}", rsrc_verb.GET) + self.testapp.process_request(f"/users/{json.loads(result.get_result())}", rsrc_verb.GET) end = time() print(f"POST/GET 1st level dict (autokey): {int(n_loop/(end-start))} Req/s") start = time() - for i in range(n_loop): + for _ in range(n_loop): self.testapp.process_request( f"/games/9b0381d4-65f6-11ee-8c99-0242ac120002/shortname", rsrc_verb.PUT, @@ -525,7 +536,7 @@ class Test_RestAPI_PERFO(unittest.TestCase): print(f"PUT/GET 1st level (value) dict: {int(n_loop/(end-start))} Req/s") start = time() - for i in range(n_loop): + for _ in range(n_loop): self.testapp.process_request( f"/games/9b0381d4-65f6-11ee-8c99-0242ac120002/patchs/cee1e870-65fa-11ee-8c99-0242ac120002", rsrc_verb.GET, @@ -534,7 +545,7 @@ class Test_RestAPI_PERFO(unittest.TestCase): print(f"GET 2nd level dict: {int(n_loop/(end-start))} Req/s") start = time() - for i in range(n_loop): + for _ in range(n_loop): self.testapp.process_request( f"/games/9b0381d4-65f6-11ee-8c99-0242ac120002/patchs/cee1e870-65fa-11ee-8c99-0242ac120002/shortname", rsrc_verb.GET, @@ -543,7 +554,7 @@ class Test_RestAPI_PERFO(unittest.TestCase): print(f"GET 2nd level (value) dict: {int(n_loop/(end-start))} Req/s") start = time() - for i in range(n_loop): + for _ in range(n_loop): self.testapp.process_request( f"/games/9b0381d4-65f6-11ee-8c99-0242ac120002/patchs/cee1e870-65fa-11ee-8c99-0242ac120002/shortname", rsrc_verb.PUT, diff --git a/test/test_rest_resource_plugins.py b/test/test_rest_resource_plugins.py index ac40326..cffa355 100644 --- a/test/test_rest_resource_plugins.py +++ b/test/test_rest_resource_plugins.py @@ -1,16 +1,9 @@ from __future__ import annotations import unittest -from unittest.mock import patch from os import chdir from pathlib import Path -from typing import Optional, Annotated +from typing import Annotated from pydantic import Field -from uuid import UUID, uuid4 -from time import time -import json - -print(__name__) -print(__package__) from src.pyrestresource import ( register_rest_rootpoint, @@ -24,7 +17,6 @@ from src.pyrestresource import ( ResourcePlugin_field_default, ResourcePlugin_RestResourceBase_default, ) -from pprint import pprint testdir_path = Path(__file__).parent.resolve() chdir(testdir_path.parent.resolve()) @@ -133,16 +125,16 @@ class Test_RestAPI_Plugin_PUT(unittest.TestCase): self.testapp.process_request("/info_put/version", rsrc_verb.PUT, '"1.5.6"') result = self.testapp.process_request("/info_put", rsrc_verb.GET) - print(result) + print(result.get_result()) result = self.testapp.process_request("/info_put/version", rsrc_verb.GET) - print(result) - self.assertEqual(result, '"42"') + print(result.get_result()) + self.assertEqual(result.get_result(), '"42"') def test_put_field_version_resourceplugin(self): self.testapp.process_request("/info_put", rsrc_verb.PUT, '{"version": "1.5.6", "api_version": "98.321"}') result = self.testapp.process_request("/info_put", rsrc_verb.GET) - self.assertEqual(result, '{"version": "42", "api_version": "98.321"}') + self.assertEqual(result.get_result(), '{"version": "42", "api_version": "98.321"}') class Test_RestAPI_Plugin_GET(unittest.TestCase): @@ -153,59 +145,59 @@ class Test_RestAPI_Plugin_GET(unittest.TestCase): def test_get_root(self): result = self.testapp.process_request("/", rsrc_verb.GET) - self.assertEqual(result, "{}") + self.assertEqual(result.get_result(), "{}") def test_get_version(self): result = self.testapp.process_request("/info", rsrc_verb.GET) - self.assertEqual(result, '{"version": "1.5.6", "api_version": "98.321"}') + self.assertEqual(result.get_result(), '{"version": "1.5.6", "api_version": "98.321"}') result = self.testapp.process_request("/info2", rsrc_verb.GET) - self.assertEqual(result, '{"version": "1.5.6", "api_version": "0.0.3"}') + self.assertEqual(result.get_result(), '{"version": "1.5.6", "api_version": "0.0.3"}') def test_get_version__trailing_slash(self): result = self.testapp.process_request("/info/", rsrc_verb.GET) - self.assertEqual(result, '{"version": "1.5.6", "api_version": "98.321"}') + self.assertEqual(result.get_result(), '{"version": "1.5.6", "api_version": "98.321"}') result = self.testapp.process_request("/info//", rsrc_verb.GET) - self.assertEqual(result, '{"version": "1.5.6", "api_version": "98.321"}') + self.assertEqual(result.get_result(), '{"version": "1.5.6", "api_version": "98.321"}') result = self.testapp.process_request("/info///", rsrc_verb.GET) - self.assertEqual(result, '{"version": "1.5.6", "api_version": "98.321"}') + self.assertEqual(result.get_result(), '{"version": "1.5.6", "api_version": "98.321"}') result = self.testapp.process_request("/info2/", rsrc_verb.GET) - self.assertEqual(result, '{"version": "1.5.6", "api_version": "0.0.3"}') + self.assertEqual(result.get_result(), '{"version": "1.5.6", "api_version": "0.0.3"}') result = self.testapp.process_request("/info2//", rsrc_verb.GET) - self.assertEqual(result, '{"version": "1.5.6", "api_version": "0.0.3"}') + self.assertEqual(result.get_result(), '{"version": "1.5.6", "api_version": "0.0.3"}') result = self.testapp.process_request("/info2///", rsrc_verb.GET) - self.assertEqual(result, '{"version": "1.5.6", "api_version": "0.0.3"}') + self.assertEqual(result.get_result(), '{"version": "1.5.6", "api_version": "0.0.3"}') def test_get_version__multiple_slash(self): result = self.testapp.process_request("//info", rsrc_verb.GET) - self.assertEqual(result, '{"version": "1.5.6", "api_version": "98.321"}') + self.assertEqual(result.get_result(), '{"version": "1.5.6", "api_version": "98.321"}') result = self.testapp.process_request("///info", rsrc_verb.GET) - self.assertEqual(result, '{"version": "1.5.6", "api_version": "98.321"}') + self.assertEqual(result.get_result(), '{"version": "1.5.6", "api_version": "98.321"}') result = self.testapp.process_request("//info2", rsrc_verb.GET) - self.assertEqual(result, '{"version": "1.5.6", "api_version": "0.0.3"}') + self.assertEqual(result.get_result(), '{"version": "1.5.6", "api_version": "0.0.3"}') result = self.testapp.process_request("///info2", rsrc_verb.GET) - self.assertEqual(result, '{"version": "1.5.6", "api_version": "0.0.3"}') + self.assertEqual(result.get_result(), '{"version": "1.5.6", "api_version": "0.0.3"}') def test_get_version__nested_value(self): result = self.testapp.process_request("/info/api_version", rsrc_verb.GET) - self.assertEqual(result, '"98.321"') + self.assertEqual(result.get_result(), '"98.321"') result = self.testapp.process_request("/info/version", rsrc_verb.GET) - self.assertEqual(result, '"1.5.6"') + self.assertEqual(result.get_result(), '"1.5.6"') result = self.testapp.process_request("/info2/api_version", rsrc_verb.GET) - self.assertEqual(result, '"0.0.3"') + self.assertEqual(result.get_result(), '"0.0.3"') result = self.testapp.process_request("/info2/version", rsrc_verb.GET) - self.assertEqual(result, '"1.5.6"') + self.assertEqual(result.get_result(), '"1.5.6"') def test_defect_plugin_field(self): with self.assertRaises(RuntimeError): diff --git a/test/test_rest_resource_walker.py b/test/test_rest_resource_walker.py index d562dc5..ecaefd2 100644 --- a/test/test_rest_resource_walker.py +++ b/test/test_rest_resource_walker.py @@ -1,13 +1,13 @@ from __future__ import annotations import unittest -from typing import Optional, cast +from typing import Optional from os import chdir from pathlib import Path from pydantic import Field from io import StringIO -from contextlib import redirect_stdout, redirect_stderr +from contextlib import redirect_stdout print(__name__) print(__package__) diff --git a/test/test_rest_resource_walker_tree.py b/test/test_rest_resource_walker_tree.py index 8ae2a48..afaeb40 100644 --- a/test/test_rest_resource_walker_tree.py +++ b/test/test_rest_resource_walker_tree.py @@ -1,13 +1,12 @@ from __future__ import annotations import unittest -from typing import Annotated, Optional +from typing import Optional from os import chdir from pathlib import Path from pydantic import Field -from io import StringIO -from contextlib import redirect_stdout, redirect_stderr + print(__name__) print(__package__) diff --git a/test/test_rest_webserver.py b/test/test_rest_webserver.py index 76033a9..6eebc21 100644 --- a/test/test_rest_webserver.py +++ b/test/test_rest_webserver.py @@ -117,8 +117,6 @@ def find_free_port(): with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s: s.bind(("", 0)) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - hostname = socket.gethostname() - IPAddr = socket.gethostbyname(hostname) return "localhost", s.getsockname()[1]