pygeai 0.6.0b6__py3-none-any.whl → 0.6.0b7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pygeai/_docs/source/content/api_reference/admin.rst +161 -0
- pygeai/_docs/source/content/api_reference/assistant.rst +326 -0
- pygeai/_docs/source/content/api_reference/auth.rst +379 -0
- pygeai/_docs/source/content/api_reference/health.rst +58 -0
- pygeai/_docs/source/content/api_reference/project.rst +20 -18
- pygeai/_docs/source/content/api_reference/rerank.rst +94 -0
- pygeai/_docs/source/content/api_reference.rst +6 -1
- pygeai/_docs/source/index.rst +59 -7
- pygeai/_docs/source/pygeai.auth.rst +29 -0
- pygeai/_docs/source/pygeai.cli.commands.rst +16 -0
- pygeai/_docs/source/pygeai.core.utils.rst +16 -0
- pygeai/_docs/source/pygeai.rst +1 -0
- pygeai/_docs/source/pygeai.tests.auth.rst +21 -0
- pygeai/_docs/source/pygeai.tests.cli.commands.rst +16 -0
- pygeai/_docs/source/pygeai.tests.core.base.rst +8 -0
- pygeai/_docs/source/pygeai.tests.core.files.rst +8 -0
- pygeai/_docs/source/pygeai.tests.core.plugins.rst +21 -0
- pygeai/_docs/source/pygeai.tests.core.rst +1 -0
- pygeai/_docs/source/pygeai.tests.evaluation.dataset.rst +21 -0
- pygeai/_docs/source/pygeai.tests.evaluation.plan.rst +21 -0
- pygeai/_docs/source/pygeai.tests.evaluation.result.rst +21 -0
- pygeai/_docs/source/pygeai.tests.evaluation.rst +20 -0
- pygeai/_docs/source/pygeai.tests.integration.lab.processes.rst +8 -0
- pygeai/_docs/source/pygeai.tests.organization.rst +8 -0
- pygeai/_docs/source/pygeai.tests.rst +2 -0
- pygeai/_docs/source/pygeai.tests.snippets.auth.rst +10 -0
- pygeai/_docs/source/pygeai.tests.snippets.organization.rst +40 -0
- pygeai/_docs/source/pygeai.tests.snippets.rst +1 -0
- pygeai/admin/clients.py +7 -32
- pygeai/assistant/clients.py +9 -44
- pygeai/assistant/data/clients.py +1 -0
- pygeai/assistant/data_analyst/clients.py +4 -13
- pygeai/assistant/rag/clients.py +13 -67
- pygeai/auth/clients.py +88 -14
- pygeai/auth/endpoints.py +4 -0
- pygeai/chat/clients.py +1 -0
- pygeai/cli/commands/auth.py +178 -2
- pygeai/cli/commands/lab/ai_lab.py +0 -2
- pygeai/cli/commands/organization.py +241 -0
- pygeai/core/base/clients.py +1 -0
- pygeai/core/embeddings/clients.py +3 -7
- pygeai/core/feedback/clients.py +3 -8
- pygeai/core/files/clients.py +5 -18
- pygeai/core/llm/clients.py +7 -26
- pygeai/core/models.py +107 -0
- pygeai/core/plugins/clients.py +3 -7
- pygeai/core/rerank/clients.py +3 -8
- pygeai/core/secrets/clients.py +8 -37
- pygeai/core/utils/parsers.py +32 -0
- pygeai/core/utils/validators.py +10 -0
- pygeai/evaluation/clients.py +1 -0
- pygeai/evaluation/dataset/clients.py +1 -0
- pygeai/evaluation/plan/clients.py +1 -0
- pygeai/evaluation/result/clients.py +1 -0
- pygeai/gam/clients.py +6 -25
- pygeai/health/clients.py +3 -7
- pygeai/lab/agents/clients.py +13 -53
- pygeai/lab/agents/endpoints.py +2 -0
- pygeai/lab/clients.py +1 -0
- pygeai/lab/processes/clients.py +24 -127
- pygeai/lab/strategies/clients.py +7 -25
- pygeai/lab/tools/clients.py +22 -67
- pygeai/lab/tools/endpoints.py +3 -0
- pygeai/organization/clients.py +122 -51
- pygeai/organization/endpoints.py +6 -1
- pygeai/organization/limits/clients.py +17 -91
- pygeai/organization/managers.py +157 -1
- pygeai/organization/mappers.py +76 -2
- pygeai/organization/responses.py +25 -1
- pygeai/proxy/clients.py +1 -0
- pygeai/tests/auth/test_clients.py +183 -7
- pygeai/tests/organization/test_clients.py +184 -1
- pygeai/tests/organization/test_managers.py +122 -1
- pygeai/tests/snippets/auth/__init__.py +0 -0
- pygeai/tests/snippets/organization/get_memberships.py +12 -0
- pygeai/tests/snippets/organization/get_organization_members.py +6 -0
- pygeai/tests/snippets/organization/get_project_members.py +6 -0
- pygeai/tests/snippets/organization/get_project_memberships.py +12 -0
- pygeai/tests/snippets/organization/get_project_roles.py +6 -0
- {pygeai-0.6.0b6.dist-info → pygeai-0.6.0b7.dist-info}/METADATA +1 -1
- {pygeai-0.6.0b6.dist-info → pygeai-0.6.0b7.dist-info}/RECORD +85 -64
- {pygeai-0.6.0b6.dist-info → pygeai-0.6.0b7.dist-info}/WHEEL +0 -0
- {pygeai-0.6.0b6.dist-info → pygeai-0.6.0b7.dist-info}/entry_points.txt +0 -0
- {pygeai-0.6.0b6.dist-info → pygeai-0.6.0b7.dist-info}/licenses/LICENSE +0 -0
- {pygeai-0.6.0b6.dist-info → pygeai-0.6.0b7.dist-info}/top_level.txt +0 -0
|
@@ -3,7 +3,7 @@ from unittest.mock import patch, MagicMock
|
|
|
3
3
|
from json import JSONDecodeError
|
|
4
4
|
|
|
5
5
|
from pygeai.auth.clients import AuthClient
|
|
6
|
-
from pygeai.core.common.exceptions import InvalidAPIResponseException
|
|
6
|
+
from pygeai.core.common.exceptions import InvalidAPIResponseException, APIResponseError
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class TestAuthClient(unittest.TestCase):
|
|
@@ -14,6 +14,7 @@ class TestAuthClient(unittest.TestCase):
|
|
|
14
14
|
def setUp(self):
|
|
15
15
|
self.client = AuthClient()
|
|
16
16
|
self.mock_response = MagicMock()
|
|
17
|
+
self.mock_response.status_code = 200 # Default to success status
|
|
17
18
|
|
|
18
19
|
@patch('pygeai.core.services.rest.ApiService.get')
|
|
19
20
|
def test_get_oauth2_access_token_success(self, mock_get):
|
|
@@ -50,19 +51,18 @@ class TestAuthClient(unittest.TestCase):
|
|
|
50
51
|
self.assertEqual(call_args[1]['params']['scope'], "custom_scope")
|
|
51
52
|
|
|
52
53
|
@patch('pygeai.core.services.rest.ApiService.get')
|
|
53
|
-
def
|
|
54
|
-
self.mock_response.json.side_effect = JSONDecodeError("error", "doc", 0)
|
|
54
|
+
def test_get_oauth2_access_token_error_status(self, mock_get):
|
|
55
55
|
self.mock_response.status_code = 401
|
|
56
56
|
self.mock_response.text = "Invalid credentials"
|
|
57
57
|
mock_get.return_value = self.mock_response
|
|
58
58
|
|
|
59
|
-
with self.assertRaises(
|
|
59
|
+
with self.assertRaises(APIResponseError) as context:
|
|
60
60
|
self.client.get_oauth2_access_token(
|
|
61
61
|
client_id="client-123",
|
|
62
62
|
username="user@example.com",
|
|
63
63
|
password="wrong"
|
|
64
64
|
)
|
|
65
|
-
self.assertIn("
|
|
65
|
+
self.assertIn("API returned an error", str(context.exception))
|
|
66
66
|
|
|
67
67
|
@patch.object(AuthClient, 'api_service', create=True)
|
|
68
68
|
def test_get_user_profile_information_success(self, mock_api_service):
|
|
@@ -96,9 +96,185 @@ class TestAuthClient(unittest.TestCase):
|
|
|
96
96
|
client = AuthClient()
|
|
97
97
|
client.api_service = mock_api_service
|
|
98
98
|
|
|
99
|
-
with self.assertRaises(
|
|
99
|
+
with self.assertRaises(APIResponseError) as context:
|
|
100
100
|
client.get_user_profile_information("invalid-token")
|
|
101
|
-
self.assertIn("
|
|
101
|
+
self.assertIn("API returned an error", str(context.exception))
|
|
102
|
+
|
|
103
|
+
@patch('pygeai.core.services.rest.ApiService.post')
|
|
104
|
+
def test_create_project_api_token_success(self, mock_post):
|
|
105
|
+
self.mock_response.json.return_value = {
|
|
106
|
+
"id": "test_token_id",
|
|
107
|
+
"name": "TestToken",
|
|
108
|
+
"description": "Test Token",
|
|
109
|
+
"status": "Active",
|
|
110
|
+
"scope": "Pia.Data.Organization",
|
|
111
|
+
"organization": "org-123",
|
|
112
|
+
"project": "project-123",
|
|
113
|
+
"messages": [
|
|
114
|
+
{
|
|
115
|
+
"id": 0,
|
|
116
|
+
"description": "Token created successfully",
|
|
117
|
+
"type": "Success"
|
|
118
|
+
}
|
|
119
|
+
],
|
|
120
|
+
"errors": []
|
|
121
|
+
}
|
|
122
|
+
mock_post.return_value = self.mock_response
|
|
123
|
+
|
|
124
|
+
result = self.client.create_project_api_token(
|
|
125
|
+
project_id="project-123",
|
|
126
|
+
name="TestToken",
|
|
127
|
+
description="Test Token"
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
mock_post.assert_called_once()
|
|
131
|
+
call_args = mock_post.call_args
|
|
132
|
+
self.assertEqual(call_args[1]['data']['name'], "TestToken")
|
|
133
|
+
self.assertEqual(call_args[1]['data']['description'], "Test Token")
|
|
134
|
+
self.assertEqual(call_args[1]['headers']['project-id'], "project-123")
|
|
135
|
+
self.assertEqual(result['name'], "TestToken")
|
|
136
|
+
self.assertEqual(result['id'], "test_token_id")
|
|
137
|
+
|
|
138
|
+
@patch('pygeai.core.services.rest.ApiService.post')
|
|
139
|
+
def test_create_project_api_token_without_description(self, mock_post):
|
|
140
|
+
self.mock_response.json.return_value = {
|
|
141
|
+
"id": "test_token_id",
|
|
142
|
+
"name": "TestToken",
|
|
143
|
+
"status": "Active"
|
|
144
|
+
}
|
|
145
|
+
mock_post.return_value = self.mock_response
|
|
146
|
+
|
|
147
|
+
result = self.client.create_project_api_token(
|
|
148
|
+
project_id="project-123",
|
|
149
|
+
name="TestToken"
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
call_args = mock_post.call_args
|
|
153
|
+
self.assertNotIn('description', call_args[1]['data'])
|
|
154
|
+
|
|
155
|
+
@patch('pygeai.core.services.rest.ApiService.post')
|
|
156
|
+
def test_create_project_api_token_json_decode_error(self, mock_post):
|
|
157
|
+
self.mock_response.json.side_effect = JSONDecodeError("error", "doc", 0)
|
|
158
|
+
self.mock_response.status_code = 400
|
|
159
|
+
self.mock_response.text = "Bad request"
|
|
160
|
+
mock_post.return_value = self.mock_response
|
|
161
|
+
|
|
162
|
+
with self.assertRaises(APIResponseError) as context:
|
|
163
|
+
self.client.create_project_api_token(
|
|
164
|
+
project_id="project-123",
|
|
165
|
+
name="TestToken"
|
|
166
|
+
)
|
|
167
|
+
self.assertIn("API returned an error", str(context.exception))
|
|
168
|
+
|
|
169
|
+
@patch('pygeai.core.services.rest.ApiService.delete')
|
|
170
|
+
def test_delete_project_api_token_success(self, mock_delete):
|
|
171
|
+
self.mock_response.json.return_value = {}
|
|
172
|
+
mock_delete.return_value = self.mock_response
|
|
173
|
+
|
|
174
|
+
result = self.client.delete_project_api_token(api_token_id="token-123")
|
|
175
|
+
|
|
176
|
+
mock_delete.assert_called_once()
|
|
177
|
+
call_args = mock_delete.call_args
|
|
178
|
+
self.assertIn("token-123", call_args[1]['endpoint'])
|
|
179
|
+
self.assertEqual(result, {})
|
|
180
|
+
|
|
181
|
+
@patch('pygeai.core.services.rest.ApiService.delete')
|
|
182
|
+
def test_delete_project_api_token_json_decode_error(self, mock_delete):
|
|
183
|
+
self.mock_response.json.side_effect = JSONDecodeError("error", "doc", 0)
|
|
184
|
+
self.mock_response.status_code = 404
|
|
185
|
+
self.mock_response.text = "Not found"
|
|
186
|
+
mock_delete.return_value = self.mock_response
|
|
187
|
+
|
|
188
|
+
with self.assertRaises(APIResponseError) as context:
|
|
189
|
+
self.client.delete_project_api_token(api_token_id="invalid-token")
|
|
190
|
+
self.assertIn("API returned an error", str(context.exception))
|
|
191
|
+
|
|
192
|
+
@patch('pygeai.core.services.rest.ApiService.put')
|
|
193
|
+
def test_update_project_api_token_success(self, mock_put):
|
|
194
|
+
self.mock_response.json.return_value = [
|
|
195
|
+
{
|
|
196
|
+
"description": "Token updated successfully",
|
|
197
|
+
"type": "Success"
|
|
198
|
+
}
|
|
199
|
+
]
|
|
200
|
+
mock_put.return_value = self.mock_response
|
|
201
|
+
|
|
202
|
+
result = self.client.update_project_api_token(
|
|
203
|
+
api_token_id="token-123",
|
|
204
|
+
description="Updated description",
|
|
205
|
+
status="blocked"
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
mock_put.assert_called_once()
|
|
209
|
+
call_args = mock_put.call_args
|
|
210
|
+
self.assertEqual(call_args[1]['data']['description'], "Updated description")
|
|
211
|
+
self.assertEqual(call_args[1]['data']['status'], "blocked")
|
|
212
|
+
self.assertIsInstance(result, list)
|
|
213
|
+
self.assertEqual(result[0]['type'], "Success")
|
|
214
|
+
|
|
215
|
+
@patch('pygeai.core.services.rest.ApiService.put')
|
|
216
|
+
def test_update_project_api_token_only_description(self, mock_put):
|
|
217
|
+
self.mock_response.json.return_value = [
|
|
218
|
+
{
|
|
219
|
+
"description": "Token updated successfully",
|
|
220
|
+
"type": "Success"
|
|
221
|
+
}
|
|
222
|
+
]
|
|
223
|
+
mock_put.return_value = self.mock_response
|
|
224
|
+
|
|
225
|
+
result = self.client.update_project_api_token(
|
|
226
|
+
api_token_id="token-123",
|
|
227
|
+
description="New description"
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
call_args = mock_put.call_args
|
|
231
|
+
self.assertEqual(call_args[1]['data']['description'], "New description")
|
|
232
|
+
self.assertNotIn('status', call_args[1]['data'])
|
|
233
|
+
|
|
234
|
+
@patch('pygeai.core.services.rest.ApiService.put')
|
|
235
|
+
def test_update_project_api_token_json_decode_error(self, mock_put):
|
|
236
|
+
self.mock_response.json.side_effect = JSONDecodeError("error", "doc", 0)
|
|
237
|
+
self.mock_response.status_code = 400
|
|
238
|
+
self.mock_response.text = "Bad request"
|
|
239
|
+
mock_put.return_value = self.mock_response
|
|
240
|
+
|
|
241
|
+
with self.assertRaises(APIResponseError) as context:
|
|
242
|
+
self.client.update_project_api_token(
|
|
243
|
+
api_token_id="token-123",
|
|
244
|
+
description="New description"
|
|
245
|
+
)
|
|
246
|
+
self.assertIn("API returned an error", str(context.exception))
|
|
247
|
+
|
|
248
|
+
@patch('pygeai.core.services.rest.ApiService.get')
|
|
249
|
+
def test_get_project_api_token_success(self, mock_get):
|
|
250
|
+
self.mock_response.json.return_value = {
|
|
251
|
+
"id": "token-123",
|
|
252
|
+
"name": "Default",
|
|
253
|
+
"description": "Default token",
|
|
254
|
+
"status": "Active",
|
|
255
|
+
"scope": "Pia.Data.Organization",
|
|
256
|
+
"timestamp": "2024-07-22T18:37:32.341"
|
|
257
|
+
}
|
|
258
|
+
mock_get.return_value = self.mock_response
|
|
259
|
+
|
|
260
|
+
result = self.client.get_project_api_token(api_token_id="token-123")
|
|
261
|
+
|
|
262
|
+
mock_get.assert_called_once()
|
|
263
|
+
call_args = mock_get.call_args
|
|
264
|
+
self.assertIn("token-123", call_args[1]['endpoint'])
|
|
265
|
+
self.assertEqual(result['id'], "token-123")
|
|
266
|
+
self.assertEqual(result['status'], "Active")
|
|
267
|
+
|
|
268
|
+
@patch('pygeai.core.services.rest.ApiService.get')
|
|
269
|
+
def test_get_project_api_token_json_decode_error(self, mock_get):
|
|
270
|
+
self.mock_response.json.side_effect = JSONDecodeError("error", "doc", 0)
|
|
271
|
+
self.mock_response.status_code = 404
|
|
272
|
+
self.mock_response.text = "Not found"
|
|
273
|
+
mock_get.return_value = self.mock_response
|
|
274
|
+
|
|
275
|
+
with self.assertRaises(APIResponseError) as context:
|
|
276
|
+
self.client.get_project_api_token(api_token_id="invalid-token")
|
|
277
|
+
self.assertIn("API returned an error", str(context.exception))
|
|
102
278
|
|
|
103
279
|
|
|
104
280
|
if __name__ == '__main__':
|
|
@@ -5,7 +5,8 @@ from unittest.mock import patch
|
|
|
5
5
|
from pygeai.organization.clients import OrganizationClient
|
|
6
6
|
from pygeai.core.common.exceptions import InvalidAPIResponseException
|
|
7
7
|
from pygeai.organization.endpoints import GET_ASSISTANT_LIST_V1, GET_PROJECT_LIST_V1, GET_PROJECT_V1, CREATE_PROJECT_V1, \
|
|
8
|
-
UPDATE_PROJECT_V1, DELETE_PROJECT_V1, GET_PROJECT_TOKENS_V1, GET_REQUEST_DATA_V1
|
|
8
|
+
UPDATE_PROJECT_V1, DELETE_PROJECT_V1, GET_PROJECT_TOKENS_V1, GET_REQUEST_DATA_V1, GET_MEMBERSHIPS_V2, \
|
|
9
|
+
GET_PROJECT_MEMBERSHIPS_V2, GET_PROJECT_ROLES_V2, GET_PROJECT_MEMBERS_V2, GET_ORGANIZATION_MEMBERS_V2
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
class TestOrganizationClient(unittest.TestCase):
|
|
@@ -293,3 +294,185 @@ class TestOrganizationClient(unittest.TestCase):
|
|
|
293
294
|
)
|
|
294
295
|
self.assertEqual(str(context.exception), "Unable to export request data: Invalid JSON response")
|
|
295
296
|
|
|
297
|
+
@patch("pygeai.core.services.rest.ApiService.get")
|
|
298
|
+
def test_get_memberships_success(self, mock_get):
|
|
299
|
+
mock_response = mock_get.return_value
|
|
300
|
+
mock_response.json.return_value = {
|
|
301
|
+
"count": 1,
|
|
302
|
+
"pages": 1,
|
|
303
|
+
"organizationsMemberships": [
|
|
304
|
+
{
|
|
305
|
+
"organizationId": "org-123",
|
|
306
|
+
"organizationName": "Test Org",
|
|
307
|
+
"projectsMemberships": []
|
|
308
|
+
}
|
|
309
|
+
]
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
result = self.client.get_memberships()
|
|
313
|
+
|
|
314
|
+
mock_get.assert_called_once_with(
|
|
315
|
+
endpoint=GET_MEMBERSHIPS_V2,
|
|
316
|
+
params={"startPage": 1, "pageSize": 20, "orderDirection": "desc"}
|
|
317
|
+
)
|
|
318
|
+
self.assertIsNotNone(result)
|
|
319
|
+
self.assertEqual(result['count'], 1)
|
|
320
|
+
|
|
321
|
+
@patch("pygeai.core.services.rest.ApiService.get")
|
|
322
|
+
def test_get_memberships_with_params(self, mock_get):
|
|
323
|
+
mock_response = mock_get.return_value
|
|
324
|
+
mock_response.json.return_value = {"count": 0, "pages": 0, "organizationsMemberships": []}
|
|
325
|
+
|
|
326
|
+
result = self.client.get_memberships(
|
|
327
|
+
email="test@example.com",
|
|
328
|
+
start_page=2,
|
|
329
|
+
page_size=10,
|
|
330
|
+
order_key="organizationName",
|
|
331
|
+
order_direction="asc",
|
|
332
|
+
role_types="backend,frontend"
|
|
333
|
+
)
|
|
334
|
+
|
|
335
|
+
mock_get.assert_called_once_with(
|
|
336
|
+
endpoint=GET_MEMBERSHIPS_V2,
|
|
337
|
+
params={
|
|
338
|
+
"email": "test@example.com",
|
|
339
|
+
"startPage": 2,
|
|
340
|
+
"pageSize": 10,
|
|
341
|
+
"orderKey": "organizationName",
|
|
342
|
+
"orderDirection": "asc",
|
|
343
|
+
"roleTypes": "backend,frontend"
|
|
344
|
+
}
|
|
345
|
+
)
|
|
346
|
+
self.assertIsNotNone(result)
|
|
347
|
+
|
|
348
|
+
@patch("pygeai.core.services.rest.ApiService.get")
|
|
349
|
+
def test_get_memberships_json_decode_error(self, mock_get):
|
|
350
|
+
mock_response = mock_get.return_value
|
|
351
|
+
mock_response.status_code = 200
|
|
352
|
+
mock_response.json.side_effect = JSONDecodeError("Invalid JSON", "", 0)
|
|
353
|
+
mock_response.text = "Invalid JSON response"
|
|
354
|
+
|
|
355
|
+
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
356
|
+
self.client.get_memberships()
|
|
357
|
+
|
|
358
|
+
self.assertEqual(str(context.exception), "Unable to get memberships: Invalid JSON response")
|
|
359
|
+
|
|
360
|
+
@patch("pygeai.core.services.rest.ApiService.get")
|
|
361
|
+
def test_get_project_memberships_success(self, mock_get):
|
|
362
|
+
mock_response = mock_get.return_value
|
|
363
|
+
mock_response.json.return_value = {
|
|
364
|
+
"count": 1,
|
|
365
|
+
"pages": 1,
|
|
366
|
+
"projectsMemberships": [
|
|
367
|
+
{
|
|
368
|
+
"organizationId": "org-123",
|
|
369
|
+
"organizationName": "Test Org",
|
|
370
|
+
"projectId": "proj-456",
|
|
371
|
+
"projectName": "Test Project",
|
|
372
|
+
"roles": []
|
|
373
|
+
}
|
|
374
|
+
]
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
result = self.client.get_project_memberships()
|
|
378
|
+
|
|
379
|
+
mock_get.assert_called_once_with(
|
|
380
|
+
endpoint=GET_PROJECT_MEMBERSHIPS_V2,
|
|
381
|
+
params={"startPage": 1, "pageSize": 20, "orderDirection": "desc"}
|
|
382
|
+
)
|
|
383
|
+
self.assertIsNotNone(result)
|
|
384
|
+
self.assertEqual(result['count'], 1)
|
|
385
|
+
|
|
386
|
+
@patch("pygeai.core.services.rest.ApiService.get")
|
|
387
|
+
def test_get_project_memberships_json_decode_error(self, mock_get):
|
|
388
|
+
mock_response = mock_get.return_value
|
|
389
|
+
mock_response.status_code = 200
|
|
390
|
+
mock_response.json.side_effect = JSONDecodeError("Invalid JSON", "", 0)
|
|
391
|
+
mock_response.text = "Invalid JSON response"
|
|
392
|
+
|
|
393
|
+
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
394
|
+
self.client.get_project_memberships()
|
|
395
|
+
|
|
396
|
+
self.assertEqual(str(context.exception), "Unable to get project memberships: Invalid JSON response")
|
|
397
|
+
|
|
398
|
+
@patch("pygeai.core.services.rest.ApiService.get")
|
|
399
|
+
def test_get_project_roles_success(self, mock_get):
|
|
400
|
+
mock_response = mock_get.return_value
|
|
401
|
+
mock_response.json.return_value = {
|
|
402
|
+
"roles": [
|
|
403
|
+
{"id": "role-1", "name": "Admin", "externalId": "admin-ext", "type": "backend", "origin": "system"}
|
|
404
|
+
]
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
result = self.client.get_project_roles(project_id="proj-123")
|
|
408
|
+
|
|
409
|
+
mock_get.assert_called_once_with(endpoint=GET_PROJECT_ROLES_V2, params={"projectId": "proj-123"})
|
|
410
|
+
self.assertIsNotNone(result)
|
|
411
|
+
self.assertEqual(len(result['roles']), 1)
|
|
412
|
+
|
|
413
|
+
@patch("pygeai.core.services.rest.ApiService.get")
|
|
414
|
+
def test_get_project_roles_json_decode_error(self, mock_get):
|
|
415
|
+
mock_response = mock_get.return_value
|
|
416
|
+
mock_response.status_code = 200
|
|
417
|
+
mock_response.json.side_effect = JSONDecodeError("Invalid JSON", "", 0)
|
|
418
|
+
mock_response.text = "Invalid JSON response"
|
|
419
|
+
|
|
420
|
+
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
421
|
+
self.client.get_project_roles(project_id="proj-123")
|
|
422
|
+
|
|
423
|
+
self.assertEqual(str(context.exception), "Unable to get project roles for project 'proj-123': Invalid JSON response")
|
|
424
|
+
|
|
425
|
+
@patch("pygeai.core.services.rest.ApiService.get")
|
|
426
|
+
def test_get_project_members_success(self, mock_get):
|
|
427
|
+
mock_response = mock_get.return_value
|
|
428
|
+
mock_response.json.return_value = {
|
|
429
|
+
"members": [
|
|
430
|
+
{"email": "user@example.com", "roles": []}
|
|
431
|
+
]
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
result = self.client.get_project_members(project_id="proj-123")
|
|
435
|
+
|
|
436
|
+
mock_get.assert_called_once_with(endpoint=GET_PROJECT_MEMBERS_V2, params={"projectId": "proj-123"})
|
|
437
|
+
self.assertIsNotNone(result)
|
|
438
|
+
self.assertEqual(len(result['members']), 1)
|
|
439
|
+
|
|
440
|
+
@patch("pygeai.core.services.rest.ApiService.get")
|
|
441
|
+
def test_get_project_members_json_decode_error(self, mock_get):
|
|
442
|
+
mock_response = mock_get.return_value
|
|
443
|
+
mock_response.status_code = 200
|
|
444
|
+
mock_response.json.side_effect = JSONDecodeError("Invalid JSON", "", 0)
|
|
445
|
+
mock_response.text = "Invalid JSON response"
|
|
446
|
+
|
|
447
|
+
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
448
|
+
self.client.get_project_members(project_id="proj-123")
|
|
449
|
+
|
|
450
|
+
self.assertEqual(str(context.exception), "Unable to get project members for project 'proj-123': Invalid JSON response")
|
|
451
|
+
|
|
452
|
+
@patch("pygeai.core.services.rest.ApiService.get")
|
|
453
|
+
def test_get_organization_members_success(self, mock_get):
|
|
454
|
+
mock_response = mock_get.return_value
|
|
455
|
+
mock_response.json.return_value = {
|
|
456
|
+
"members": [
|
|
457
|
+
{"email": "user@example.com", "roles": []}
|
|
458
|
+
]
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
result = self.client.get_organization_members(organization_id="org-123")
|
|
462
|
+
|
|
463
|
+
mock_get.assert_called_once_with(endpoint=GET_ORGANIZATION_MEMBERS_V2, params={"organizationId": "org-123"})
|
|
464
|
+
self.assertIsNotNone(result)
|
|
465
|
+
self.assertEqual(len(result['members']), 1)
|
|
466
|
+
|
|
467
|
+
@patch("pygeai.core.services.rest.ApiService.get")
|
|
468
|
+
def test_get_organization_members_json_decode_error(self, mock_get):
|
|
469
|
+
mock_response = mock_get.return_value
|
|
470
|
+
mock_response.status_code = 200
|
|
471
|
+
mock_response.json.side_effect = JSONDecodeError("Invalid JSON", "", 0)
|
|
472
|
+
mock_response.text = "Invalid JSON response"
|
|
473
|
+
|
|
474
|
+
with self.assertRaises(InvalidAPIResponseException) as context:
|
|
475
|
+
self.client.get_organization_members(organization_id="org-123")
|
|
476
|
+
|
|
477
|
+
self.assertEqual(str(context.exception), "Unable to get organization members for organization 'org-123': Invalid JSON response")
|
|
478
|
+
|
|
@@ -9,7 +9,8 @@ from pygeai.core.base.responses import EmptyResponse
|
|
|
9
9
|
from pygeai.organization.managers import OrganizationManager
|
|
10
10
|
from pygeai.organization.mappers import OrganizationResponseMapper
|
|
11
11
|
from pygeai.organization.responses import AssistantListResponse, ProjectListResponse, ProjectDataResponse, \
|
|
12
|
-
ProjectTokensResponse, ProjectItemListResponse
|
|
12
|
+
ProjectTokensResponse, ProjectItemListResponse, MembershipsResponse, ProjectMembershipsResponse, \
|
|
13
|
+
ProjectRolesResponse, ProjectMembersResponse, OrganizationMembersResponse
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
class TestOrganizationManager(unittest.TestCase):
|
|
@@ -261,3 +262,123 @@ class TestOrganizationManager(unittest.TestCase):
|
|
|
261
262
|
skip=0,
|
|
262
263
|
count=0
|
|
263
264
|
)
|
|
265
|
+
|
|
266
|
+
@patch("pygeai.organization.clients.OrganizationClient.get_memberships")
|
|
267
|
+
def test_get_memberships(self, mock_get_memberships):
|
|
268
|
+
mock_response = MembershipsResponse(count=0, pages=0, organizations=[])
|
|
269
|
+
mock_get_memberships.return_value = {}
|
|
270
|
+
|
|
271
|
+
with patch.object(OrganizationResponseMapper, 'map_to_memberships_response', return_value=mock_response):
|
|
272
|
+
response = self.manager.get_memberships()
|
|
273
|
+
|
|
274
|
+
self.assertIsInstance(response, MembershipsResponse)
|
|
275
|
+
self.assertEqual(response.count, 0)
|
|
276
|
+
mock_get_memberships.assert_called_once_with(email=None, start_page=1, page_size=20, order_key=None, order_direction="desc", role_types=None)
|
|
277
|
+
|
|
278
|
+
@patch("pygeai.organization.clients.OrganizationClient.get_memberships")
|
|
279
|
+
def test_get_memberships_error(self, mock_get_memberships):
|
|
280
|
+
mock_get_memberships.return_value = self.error_response
|
|
281
|
+
|
|
282
|
+
with patch.object(ErrorHandler, 'has_errors', return_value=True):
|
|
283
|
+
with patch.object(ErrorHandler, 'extract_error', return_value="Access denied"):
|
|
284
|
+
with self.assertRaises(APIError) as context:
|
|
285
|
+
self.manager.get_memberships()
|
|
286
|
+
|
|
287
|
+
self.assertIn("Error received while retrieving memberships", str(context.exception))
|
|
288
|
+
mock_get_memberships.assert_called_once_with(email=None, start_page=1, page_size=20, order_key=None, order_direction="desc", role_types=None)
|
|
289
|
+
|
|
290
|
+
@patch("pygeai.organization.clients.OrganizationClient.get_project_memberships")
|
|
291
|
+
def test_get_project_memberships(self, mock_get_project_memberships):
|
|
292
|
+
mock_response = ProjectMembershipsResponse(count=0, pages=0, projects=[])
|
|
293
|
+
mock_get_project_memberships.return_value = {}
|
|
294
|
+
|
|
295
|
+
with patch.object(OrganizationResponseMapper, 'map_to_project_memberships_response', return_value=mock_response):
|
|
296
|
+
response = self.manager.get_project_memberships()
|
|
297
|
+
|
|
298
|
+
self.assertIsInstance(response, ProjectMembershipsResponse)
|
|
299
|
+
self.assertEqual(response.count, 0)
|
|
300
|
+
mock_get_project_memberships.assert_called_once_with(email=None, start_page=1, page_size=20, order_key=None, order_direction="desc", role_types=None)
|
|
301
|
+
|
|
302
|
+
@patch("pygeai.organization.clients.OrganizationClient.get_project_memberships")
|
|
303
|
+
def test_get_project_memberships_error(self, mock_get_project_memberships):
|
|
304
|
+
mock_get_project_memberships.return_value = self.error_response
|
|
305
|
+
|
|
306
|
+
with patch.object(ErrorHandler, 'has_errors', return_value=True):
|
|
307
|
+
with patch.object(ErrorHandler, 'extract_error', return_value="Access denied"):
|
|
308
|
+
with self.assertRaises(APIError) as context:
|
|
309
|
+
self.manager.get_project_memberships()
|
|
310
|
+
|
|
311
|
+
self.assertIn("Error received while retrieving project memberships", str(context.exception))
|
|
312
|
+
mock_get_project_memberships.assert_called_once_with(email=None, start_page=1, page_size=20, order_key=None, order_direction="desc", role_types=None)
|
|
313
|
+
|
|
314
|
+
@patch("pygeai.organization.clients.OrganizationClient.get_project_roles")
|
|
315
|
+
def test_get_project_roles(self, mock_get_project_roles):
|
|
316
|
+
mock_response = ProjectRolesResponse(roles=[])
|
|
317
|
+
mock_get_project_roles.return_value = {}
|
|
318
|
+
|
|
319
|
+
with patch.object(OrganizationResponseMapper, 'map_to_project_roles_response', return_value=mock_response):
|
|
320
|
+
response = self.manager.get_project_roles("proj-123")
|
|
321
|
+
|
|
322
|
+
self.assertIsInstance(response, ProjectRolesResponse)
|
|
323
|
+
self.assertEqual(response.roles, [])
|
|
324
|
+
mock_get_project_roles.assert_called_once_with(project_id="proj-123")
|
|
325
|
+
|
|
326
|
+
@patch("pygeai.organization.clients.OrganizationClient.get_project_roles")
|
|
327
|
+
def test_get_project_roles_error(self, mock_get_project_roles):
|
|
328
|
+
mock_get_project_roles.return_value = self.error_response
|
|
329
|
+
|
|
330
|
+
with patch.object(ErrorHandler, 'has_errors', return_value=True):
|
|
331
|
+
with patch.object(ErrorHandler, 'extract_error', return_value="Project not found"):
|
|
332
|
+
with self.assertRaises(APIError) as context:
|
|
333
|
+
self.manager.get_project_roles("proj-123")
|
|
334
|
+
|
|
335
|
+
self.assertIn("Error received while retrieving project roles", str(context.exception))
|
|
336
|
+
mock_get_project_roles.assert_called_once_with(project_id="proj-123")
|
|
337
|
+
|
|
338
|
+
@patch("pygeai.organization.clients.OrganizationClient.get_project_members")
|
|
339
|
+
def test_get_project_members(self, mock_get_project_members):
|
|
340
|
+
mock_response = ProjectMembersResponse(members=[])
|
|
341
|
+
mock_get_project_members.return_value = {}
|
|
342
|
+
|
|
343
|
+
with patch.object(OrganizationResponseMapper, 'map_to_project_members_response', return_value=mock_response):
|
|
344
|
+
response = self.manager.get_project_members("proj-123")
|
|
345
|
+
|
|
346
|
+
self.assertIsInstance(response, ProjectMembersResponse)
|
|
347
|
+
self.assertEqual(response.members, [])
|
|
348
|
+
mock_get_project_members.assert_called_once_with(project_id="proj-123")
|
|
349
|
+
|
|
350
|
+
@patch("pygeai.organization.clients.OrganizationClient.get_project_members")
|
|
351
|
+
def test_get_project_members_error(self, mock_get_project_members):
|
|
352
|
+
mock_get_project_members.return_value = self.error_response
|
|
353
|
+
|
|
354
|
+
with patch.object(ErrorHandler, 'has_errors', return_value=True):
|
|
355
|
+
with patch.object(ErrorHandler, 'extract_error', return_value="Project not found"):
|
|
356
|
+
with self.assertRaises(APIError) as context:
|
|
357
|
+
self.manager.get_project_members("proj-123")
|
|
358
|
+
|
|
359
|
+
self.assertIn("Error received while retrieving project members", str(context.exception))
|
|
360
|
+
mock_get_project_members.assert_called_once_with(project_id="proj-123")
|
|
361
|
+
|
|
362
|
+
@patch("pygeai.organization.clients.OrganizationClient.get_organization_members")
|
|
363
|
+
def test_get_organization_members(self, mock_get_organization_members):
|
|
364
|
+
mock_response = OrganizationMembersResponse(members=[])
|
|
365
|
+
mock_get_organization_members.return_value = {}
|
|
366
|
+
|
|
367
|
+
with patch.object(OrganizationResponseMapper, 'map_to_organization_members_response', return_value=mock_response):
|
|
368
|
+
response = self.manager.get_organization_members("org-123")
|
|
369
|
+
|
|
370
|
+
self.assertIsInstance(response, OrganizationMembersResponse)
|
|
371
|
+
self.assertEqual(response.members, [])
|
|
372
|
+
mock_get_organization_members.assert_called_once_with(organization_id="org-123")
|
|
373
|
+
|
|
374
|
+
@patch("pygeai.organization.clients.OrganizationClient.get_organization_members")
|
|
375
|
+
def test_get_organization_members_error(self, mock_get_organization_members):
|
|
376
|
+
mock_get_organization_members.return_value = self.error_response
|
|
377
|
+
|
|
378
|
+
with patch.object(ErrorHandler, 'has_errors', return_value=True):
|
|
379
|
+
with patch.object(ErrorHandler, 'extract_error', return_value="Organization not found"):
|
|
380
|
+
with self.assertRaises(APIError) as context:
|
|
381
|
+
self.manager.get_organization_members("org-123")
|
|
382
|
+
|
|
383
|
+
self.assertIn("Error received while retrieving organization members", str(context.exception))
|
|
384
|
+
mock_get_organization_members.assert_called_once_with(organization_id="org-123")
|
|
File without changes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from pygeai.organization.managers import OrganizationManager
|
|
2
|
+
|
|
3
|
+
manager = OrganizationManager(alias="sdkorg")
|
|
4
|
+
|
|
5
|
+
response = manager.get_memberships(
|
|
6
|
+
email="alejandro.trinidad@globant.com",
|
|
7
|
+
start_page=1,
|
|
8
|
+
page_size=10,
|
|
9
|
+
#order_key="organizationName",
|
|
10
|
+
#order_direction="asc"
|
|
11
|
+
)
|
|
12
|
+
print(f"response: {response}")
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from pygeai.organization.managers import OrganizationManager
|
|
2
|
+
|
|
3
|
+
manager = OrganizationManager()
|
|
4
|
+
|
|
5
|
+
response = manager.get_project_memberships(
|
|
6
|
+
email="user@example.com",
|
|
7
|
+
start_page=1,
|
|
8
|
+
page_size=10,
|
|
9
|
+
order_key="projectName",
|
|
10
|
+
order_direction="desc"
|
|
11
|
+
)
|
|
12
|
+
print(f"response: {response}")
|