codemie-test-harness 0.1.221__py3-none-any.whl → 0.1.222__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.

Potentially problematic release.


This version of codemie-test-harness might be problematic. Click here for more details.

@@ -950,6 +950,14 @@ def integration(integration_utils):
950
950
  integration_utils.delete_integration(created_integration)
951
951
 
952
952
 
953
+ @pytest.fixture(scope="session")
954
+ def vendor_utils():
955
+ """Create VendorUtils instance for managing vendor assistants"""
956
+ from codemie_test_harness.tests.utils.vendor_utils import VendorUtils
957
+
958
+ return VendorUtils()
959
+
960
+
953
961
  def pytest_sessionfinish(session):
954
962
  """Run cleanup code after all tests have finished."""
955
963
  clean_up_timeout = 1 if EnvironmentResolver.is_production() else 0
@@ -0,0 +1,36 @@
1
+ """Test data for vendor service endpoint tests."""
2
+
3
+ import pytest
4
+ from codemie_sdk.models.vendor_assistant import VendorType
5
+ from codemie_sdk.models.integration import CredentialTypes
6
+
7
+ from codemie_test_harness.tests.utils.credentials_manager import CredentialsManager
8
+
9
+
10
+ # Test data for vendor endpoint tests
11
+ # Extensible for AWS Bedrock, Azure AI, and GCP Vertex AI
12
+ vendor_endpoint_test_data = [
13
+ pytest.param(
14
+ VendorType.AWS,
15
+ CredentialTypes.AWS,
16
+ CredentialsManager.aws_credentials(),
17
+ marks=[pytest.mark.aws, pytest.mark.bedrock],
18
+ id="AWS_Bedrock",
19
+ ),
20
+ # Future: Azure AI endpoints
21
+ # pytest.param(
22
+ # VendorType.AZURE,
23
+ # CredentialTypes.AZURE,
24
+ # CredentialsManager.azure_credentials(),
25
+ # marks=[pytest.mark.azure],
26
+ # id="Azure_AI",
27
+ # ),
28
+ # Future: GCP Vertex AI endpoints
29
+ # pytest.param(
30
+ # VendorType.GCP,
31
+ # CredentialTypes.GCP,
32
+ # CredentialsManager.gcp_credentials(),
33
+ # marks=[pytest.mark.gcp],
34
+ # id="GCP_Vertex_AI",
35
+ # ),
36
+ ]
@@ -0,0 +1,43 @@
1
+ """Test data for 3rd party vendor assistant tests."""
2
+
3
+ import pytest
4
+ from codemie_sdk.models.vendor_assistant import VendorType
5
+ from codemie_sdk.models.integration import CredentialTypes
6
+
7
+ from codemie_test_harness.tests.llm.assistants.test_llm import SIMPLE_GREETING_PROMPT
8
+ from codemie_test_harness.tests.utils.credentials_manager import CredentialsManager
9
+
10
+
11
+ # Test data for vendor assistant tests
12
+ # Extensible for AWS Bedrock, Azure AI, and GCP Vertex AI
13
+ vendor_assistant_test_data = [
14
+ pytest.param(
15
+ VendorType.AWS,
16
+ CredentialTypes.AWS,
17
+ CredentialsManager.aws_credentials(),
18
+ SIMPLE_GREETING_PROMPT,
19
+ "Hello",
20
+ marks=[pytest.mark.aws, pytest.mark.bedrock],
21
+ id="AWS_Bedrock",
22
+ ),
23
+ # Future: Azure AI assistants
24
+ # pytest.param(
25
+ # VendorType.AZURE,
26
+ # CredentialTypes.AZURE,
27
+ # CredentialsManager.azure_credentials(),
28
+ # "Just say one word: 'Hello'",
29
+ # "Hello",
30
+ # marks=[pytest.mark.vendor, pytest.mark.azure, pytest.mark.api],
31
+ # id="Azure_AI",
32
+ # ),
33
+ # Future: GCP Vertex AI assistants
34
+ # pytest.param(
35
+ # VendorType.GCP,
36
+ # CredentialTypes.GCP,
37
+ # CredentialsManager.gcp_credentials(),
38
+ # "Just say one word: 'Hello'",
39
+ # "Hello",
40
+ # marks=[pytest.mark.vendor, pytest.mark.gcp, pytest.mark.api],
41
+ # id="GCP_Vertex_AI",
42
+ # ),
43
+ ]
@@ -0,0 +1,343 @@
1
+ """Utility class for managing vendor assistants (AWS Bedrock, Azure, GCP)."""
2
+
3
+ from typing import Optional, List
4
+ from codemie_sdk.models.vendor_assistant import (
5
+ VendorType,
6
+ VendorAssistantSettingsResponse,
7
+ VendorAssistantsResponse,
8
+ VendorAssistant,
9
+ VendorAssistantAliasesResponse,
10
+ VendorAssistantInstallRequest,
11
+ VendorAssistantInstallResponse,
12
+ VendorAssistantUninstallResponse,
13
+ VendorAssistantStatus,
14
+ )
15
+ from codemie_test_harness.tests.utils.client_factory import get_client
16
+ from codemie_test_harness.tests.utils.logger_util import setup_logger
17
+
18
+ logger = setup_logger(__name__)
19
+
20
+ DRAFT_VERSION = "DRAFT"
21
+
22
+
23
+ class VendorUtils:
24
+ """Utility class for vendor assistant operations."""
25
+
26
+ def __init__(self):
27
+ """Initialize VendorUtils with CodeMie client."""
28
+ self.client = get_client()
29
+ self.vendor_service = self.client.vendors
30
+
31
+ def get_assistant_settings(
32
+ self,
33
+ vendor: VendorType,
34
+ page: int = 0,
35
+ per_page: int = 10,
36
+ ) -> VendorAssistantSettingsResponse:
37
+ """Get assistant settings for a specific cloud vendor.
38
+
39
+ Args:
40
+ vendor: Cloud vendor type (AWS, AZURE, GCP)
41
+ page: Page number for pagination
42
+ per_page: Number of items per page
43
+
44
+ Returns:
45
+ VendorAssistantSettingsResponse containing list of settings
46
+ """
47
+ logger.info(
48
+ f"Getting assistant settings for {vendor.value} (page={page}, per_page={per_page})"
49
+ )
50
+ settings = self.vendor_service.get_assistant_settings(
51
+ vendor=vendor, page=page, per_page=per_page
52
+ )
53
+ logger.info(
54
+ f"Retrieved {len(settings.data)} settings for {vendor.value} (total: {settings.pagination.total})"
55
+ )
56
+ return settings
57
+
58
+ def get_assistants(
59
+ self,
60
+ vendor: VendorType,
61
+ setting_id: str,
62
+ per_page: int = 10,
63
+ next_token: Optional[str] = None,
64
+ ) -> VendorAssistantsResponse:
65
+ """Get assistants for a specific vendor setting.
66
+
67
+ Args:
68
+ vendor: Cloud vendor type
69
+ setting_id: ID of the vendor setting
70
+ per_page: Number of items per page
71
+ next_token: Token for pagination
72
+
73
+ Returns:
74
+ VendorAssistantsResponse containing list of assistants
75
+ """
76
+ logger.info(
77
+ f"Getting assistants for {vendor.value} setting {setting_id} (per_page={per_page})"
78
+ )
79
+ assistants = self.vendor_service.get_assistants(
80
+ vendor=vendor,
81
+ setting_id=setting_id,
82
+ per_page=per_page,
83
+ next_token=next_token,
84
+ )
85
+ logger.info(
86
+ f"Retrieved {len(assistants.data)} assistants for setting {setting_id}"
87
+ )
88
+ return assistants
89
+
90
+ def get_assistant(
91
+ self,
92
+ vendor: VendorType,
93
+ assistant_id: str,
94
+ setting_id: str,
95
+ ) -> VendorAssistant:
96
+ """Get a specific assistant by ID.
97
+
98
+ Args:
99
+ vendor: Cloud vendor type
100
+ assistant_id: ID of the assistant
101
+ setting_id: ID of the vendor setting
102
+
103
+ Returns:
104
+ VendorAssistant with assistant details
105
+ """
106
+ logger.info(
107
+ f"Getting assistant {assistant_id} for {vendor.value} setting {setting_id}"
108
+ )
109
+ assistant = self.vendor_service.get_assistant(
110
+ vendor=vendor, assistant_id=assistant_id, setting_id=setting_id
111
+ )
112
+ logger.info(
113
+ f"Retrieved assistant: {assistant.name} (status: {assistant.status})"
114
+ )
115
+ return assistant
116
+
117
+ def get_assistant_aliases(
118
+ self,
119
+ vendor: VendorType,
120
+ assistant_id: str,
121
+ setting_id: str,
122
+ per_page: int = 10,
123
+ next_token: Optional[str] = None,
124
+ ) -> VendorAssistantAliasesResponse:
125
+ """Get aliases for a specific vendor assistant.
126
+
127
+ Args:
128
+ vendor: Cloud vendor type
129
+ assistant_id: ID of the assistant
130
+ setting_id: ID of the vendor setting
131
+ per_page: Number of items per page
132
+ next_token: Token for pagination
133
+
134
+ Returns:
135
+ VendorAssistantAliasesResponse containing list of aliases
136
+ """
137
+ logger.info(
138
+ f"Getting aliases for assistant {assistant_id} in {vendor.value} setting {setting_id}"
139
+ )
140
+ aliases = self.vendor_service.get_assistant_aliases(
141
+ vendor=vendor,
142
+ assistant_id=assistant_id,
143
+ setting_id=setting_id,
144
+ per_page=per_page,
145
+ next_token=next_token,
146
+ )
147
+ logger.info(
148
+ f"Retrieved {len(aliases.data)} aliases for assistant {assistant_id}"
149
+ )
150
+ return aliases
151
+
152
+ def install_assistants(
153
+ self,
154
+ vendor: VendorType,
155
+ assistants: List[VendorAssistantInstallRequest],
156
+ ) -> VendorAssistantInstallResponse:
157
+ """Install/activate vendor assistants.
158
+
159
+ Args:
160
+ vendor: Cloud vendor type
161
+ assistants: List of assistant installation requests
162
+
163
+ Returns:
164
+ VendorAssistantInstallResponse containing installation summary with AI run IDs
165
+ """
166
+ logger.info(f"Installing {len(assistants)} assistant(s) for {vendor.value}")
167
+ response = self.vendor_service.install_assistants(
168
+ vendor=vendor, assistants=assistants
169
+ )
170
+ for item in response.summary:
171
+ logger.info(
172
+ f"Installed assistant {item.agentId} (alias: {item.agentAliasId}) -> CodeMie ID: {item.aiRunId}"
173
+ )
174
+ return response
175
+
176
+ def uninstall_assistant(
177
+ self,
178
+ vendor: VendorType,
179
+ codemie_id: str,
180
+ ) -> VendorAssistantUninstallResponse:
181
+ """Uninstall/deactivate a vendor assistant.
182
+
183
+ Args:
184
+ vendor: Cloud vendor type
185
+ codemie_id: CodeMie assistant ID from installation
186
+
187
+ Returns:
188
+ VendorAssistantUninstallResponse with success status
189
+ """
190
+ logger.info(f"Uninstalling assistant with CodeMie ID: {codemie_id}")
191
+ response = self.vendor_service.uninstall_assistant(
192
+ vendor=vendor, ai_run_id=codemie_id
193
+ )
194
+ if response.success:
195
+ logger.info(f"Successfully uninstalled assistant {codemie_id}")
196
+ else:
197
+ logger.warning(f"Failed to uninstall assistant {codemie_id}")
198
+ return response
199
+
200
+ def get_prepared_assistant(
201
+ self,
202
+ assistants: List[VendorAssistant],
203
+ ) -> Optional[VendorAssistant]:
204
+ """Get first PREPARED assistant from the list.
205
+
206
+ Args:
207
+ assistants: List of vendor assistants
208
+
209
+ Returns:
210
+ First PREPARED assistant or first assistant if none are PREPARED
211
+ """
212
+ return next(
213
+ (a for a in assistants if a.status == VendorAssistantStatus.PREPARED),
214
+ assistants[0] if assistants else None,
215
+ )
216
+
217
+ def get_non_draft_alias(
218
+ self,
219
+ aliases: List,
220
+ ) -> Optional:
221
+ """Get first non-DRAFT alias from the list.
222
+
223
+ Args:
224
+ aliases: List of vendor assistant aliases
225
+
226
+ Returns:
227
+ First non-DRAFT alias or first alias if all are DRAFT
228
+ """
229
+ return next(
230
+ (a for a in aliases if a.version != DRAFT_VERSION),
231
+ aliases[0] if aliases else None,
232
+ )
233
+
234
+ def find_first_available_assistant(
235
+ self,
236
+ vendor: VendorType,
237
+ setting_id: str,
238
+ ) -> Optional[tuple[VendorAssistant, str]]:
239
+ """Find the first available (PREPARED) assistant with an alias.
240
+
241
+ Args:
242
+ vendor: Cloud vendor type
243
+ setting_id: ID of the vendor setting
244
+
245
+ Returns:
246
+ Tuple of (VendorAssistant, alias_id) or None if no available assistant found
247
+ """
248
+ logger.info(
249
+ f"Searching for available assistant in {vendor.value} setting {setting_id}"
250
+ )
251
+ assistants_response = self.get_assistants(vendor=vendor, setting_id=setting_id)
252
+
253
+ for assistant in assistants_response.data:
254
+ if assistant.status.value == "PREPARED":
255
+ # Get aliases for this assistant
256
+ aliases_response = self.get_assistant_aliases(
257
+ vendor=vendor, assistant_id=assistant.id, setting_id=setting_id
258
+ )
259
+ if aliases_response.data:
260
+ first_alias = aliases_response.data[0]
261
+ logger.info(
262
+ f"Found available assistant: {assistant.name} (ID: {assistant.id}, Alias: {first_alias.id})"
263
+ )
264
+ return assistant, first_alias.id
265
+
266
+ logger.warning(
267
+ f"No available assistant found for {vendor.value} setting {setting_id}"
268
+ )
269
+ return None
270
+
271
+ def install_first_available_assistant(
272
+ self,
273
+ vendor: VendorType,
274
+ setting_id: str,
275
+ ) -> Optional[str]:
276
+ """Find and install the first available assistant.
277
+
278
+ Args:
279
+ vendor: Cloud vendor type
280
+ setting_id: ID of the vendor setting
281
+
282
+ Returns:
283
+ CodeMie ID of the installed assistant or None if no assistant available
284
+ """
285
+ result = self.find_first_available_assistant(
286
+ vendor=vendor, setting_id=setting_id
287
+ )
288
+ if not result:
289
+ return None
290
+
291
+ assistant, alias_id = result
292
+ install_request = VendorAssistantInstallRequest(
293
+ id=assistant.id,
294
+ agentAliasId=alias_id,
295
+ setting_id=setting_id,
296
+ )
297
+
298
+ install_response = self.install_assistants(
299
+ vendor=vendor, assistants=[install_request]
300
+ )
301
+
302
+ if install_response.summary:
303
+ return install_response.summary[0].aiRunId
304
+
305
+ return None
306
+
307
+ def find_setting_for_integration(
308
+ self,
309
+ vendor: VendorType,
310
+ integration_id: str,
311
+ ):
312
+ """Find setting for an integration by paginating through all settings.
313
+
314
+ Args:
315
+ vendor: Type of vendor (AWS, AZURE, GCP)
316
+ integration_id: ID of the integration to find (searches by setting_id)
317
+
318
+ Returns:
319
+ VendorAssistantSetting or None if not found
320
+ """
321
+ page = 0
322
+ per_page = 50
323
+
324
+ while True:
325
+ settings_response = self.get_assistant_settings(
326
+ vendor=vendor,
327
+ page=page,
328
+ per_page=per_page,
329
+ )
330
+
331
+ # Find the setting for our integration by setting_id
332
+ for s in settings_response.data:
333
+ if s.setting_id == integration_id:
334
+ return s
335
+
336
+ # Check if there are more pages
337
+ if page >= settings_response.pagination.pages - 1:
338
+ break
339
+
340
+ page += 1
341
+
342
+ logger.warning(f"Setting not found for integration ID '{integration_id}'")
343
+ return None
@@ -0,0 +1 @@
1
+ """Tests for 3rd party vendor assistants (AWS Bedrock, Azure, GCP)."""
@@ -0,0 +1,65 @@
1
+ import pytest
2
+ from hamcrest import assert_that, is_not, none, empty, is_
3
+ from codemie_test_harness.tests.test_data.vendor_test_data import (
4
+ vendor_assistant_test_data,
5
+ )
6
+
7
+
8
+ @pytest.mark.vendor
9
+ @pytest.mark.api
10
+ @pytest.mark.parametrize(
11
+ "vendor_type,credential_type,credentials,prompt,expected_response",
12
+ vendor_assistant_test_data,
13
+ )
14
+ def test_vendor_assistant_installation_and_chat(
15
+ vendor_utils,
16
+ integration,
17
+ assistant_utils,
18
+ similarity_check,
19
+ vendor_type,
20
+ credential_type,
21
+ credentials,
22
+ prompt,
23
+ expected_response,
24
+ ):
25
+ """Test vendor assistant installation and chat functionality."""
26
+ _integration = integration(credential_type, credentials)
27
+
28
+ setting = vendor_utils.find_setting_for_integration(
29
+ vendor=vendor_type,
30
+ integration_id=_integration.id,
31
+ )
32
+ assert_that(setting, is_not(none()))
33
+ assert_that(setting.invalid or False, is_(False))
34
+
35
+ assistants_response = vendor_utils.get_assistants(
36
+ vendor=vendor_type,
37
+ setting_id=setting.setting_id,
38
+ )
39
+ assert_that(assistants_response, is_not(none()))
40
+ assert_that(assistants_response.data, is_not(empty()))
41
+
42
+ codemie_id = vendor_utils.install_first_available_assistant(
43
+ vendor=vendor_type,
44
+ setting_id=setting.setting_id,
45
+ )
46
+ assert_that(codemie_id, is_not(none()))
47
+
48
+ class AssistantIdWrapper:
49
+ def __init__(self, assistant_id):
50
+ self.id = assistant_id
51
+
52
+ assistant_wrapper = AssistantIdWrapper(codemie_id)
53
+ response = assistant_utils.ask_assistant(
54
+ assistant=assistant_wrapper,
55
+ user_prompt=prompt,
56
+ minimal_response=True,
57
+ )
58
+
59
+ similarity_check.check_similarity(response, expected_response)
60
+
61
+ uninstall_response = vendor_utils.uninstall_assistant(
62
+ vendor=vendor_type,
63
+ codemie_id=codemie_id,
64
+ )
65
+ assert_that(uninstall_response.success, is_(True))
@@ -0,0 +1,386 @@
1
+ """Tests for vendor service SDK endpoints.
2
+
3
+ Architecture:
4
+ - Parametrized tests that support multiple vendors (AWS, Azure, GCP)
5
+ - Extensible design for easy addition of new vendors
6
+ - Uses integration fixture factory for consistent setup
7
+ - Each test validates a specific SDK endpoint
8
+ """
9
+
10
+ import pytest
11
+ from hamcrest import (
12
+ assert_that,
13
+ is_not,
14
+ none,
15
+ empty,
16
+ greater_than,
17
+ instance_of,
18
+ has_length,
19
+ is_,
20
+ )
21
+ from codemie_sdk.models.vendor_assistant import (
22
+ VendorAssistantSettingsResponse,
23
+ VendorAssistantsResponse,
24
+ VendorAssistant,
25
+ VendorAssistantVersion,
26
+ VendorAssistantAliasesResponse,
27
+ VendorAssistantInstallRequest,
28
+ VendorAssistantInstallResponse,
29
+ VendorAssistantUninstallResponse,
30
+ VendorAssistantStatus,
31
+ )
32
+ from codemie_test_harness.tests.test_data.vendor_endpoint_test_data import (
33
+ vendor_endpoint_test_data,
34
+ )
35
+
36
+
37
+ @pytest.mark.vendor
38
+ @pytest.mark.api
39
+ @pytest.mark.parametrize(
40
+ "vendor_type,credential_type,credentials",
41
+ vendor_endpoint_test_data,
42
+ )
43
+ def test_get_assistant_settings(
44
+ vendor_utils, integration, vendor_type, credential_type, credentials
45
+ ):
46
+ """Test GET /v1/vendors/{vendor}/assistants/settings endpoint."""
47
+ _integration = integration(credential_type, credentials)
48
+
49
+ settings_response = vendor_utils.get_assistant_settings(vendor=vendor_type)
50
+
51
+ assert_that(settings_response, instance_of(VendorAssistantSettingsResponse))
52
+ assert_that(settings_response.data, is_not(none()))
53
+ assert_that(settings_response.pagination, is_not(none()))
54
+ assert_that(settings_response.data, is_not(empty()))
55
+ assert_that(settings_response.pagination.total, greater_than(0))
56
+
57
+ created_setting = vendor_utils.find_setting_for_integration(
58
+ vendor=vendor_type,
59
+ integration_id=_integration.id,
60
+ )
61
+ assert_that(created_setting, is_not(none()))
62
+
63
+
64
+ @pytest.mark.vendor
65
+ @pytest.mark.api
66
+ @pytest.mark.parametrize(
67
+ "vendor_type,credential_type,credentials",
68
+ vendor_endpoint_test_data,
69
+ )
70
+ def test_get_assistants(
71
+ vendor_utils, integration, vendor_type, credential_type, credentials
72
+ ):
73
+ """Test GET /v1/vendors/{vendor}/assistants endpoint."""
74
+ _integration = integration(credential_type, credentials)
75
+
76
+ setting = vendor_utils.find_setting_for_integration(
77
+ vendor=vendor_type,
78
+ integration_id=_integration.id,
79
+ )
80
+ assert_that(setting, is_not(none()))
81
+
82
+ assistants_response = vendor_utils.get_assistants(
83
+ vendor=vendor_type,
84
+ setting_id=setting.setting_id,
85
+ )
86
+
87
+ assert_that(assistants_response, instance_of(VendorAssistantsResponse))
88
+ assert_that(assistants_response.data, is_not(none()))
89
+ assert_that(assistants_response.pagination, is_not(none()))
90
+ assert_that(assistants_response.data, is_not(empty()))
91
+
92
+ _assistant = vendor_utils.get_prepared_assistant(assistants_response.data)
93
+
94
+ assert_that(_assistant.id, is_not(none()))
95
+ assert_that(_assistant.name, is_not(none()))
96
+ assert_that(_assistant.status, is_(VendorAssistantStatus.PREPARED))
97
+ assert_that(_assistant.description, is_not(none()))
98
+ assert_that(_assistant.updatedAt, is_not(none()))
99
+
100
+
101
+ @pytest.mark.vendor
102
+ @pytest.mark.api
103
+ @pytest.mark.parametrize(
104
+ "vendor_type,credential_type,credentials",
105
+ vendor_endpoint_test_data,
106
+ )
107
+ def test_get_assistant(
108
+ vendor_utils, integration, vendor_type, credential_type, credentials
109
+ ):
110
+ """Test GET /v1/vendors/{vendor}/assistants/{assistant_id} endpoint."""
111
+ _integration = integration(credential_type, credentials)
112
+
113
+ setting = vendor_utils.find_setting_for_integration(
114
+ vendor=vendor_type,
115
+ integration_id=_integration.id,
116
+ )
117
+ assert_that(setting, is_not(none()))
118
+
119
+ assistants_response = vendor_utils.get_assistants(
120
+ vendor=vendor_type,
121
+ setting_id=setting.setting_id,
122
+ )
123
+ assert_that(assistants_response.data, is_not(empty()))
124
+
125
+ first_assistant = vendor_utils.get_prepared_assistant(assistants_response.data)
126
+
127
+ _assistant = vendor_utils.get_assistant(
128
+ vendor=vendor_type,
129
+ assistant_id=first_assistant.id,
130
+ setting_id=setting.setting_id,
131
+ )
132
+
133
+ assert_that(_assistant, instance_of(VendorAssistant))
134
+ assert_that(_assistant.id, is_(first_assistant.id))
135
+ assert_that(_assistant.name, is_not(none()))
136
+ assert_that(_assistant.status, is_(VendorAssistantStatus.PREPARED))
137
+ assert_that(_assistant.description, is_not(none()))
138
+ assert_that(_assistant.updatedAt, is_not(none()))
139
+
140
+
141
+ @pytest.mark.vendor
142
+ @pytest.mark.api
143
+ @pytest.mark.parametrize(
144
+ "vendor_type,credential_type,credentials",
145
+ vendor_endpoint_test_data,
146
+ )
147
+ def test_get_assistant_version(
148
+ vendor_utils, integration, vendor_type, credential_type, credentials
149
+ ):
150
+ """Test GET /v1/vendors/{vendor}/assistants/{assistant_id}/{version} endpoint."""
151
+ _integration = integration(credential_type, credentials)
152
+
153
+ setting = vendor_utils.find_setting_for_integration(
154
+ vendor=vendor_type,
155
+ integration_id=_integration.id,
156
+ )
157
+ assert_that(setting, is_not(none()))
158
+
159
+ assistants_response = vendor_utils.get_assistants(
160
+ vendor=vendor_type,
161
+ setting_id=setting.setting_id,
162
+ )
163
+ assert_that(assistants_response.data, is_not(empty()))
164
+
165
+ first_assistant = vendor_utils.get_prepared_assistant(assistants_response.data)
166
+ aliases_response = vendor_utils.get_assistant_aliases(
167
+ vendor=vendor_type,
168
+ assistant_id=first_assistant.id,
169
+ setting_id=setting.setting_id,
170
+ )
171
+ assert_that(aliases_response.data, is_not(empty()))
172
+
173
+ first_alias = vendor_utils.get_non_draft_alias(aliases_response.data)
174
+
175
+ assistant_version = vendor_utils.vendor_service.get_assistant_version(
176
+ vendor=vendor_type,
177
+ assistant_id=first_assistant.id,
178
+ version=first_alias.version,
179
+ setting_id=setting.setting_id,
180
+ )
181
+
182
+ assert_that(assistant_version, instance_of(VendorAssistantVersion))
183
+ assert_that(assistant_version.id, is_(first_assistant.id))
184
+ assert_that(assistant_version.name, is_not(none()))
185
+ assert_that(assistant_version.status, is_not(none()))
186
+ assert_that(assistant_version.version, is_(first_alias.version))
187
+ assert_that(assistant_version.instruction, is_not(none()))
188
+ assert_that(assistant_version.foundationModel, is_not(none()))
189
+ assert_that(assistant_version.createdAt, is_not(none()))
190
+ assert_that(assistant_version.updatedAt, is_not(none()))
191
+
192
+
193
+ @pytest.mark.vendor
194
+ @pytest.mark.api
195
+ @pytest.mark.parametrize(
196
+ "vendor_type,credential_type,credentials",
197
+ vendor_endpoint_test_data,
198
+ )
199
+ def test_get_assistant_aliases(
200
+ vendor_utils, integration, vendor_type, credential_type, credentials
201
+ ):
202
+ """Test GET /v1/vendors/{vendor}/assistants/{assistant_id}/aliases endpoint."""
203
+ _integration = integration(credential_type, credentials)
204
+
205
+ setting = vendor_utils.find_setting_for_integration(
206
+ vendor=vendor_type,
207
+ integration_id=_integration.id,
208
+ )
209
+ assert_that(setting, is_not(none()))
210
+
211
+ assistants_response = vendor_utils.get_assistants(
212
+ vendor=vendor_type,
213
+ setting_id=setting.setting_id,
214
+ )
215
+ assert_that(assistants_response.data, is_not(empty()))
216
+
217
+ first_assistant = vendor_utils.get_prepared_assistant(assistants_response.data)
218
+
219
+ aliases_response = vendor_utils.get_assistant_aliases(
220
+ vendor=vendor_type,
221
+ assistant_id=first_assistant.id,
222
+ setting_id=setting.setting_id,
223
+ )
224
+
225
+ assert_that(aliases_response, instance_of(VendorAssistantAliasesResponse))
226
+ assert_that(aliases_response.data, is_not(none()))
227
+ assert_that(aliases_response.pagination, is_not(none()))
228
+ assert_that(aliases_response.data, is_not(empty()))
229
+
230
+ first_alias = aliases_response.data[0]
231
+ assert_that(first_alias.id, is_not(none()))
232
+ assert_that(first_alias.name, is_not(none()))
233
+ assert_that(first_alias.status, is_not(none()))
234
+ assert_that(first_alias.description, is_not(none()))
235
+ assert_that(first_alias.version, is_not(none()))
236
+ assert_that(first_alias.createdAt, is_not(none()))
237
+ assert_that(first_alias.updatedAt, is_not(none()))
238
+
239
+
240
+ @pytest.mark.vendor
241
+ @pytest.mark.api
242
+ @pytest.mark.parametrize(
243
+ "vendor_type,credential_type,credentials",
244
+ vendor_endpoint_test_data,
245
+ )
246
+ def test_install_assistants(
247
+ vendor_utils, integration, vendor_type, credential_type, credentials
248
+ ):
249
+ """Test POST /v1/vendors/{vendor}/assistants endpoint."""
250
+ _integration = integration(credential_type, credentials)
251
+
252
+ setting = vendor_utils.find_setting_for_integration(
253
+ vendor=vendor_type,
254
+ integration_id=_integration.id,
255
+ )
256
+ assert_that(setting, is_not(none()))
257
+
258
+ result = vendor_utils.find_first_available_assistant(
259
+ vendor=vendor_type,
260
+ setting_id=setting.setting_id,
261
+ )
262
+ assert_that(result, is_not(none()))
263
+
264
+ _assistant, alias_id = result
265
+
266
+ install_request = VendorAssistantInstallRequest(
267
+ id=_assistant.id,
268
+ agentAliasId=alias_id,
269
+ setting_id=setting.setting_id,
270
+ )
271
+
272
+ install_response = vendor_utils.install_assistants(
273
+ vendor=vendor_type,
274
+ assistants=[install_request],
275
+ )
276
+
277
+ assert_that(install_response, instance_of(VendorAssistantInstallResponse))
278
+ assert_that(install_response.summary, is_not(empty()))
279
+ assert_that(install_response.summary, has_length(1))
280
+
281
+ installed = install_response.summary[0]
282
+ assert_that(installed.agentId, is_(_assistant.id))
283
+ assert_that(installed.agentAliasId, is_(alias_id))
284
+ assert_that(installed.aiRunId, is_not(none()))
285
+
286
+
287
+ @pytest.mark.vendor
288
+ @pytest.mark.api
289
+ @pytest.mark.parametrize(
290
+ "vendor_type,credential_type,credentials",
291
+ vendor_endpoint_test_data,
292
+ )
293
+ def test_uninstall_assistant(
294
+ vendor_utils, integration, vendor_type, credential_type, credentials
295
+ ):
296
+ """Test DELETE /v1/vendors/{vendor}/assistants/{ai_run_id} endpoint."""
297
+ _integration = integration(credential_type, credentials)
298
+
299
+ setting = vendor_utils.find_setting_for_integration(
300
+ vendor=vendor_type,
301
+ integration_id=_integration.id,
302
+ )
303
+ assert_that(setting, is_not(none()))
304
+
305
+ codemie_id = vendor_utils.install_first_available_assistant(
306
+ vendor=vendor_type,
307
+ setting_id=setting.setting_id,
308
+ )
309
+ assert_that(codemie_id, is_not(none()))
310
+
311
+ uninstall_response = vendor_utils.uninstall_assistant(
312
+ vendor=vendor_type,
313
+ codemie_id=codemie_id,
314
+ )
315
+
316
+ assert_that(uninstall_response, instance_of(VendorAssistantUninstallResponse))
317
+ assert_that(uninstall_response.success, is_(True))
318
+
319
+
320
+ @pytest.mark.vendor
321
+ @pytest.mark.api
322
+ @pytest.mark.parametrize(
323
+ "vendor_type,credential_type,credentials",
324
+ vendor_endpoint_test_data,
325
+ )
326
+ def test_get_assistant_settings_pagination(
327
+ vendor_utils, integration, vendor_type, credential_type, credentials
328
+ ):
329
+ """Test pagination functionality for get_assistant_settings endpoint."""
330
+ first_page = vendor_utils.get_assistant_settings(
331
+ vendor=vendor_type,
332
+ page=0,
333
+ per_page=2,
334
+ )
335
+
336
+ assert_that(first_page.pagination.page, is_(0))
337
+ assert_that(first_page.pagination.per_page, is_(2))
338
+ assert_that(first_page.pagination.total, greater_than(0))
339
+
340
+ if first_page.pagination.pages > 1:
341
+ second_page = vendor_utils.get_assistant_settings(
342
+ vendor=vendor_type,
343
+ page=1,
344
+ per_page=2,
345
+ )
346
+ assert_that(second_page.pagination.page, is_(1))
347
+ assert_that(second_page.data, is_not(empty()))
348
+
349
+
350
+ @pytest.mark.vendor
351
+ @pytest.mark.api
352
+ @pytest.mark.parametrize(
353
+ "vendor_type,credential_type,credentials",
354
+ vendor_endpoint_test_data,
355
+ )
356
+ def test_get_assistants_pagination(
357
+ vendor_utils, integration, vendor_type, credential_type, credentials
358
+ ):
359
+ """Test pagination functionality for get_assistants endpoint using next_token."""
360
+ _integration = integration(credential_type, credentials)
361
+
362
+ setting = vendor_utils.find_setting_for_integration(
363
+ vendor=vendor_type,
364
+ integration_id=_integration.id,
365
+ )
366
+ assert_that(setting, is_not(none()))
367
+
368
+ first_page = vendor_utils.get_assistants(
369
+ vendor=vendor_type,
370
+ setting_id=setting.setting_id,
371
+ per_page=2,
372
+ )
373
+
374
+ assert_that(first_page.data, is_not(empty()))
375
+
376
+ if first_page.pagination.next_token:
377
+ second_page = vendor_utils.get_assistants(
378
+ vendor=vendor_type,
379
+ setting_id=setting.setting_id,
380
+ per_page=2,
381
+ next_token=first_page.pagination.next_token,
382
+ )
383
+ assert_that(second_page.data, is_not(empty()))
384
+ first_page_ids = {a.id for a in first_page.data}
385
+ second_page_ids = {a.id for a in second_page.data}
386
+ assert_that(first_page_ids.intersection(second_page_ids), is_(set()))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: codemie-test-harness
3
- Version: 0.1.221
3
+ Version: 0.1.222
4
4
  Summary: Autotest for CodeMie backend and UI
