|
1 | 1 | from __future__ import annotations
|
2 | 2 |
|
| 3 | +import json |
3 | 4 | from unittest import mock
|
4 | 5 | from unittest.mock import Mock
|
5 | 6 |
|
6 | 7 | import impit
|
| 8 | +import pytest |
7 | 9 |
|
8 | 10 | from integration.integration_test_utils import parametrized_api_urls, random_resource_name
|
9 | 11 |
|
10 | 12 | from apify_client import ApifyClient, ApifyClientAsync
|
11 | 13 | from apify_client.client import DEFAULT_API_URL
|
12 | 14 |
|
13 |
| -MOCKED_API_KVS_RESPONSE = """{ |
14 |
| - "data": { |
15 |
| - "id": "someID", |
16 |
| - "name": "name", |
17 |
| - "userId": "userId", |
18 |
| - "createdAt": "2025-09-11T08:48:51.806Z", |
19 |
| - "modifiedAt": "2025-09-11T08:48:51.806Z", |
20 |
| - "accessedAt": "2025-09-11T08:48:51.806Z", |
21 |
| - "actId": null, |
22 |
| - "actRunId": null, |
23 |
| - "schema": null, |
24 |
| - "stats": { |
25 |
| - "readCount": 0, |
26 |
| - "writeCount": 0, |
27 |
| - "deleteCount": 0, |
28 |
| - "listCount": 0, |
29 |
| - "storageBytes": 0 |
30 |
| - }, |
31 |
| - "consoleUrl": "https://console.apify.com/storage/key-value-stores/someID", |
32 |
| - "keysPublicUrl": "https://api.apify.com/v2/key-value-stores/someID/keys", |
33 |
| - "generalAccess": "FOLLOW_USER_SETTING", |
34 |
| - "urlSigningSecretKey": "urlSigningSecretKey" |
35 |
| - } |
36 |
| -}""" |
| 15 | + |
| 16 | +def _get_mocked_api_kvs_response(signing_key: str | None = None) -> str: |
| 17 | + response_data = { |
| 18 | + 'data': { |
| 19 | + 'id': 'someID', |
| 20 | + 'name': 'name', |
| 21 | + 'userId': 'userId', |
| 22 | + 'createdAt': '2025-09-11T08:48:51.806Z', |
| 23 | + 'modifiedAt': '2025-09-11T08:48:51.806Z', |
| 24 | + 'accessedAt': '2025-09-11T08:48:51.806Z', |
| 25 | + 'actId': None, |
| 26 | + 'actRunId': None, |
| 27 | + 'schema': None, |
| 28 | + 'stats': {'readCount': 0, 'writeCount': 0, 'deleteCount': 0, 'listCount': 0, 'storageBytes': 0}, |
| 29 | + 'consoleUrl': 'https://console.apify.com/storage/key-value-stores/someID', |
| 30 | + 'keysPublicUrl': 'https://api.apify.com/v2/key-value-stores/someID/keys', |
| 31 | + 'generalAccess': 'FOLLOW_USER_SETTING', |
| 32 | + } |
| 33 | + } |
| 34 | + if signing_key: |
| 35 | + response_data['data']['urlSigningSecretKey'] = signing_key |
| 36 | + |
| 37 | + return json.dumps(response_data) |
37 | 38 |
|
38 | 39 |
|
39 | 40 | class TestKeyValueStoreSync:
|
@@ -73,17 +74,22 @@ def test_key_value_store_should_create_public_keys_non_expiring_url(self, apify_
|
73 | 74 | store.delete()
|
74 | 75 | assert apify_client.key_value_store(created_store['id']).get() is None
|
75 | 76 |
|
| 77 | + @pytest.mark.parametrize('signature', [None, 'custom-signature']) |
76 | 78 | @parametrized_api_urls
|
77 |
| - def test_public_url(self, api_token: str, api_url: str, api_public_url: str) -> None: |
| 79 | + def test_public_url(self, api_token: str, api_url: str, api_public_url: str, signature: str) -> None: |
78 | 80 | apify_client = ApifyClient(token=api_token, api_url=api_url, api_public_url=api_public_url)
|
79 | 81 | kvs = apify_client.key_value_store('someID')
|
80 | 82 |
|
81 | 83 | # Mock the API call to return predefined response
|
82 |
| - with mock.patch.object(apify_client.http_client, 'call', return_value=Mock(text=MOCKED_API_KVS_RESPONSE)): |
| 84 | + with mock.patch.object( |
| 85 | + apify_client.http_client, |
| 86 | + 'call', |
| 87 | + return_value=Mock(text=_get_mocked_api_kvs_response(signing_key=signature)), |
| 88 | + ): |
83 | 89 | public_url = kvs.create_keys_public_url()
|
| 90 | + expected_signature = f'?signature={public_url.split("signature=")[1]}' if signature else '' |
84 | 91 | assert public_url == (
|
85 |
| - f'{(api_public_url or DEFAULT_API_URL).strip("/")}/v2/key-value-stores/' |
86 |
| - f'someID/keys?signature={public_url.split("signature=")[1]}' |
| 92 | + f'{(api_public_url or DEFAULT_API_URL).strip("/")}/v2/key-value-stores/someID/keys{expected_signature}' |
87 | 93 | )
|
88 | 94 |
|
89 | 95 |
|
@@ -130,15 +136,20 @@ async def test_key_value_store_should_create_public_keys_non_expiring_url(
|
130 | 136 | await store.delete()
|
131 | 137 | assert await apify_client_async.key_value_store(created_store['id']).get() is None
|
132 | 138 |
|
| 139 | + @pytest.mark.parametrize('signature', [None, 'custom-signature']) |
133 | 140 | @parametrized_api_urls
|
134 |
| - async def test_public_url(self, api_token: str, api_url: str, api_public_url: str) -> None: |
| 141 | + async def test_public_url(self, api_token: str, api_url: str, api_public_url: str, signature: str) -> None: |
135 | 142 | apify_client = ApifyClientAsync(token=api_token, api_url=api_url, api_public_url=api_public_url)
|
136 | 143 | kvs = apify_client.key_value_store('someID')
|
137 | 144 |
|
138 | 145 | # Mock the API call to return predefined response
|
139 |
| - with mock.patch.object(apify_client.http_client, 'call', return_value=Mock(text=MOCKED_API_KVS_RESPONSE)): |
| 146 | + with mock.patch.object( |
| 147 | + apify_client.http_client, |
| 148 | + 'call', |
| 149 | + return_value=Mock(text=_get_mocked_api_kvs_response(signing_key=signature)), |
| 150 | + ): |
140 | 151 | public_url = await kvs.create_keys_public_url()
|
| 152 | + expected_signature = f'?signature={public_url.split("signature=")[1]}' if signature else '' |
141 | 153 | assert public_url == (
|
142 |
| - f'{(api_public_url or DEFAULT_API_URL).strip("/")}/v2/key-value-stores/' |
143 |
| - f'someID/keys?signature={public_url.split("signature=")[1]}' |
| 154 | + f'{(api_public_url or DEFAULT_API_URL).strip("/")}/v2/key-value-stores/someID/keys{expected_signature}' |
144 | 155 | )
|
0 commit comments