diff --git a/mpt_api_client/resources/accounts/users.py b/mpt_api_client/resources/accounts/users.py index 5409c398..d481f689 100644 --- a/mpt_api_client/resources/accounts/users.py +++ b/mpt_api_client/resources/accounts/users.py @@ -52,6 +52,17 @@ def sso_check(self, resource_id: str, resource_data: ResourceData | None = None) """ return self._resource_action(resource_id, "POST", "sso-check", json=resource_data) + def set_password(self, resource_id: str, password: str) -> User: + """Set password for a user. + + Args: + resource_id: Resource ID + password: New password + """ + resource_data = {"password": password} + + return self._resource_action(resource_id, "POST", "set-password", json=resource_data) + class AsyncUsersService( AsyncUpdateMixin[User], @@ -79,3 +90,14 @@ async def sso_check(self, resource_id: str, resource_data: ResourceData | None = resource_data: Resource data will be updated """ return await self._resource_action(resource_id, "POST", "sso-check", json=resource_data) + + async def set_password(self, resource_id: str, password: str) -> User: + """Set password for a user. + + Args: + resource_id: Resource ID + password: New password + """ + resource_data = {"password": password} + + return await self._resource_action(resource_id, "POST", "set-password", json=resource_data) diff --git a/setup.cfg b/setup.cfg index a6ce265f..cc6472de 100644 --- a/setup.cfg +++ b/setup.cfg @@ -45,6 +45,7 @@ per-file-ignores = tests/http/test_mixins.py: WPS204 WPS202 tests/resources/catalog/test_products.py: WPS202 WPS210 tests/resources/*/test_mixins.py: WPS118 WPS202 WPS204 WPS235 + tests/resources/accounts/test_users.py: WPS204 WPS202 WPS210 tests/test_mpt_client.py: WPS235 tests/*: diff --git a/tests/resources/accounts/test_users.py b/tests/resources/accounts/test_users.py index 6fff635c..733960d2 100644 --- a/tests/resources/accounts/test_users.py +++ b/tests/resources/accounts/test_users.py @@ -16,14 +16,14 @@ def async_users_service(async_http_client): @pytest.mark.parametrize( - "method", ["get", "update", "delete", "block", "unblock", "sso", "sso_check"] + "method", ["get", "update", "delete", "block", "unblock", "sso", "sso_check", "set_password"] ) def test_mixins_present(users_service, method): assert hasattr(users_service, method) @pytest.mark.parametrize( - "method", ["get", "update", "delete", "block", "unblock", "sso", "sso_check"] + "method", ["get", "update", "delete", "block", "unblock", "sso", "sso_check", "set_password"] ) def test_async_mixins_present(async_users_service, method): assert hasattr(async_users_service, method) @@ -36,7 +36,7 @@ def test_async_mixins_present(async_users_service, method): ("sso_check", {"id": "OBJ-0000-0001", "status": "update"}), ], ) -def test_sso_resource_actions(users_service, action, input_status): +def test_resource_actions(users_service, action, input_status): request_expected_content = b'{"id":"OBJ-0000-0001","status":"update"}' response_expected_data = {"id": "OBJ-0000-0001", "status": "new_status"} with respx.mock: @@ -65,7 +65,7 @@ def test_sso_resource_actions(users_service, action, input_status): ("sso_check", None), ], ) -def test_sso_resource_actions_no_data(users_service, action, input_status): +def test_resource_actions_no_data(users_service, action, input_status): request_expected_content = b"" response_expected_data = {"id": "OBJ-0000-0001", "status": "new_status"} with respx.mock: @@ -94,7 +94,7 @@ def test_sso_resource_actions_no_data(users_service, action, input_status): ("sso_check", {"id": "OBJ-0000-0001", "status": "update"}), ], ) -async def test_async_sso_resource_actions(async_users_service, action, input_status): +async def test_async_resource_actions(async_users_service, action, input_status): request_expected_content = b'{"id":"OBJ-0000-0001","status":"update"}' response_expected_data = {"id": "OBJ-0000-0001", "status": "new_status"} with respx.mock: @@ -123,7 +123,7 @@ async def test_async_sso_resource_actions(async_users_service, action, input_sta ("sso_check", None), ], ) -async def test_async_sso_resource_actions_no_data(async_users_service, action, input_status): +async def test_async_resource_actions_no_data(async_users_service, action, input_status): request_expected_content = b"" response_expected_data = {"id": "OBJ-0000-0001", "status": "new_status"} with respx.mock: @@ -143,3 +143,61 @@ async def test_async_sso_resource_actions_no_data(async_users_service, action, i assert request.content == request_expected_content assert blockable_obj.to_dict() == response_expected_data assert isinstance(blockable_obj, User) + + +@pytest.mark.parametrize( + ("action", "input_password"), + [ + ("set_password", "new-password-123"), + ], +) +def test_set_password_action(users_service, action, input_password): + request_expected_content_str = f'{{"password":"{input_password}"}}' + request_expected_content = request_expected_content_str.encode() + response_expected_data = {"password": input_password} + with respx.mock: + mock_route = respx.post( + "https://api.example.com/public/v1/" + f"accounts/users/OBJ-0000-0001/{action.replace('_', '-')}" + ).mock( + return_value=httpx.Response( + status_code=httpx.codes.OK, + json=response_expected_data, + ) + ) + blockable_obj = getattr(users_service, action)("OBJ-0000-0001", input_password) + + request = mock_route.calls[0].request + + assert request.content == request_expected_content + assert blockable_obj.to_dict() == response_expected_data + assert isinstance(blockable_obj, User) + + +@pytest.mark.parametrize( + ("action", "input_password"), + [ + ("set_password", "new-password-123"), + ], +) +async def test_async_set_password_action(async_users_service, action, input_password): + request_expected_content_str = f'{{"password":"{input_password}"}}' + request_expected_content = request_expected_content_str.encode() + response_expected_data = {"password": input_password} + with respx.mock: + mock_route = respx.post( + "https://api.example.com/public/v1/" + f"accounts/users/OBJ-0000-0001/{action.replace('_', '-')}" + ).mock( + return_value=httpx.Response( + status_code=httpx.codes.OK, + json=response_expected_data, + ) + ) + blockable_obj = await getattr(async_users_service, action)("OBJ-0000-0001", input_password) + + request = mock_route.calls[0].request + + assert request.content == request_expected_content + assert blockable_obj.to_dict() == response_expected_data + assert isinstance(blockable_obj, User)