5
5
  Author: Anton Yeromin
6
6
  Author-email: anton_yeromin@epam.com
@@ -13,7 +13,7 @@ Requires-Dist: aws-assume-role-lib (>=2.10.0,<3.0.0)
13
13
  Requires-Dist: boto3 (>=1.39.8,<2.0.0)
14
14
  Requires-Dist: click (>=8.1.7,<9.0.0)
15
15
  Requires-Dist: codemie-plugins (>=0.1.123,<0.2.0)
16
- Requires-Dist: codemie-sdk-python (==0.1.221)
16
+ Requires-Dist: codemie-sdk-python (==0.1.222)
17
17
  Requires-Dist: pytest (>=8.4.1,<9.0.0)
18
18
  Requires-Dist: pytest-playwright (>=0.7.0,<0.8.0)
19
19
  Requires-Dist: pytest-repeat (>=0.9.3,<0.10.0)
@@ -65,7 +65,7 @@ codemie_test_harness/tests/assistant/tools/servicenow/__init__.py,sha256=47DEQpj
65
65
  codemie_test_harness/tests/assistant/tools/servicenow/test_servicenow_tools.py,sha256=aUjfZ4773WoQJjcHx3JqH5e8ckaKB-aIMO-OZWTm0Ek,888
66
66
  codemie_test_harness/tests/assistant/tools/vcs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
