diff --git a/src/onepasswordconnectsdk/utils.py b/src/onepasswordconnectsdk/utils.py index 124aadd..ab7477d 100644 --- a/src/onepasswordconnectsdk/utils.py +++ b/src/onepasswordconnectsdk/utils.py @@ -1,4 +1,5 @@ import os +from urllib.parse import quote, urlencode from httpx._client import DEFAULT_TIMEOUT_CONFIG, Timeout @@ -55,7 +56,7 @@ def content(self) -> 'PathBuilder': return self def query(self, key: str, value: str) -> 'PathBuilder': - key_value_pair = f"{key}={value}" + key_value_pair = urlencode({key: value}, quote_via=quote) self._append_path(query=key_value_pair) return self diff --git a/src/tests/test_client_items.py b/src/tests/test_client_items.py index eae6634..e46985d 100644 --- a/src/tests/test_client_items.py +++ b/src/tests/test_client_items.py @@ -42,30 +42,32 @@ async def test_get_item_by_id_async(respx_mock): assert mock.called -def test_get_item_by_title(respx_mock): +@pytest.mark.parametrize('title', [ITEM_TITLE, 'Login+A&B#1%20', 'caf\u00e9']) +def test_get_item_by_title(respx_mock, title): expected_item = get_item() - expected_path_item_title = f"/v1/vaults/{VAULT_ID}/items?filter=title eq \"{ITEM_TITLE}\"" + expected_path_item_title = f"/v1/vaults/{VAULT_ID}/items" expected_path_item = f"/v1/vaults/{VAULT_ID}/items/{ITEM_ID}" - items_summary_mock = respx_mock.get(expected_path_item_title).mock(return_value=Response(200, json=get_items())) + items_summary_mock = respx_mock.get(expected_path_item_title, params={'filter': f'title eq "{title}"'}).mock(return_value=Response(200, json=get_items())) item_mock = respx_mock.get(expected_path_item).mock(return_value=Response(200, json=expected_item)) - item = SS_CLIENT.get_item_by_title(ITEM_TITLE, VAULT_ID) + item = SS_CLIENT.get_item_by_title(title, VAULT_ID) compare_items(expected_item, item) assert items_summary_mock.called assert item_mock.called @pytest.mark.asyncio -async def test_get_item_by_title_async(respx_mock): +@pytest.mark.parametrize('title', [ITEM_TITLE, 'Login+A&B#1%20', 'caf\u00e9']) +async def test_get_item_by_title_async(respx_mock, title): expected_item = get_item() - expected_path_item_title = f"/v1/vaults/{VAULT_ID}/items?filter=title eq \"{ITEM_TITLE}\"" + expected_path_item_title = f"/v1/vaults/{VAULT_ID}/items" expected_path_item = f"/v1/vaults/{VAULT_ID}/items/{ITEM_ID}" - items_summary_mock = respx_mock.get(expected_path_item_title).mock(return_value=Response(200, json=get_items())) + items_summary_mock = respx_mock.get(expected_path_item_title, params={'filter': f'title eq "{title}"'}).mock(return_value=Response(200, json=get_items())) item_mock = respx_mock.get(expected_path_item).mock(return_value=Response(200, json=expected_item)) - item = await SS_CLIENT_ASYNC.get_item_by_title(ITEM_TITLE, VAULT_ID) + item = await SS_CLIENT_ASYNC.get_item_by_title(title, VAULT_ID) compare_items(expected_item, item) assert items_summary_mock.called assert item_mock.called diff --git a/src/tests/test_client_vaults.py b/src/tests/test_client_vaults.py index 9a3eab3..180773d 100644 --- a/src/tests/test_client_vaults.py +++ b/src/tests/test_client_vaults.py @@ -56,25 +56,27 @@ async def test_get_vault_async(respx_mock): assert mock.called -def test_get_vault_by_title(respx_mock): +@pytest.mark.parametrize('title', [VAULT_NAME, 'Vault+A&B#1%20', 'caf\u00e9']) +def test_get_vault_by_title(respx_mock, title): expected_vaults = list_vaults() - expected_path = f"/v1/vaults?filter=name eq \"{VAULT_NAME}\"" + expected_path = '/v1/vaults' - mock = respx_mock.get(expected_path).mock(return_value=Response(200, json=expected_vaults)) + mock = respx_mock.get(expected_path, params={'filter': f'name eq "{title}"'}).mock(return_value=Response(200, json=expected_vaults)) - vault = SS_CLIENT.get_vault_by_title(VAULT_NAME) + vault = SS_CLIENT.get_vault_by_title(title) compare_vaults(expected_vaults[0], vault) assert mock.called @pytest.mark.asyncio -async def test_get_vault_by_title_async(respx_mock): +@pytest.mark.parametrize('title', [VAULT_NAME, 'Vault+A&B#1%20', 'caf\u00e9']) +async def test_get_vault_by_title_async(respx_mock, title): expected_vaults = list_vaults() - expected_path = f"/v1/vaults?filter=name eq \"{VAULT_NAME}\"" + expected_path = '/v1/vaults' - mock = respx_mock.get(expected_path).mock(return_value=Response(200, json=expected_vaults)) + mock = respx_mock.get(expected_path, params={'filter': f'name eq "{title}"'}).mock(return_value=Response(200, json=expected_vaults)) - vault = await SS_CLIENT_ASYNC.get_vault_by_title(VAULT_NAME) + vault = await SS_CLIENT_ASYNC.get_vault_by_title(title) compare_vaults(expected_vaults[0], vault) assert mock.called