67
67
  codemie_test_harness/tests/assistant/tools/vcs/test_assistant_with_vcs_tools.py,sha256=qOPr4XOh2rgUV2MXMxkRzRGkAKl9ViwQGCZ-dMEtscU,1145
68
- codemie_test_harness/tests/conftest.py,sha256=FH6xBlPTjU6wlHNZSJAxbNvYCjICZq3SRWMCEAKvF2c,33929
68
+ codemie_test_harness/tests/conftest.py,sha256=k58Uf7roM5uRqkbke1mCXL2EEf_OoYSQpKQqts0p9Rw,34153
69
69
  codemie_test_harness/tests/conversations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
70
70
  codemie_test_harness/tests/conversations/test_conversations_endpoints.py,sha256=HQ2nu9lXfRNkyJhA0rzar7Rmv6pMe-te0rFYAy-X5UA,4128
71
71
  codemie_test_harness/tests/e2e/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -170,6 +170,8 @@ codemie_test_harness/tests/test_data/report_portal_tools_test_data.py,sha256=YZd
170
170
  codemie_test_harness/tests/test_data/research_tools_test_data.py,sha256=zwpzm-VSnrLZEfG97AE9Ms7z7j3xmqxiNd1EmZyWCSk,9102
171
171
  codemie_test_harness/tests/test_data/servicenow_tools_test_data.py,sha256=PKw9zEYSNcQM1KApCSjsBiA_3Py0bNQI7clqw8cmT-s,1983
172
172
  codemie_test_harness/tests/test_data/vcs_tools_test_data.py,sha256=ZJdday96uOKOy_kPRBPp0w9JZbf0il7Y_hPfwRmUkuM,4518
173
+ codemie_test_harness/tests/test_data/vendor_endpoint_test_data.py,sha256=Fti3ZbpS3m06Heyh5AAcoAKZuimX709iZQFPhzKvrC4,1075
174
+ codemie_test_harness/tests/test_data/vendor_test_data.py,sha256=FFS35ikzMzSHShnfmdIme-WjueSjj0qBwa0OU6ooKfc,1409
173
175
  codemie_test_harness/tests/test_data/workflow/invalid_config/invalid_assistant_id.yaml,sha256=_cioQNq3icemob9u0i-hXkTy2nflzyP0Ce8FWiPG14M,265
174
176
  codemie_test_harness/tests/test_data/workflow/invalid_config/invalid_assistant_in_state.yaml,sha256=t_W95zD5bfdGf3F6p64-2qBHz7SkL_7mFT675uieWZg,209
175
177
  codemie_test_harness/tests/test_data/workflow/invalid_config/invalid_data_source.yaml,sha256=Vwx3HyrQkL8sWNtfwL6d0qiJhru6X3ojKBASAzJeY9w,252
@@ -295,9 +297,14 @@ codemie_test_harness/tests/utils/pytest_utils.py,sha256=k-mEjX2qpnh37sqKpJqYhZT6
295
297
  codemie_test_harness/tests/utils/search_utils.py,sha256=SrXiB2d9wiI5ka9bgg0CD73GOX_1mqi2Hz5FBm5DsEU,1435
296
298
  codemie_test_harness/tests/utils/similarity_check.py,sha256=2URqvD3Ft7efwLmhh2iYVsXrYboP9f-_B_ekZmJn0ac,1527
297
299
  codemie_test_harness/tests/utils/user_utils.py,sha256=zJNrmL3Fb7iGuaVRobUMwJ2Og6NqEPcM_9lw60m18T8,242
300
+ codemie_test_harness/tests/utils/vendor_utils.py,sha256=4ezTRzBfKbpk4bgcq8pzBIPhBoIinOkvmEHA7lDcbPg,10966
298
301
  codemie_test_harness/tests/utils/webhook_utils.py,sha256=YjyLwAqQjR12vYFOUmYhJCJIyZvKm4SvU-1oIjIYNqg,340
299
302
  codemie_test_harness/tests/utils/workflow_utils.py,sha256=bHxPQkblRPF1fZp_AXI36elMFm14nzqGYoU5Eqz4MWY,11553
300
303
  codemie_test_harness/tests/utils/yaml_utils.py,sha256=iIdEl-rUUh1LgzAmD_mjfftthhvlzXyCuA37yBoH0Gw,1617
304
+ codemie_test_harness/tests/vendor/__init__.py,sha256=7kcktgm5ZkmcVLRX2mTRhGzVzFpVR_rcgYUbhKe-3q0,71
305
+ codemie_test_harness/tests/vendor/assistants/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
306
+ codemie_test_harness/tests/vendor/assistants/test_vendor_assistants.py,sha256=zXTT5wZuKZw5XP0do3uMi69s2GZZr310VuOT2caEC0E,1907
307
+ codemie_test_harness/tests/vendor/assistants/test_vendor_assistants_endpoints.py,sha256=L75FcCB1e4dDMgsJXnNAMz6SMmcygfyzqjqOi4l64tI,12779
301
308
  codemie_test_harness/tests/webhook/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
302
309
  codemie_test_harness/tests/webhook/test_webhook_service.py,sha256=POmxQG0tpcNW9-yKQ62CcnQpUEFYlTOs0_4H9MijIHY,8127
303
310
  codemie_test_harness/tests/workflow/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -405,7 +412,7 @@ codemie_test_harness/tests/workflow/virtual_assistant_tools/servicenow/__init__.
405
412
  codemie_test_harness/tests/workflow/virtual_assistant_tools/servicenow/test_workflow_with_servicenow_tools.py,sha256=D835gaRbCnB4va5mi9TdA_u9StSpGXQ_fgzwW0S2pwo,1173
406
413
  codemie_test_harness/tests/workflow/virtual_assistant_tools/vcs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
407
414
  codemie_test_harness/tests/workflow/virtual_assistant_tools/vcs/test_workflow_with_vcs_tools.py,sha256=Se9imIiBYuJU78m1pLu0g4ZmHygKZjr6JjIWkGXTy1Q,1364
408
- codemie_test_harness-0.1.221.dist-info/METADATA,sha256=OuLbVODiKmBvq1nHcaT-popN7ecY22G6Mcci97oQCOc,27184
409
- codemie_test_harness-0.1.221.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
410
- codemie_test_harness-0.1.221.dist-info/entry_points.txt,sha256=n98t-EOM5M1mnMl_j2X4siyeO9zr0WD9a5LF7JyElIM,73
411
- codemie_test_harness-0.1.221.dist-info/RECORD,,
415
+ codemie_test_harness-0.1.222.dist-info/METADATA,sha256=yHhjepfUj4HR-VC6ERKK6rGJHDcHsEsgdpI0uR4jMQs,27184
416
+ codemie_test_harness-0.1.222.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
417
+ codemie_test_harness-0.1.222.dist-info/entry_points.txt,sha256=n98t-EOM5M1mnMl_j2X4siyeO9zr0WD9a5LF7JyElIM,73
418
+ codemie_test_harness-0.1.222.dist-info/RECORD,,