1212from hypothesis import given , settings
1313from hypothesis import strategies as st
1414
15+ from stackone_ai .constants import DEFAULT_BASE_URL
1516from stackone_ai .feedback import create_feedback_tool
17+ from tests .conftest import TEST_BASE_URL
1618from stackone_ai .models import StackOneError
1719
1820# Hypothesis strategies for PBT
@@ -48,7 +50,7 @@ class TestFeedbackToolValidation:
4850
4951 def test_missing_required_fields (self ) -> None :
5052 """Test validation errors for missing required fields."""
51- tool = create_feedback_tool (api_key = "test_key" )
53+ tool = create_feedback_tool (api_key = "test_key" , base_url = TEST_BASE_URL )
5254
5355 with pytest .raises (StackOneError , match = "account_id" ):
5456 tool .execute ({"feedback" : "Great tools!" , "tool_names" : ["test_tool" ]})
@@ -61,7 +63,7 @@ def test_missing_required_fields(self) -> None:
6163
6264 def test_empty_and_whitespace_validation (self ) -> None :
6365 """Test validation for empty and whitespace-only strings."""
64- tool = create_feedback_tool (api_key = "test_key" )
66+ tool = create_feedback_tool (api_key = "test_key" , base_url = TEST_BASE_URL )
6567
6668 with pytest .raises (StackOneError , match = "non-empty" ):
6769 tool .execute ({"feedback" : " " , "account_id" : "acc_123456" , "tool_names" : ["test_tool" ]})
@@ -77,7 +79,7 @@ def test_empty_and_whitespace_validation(self) -> None:
7779
7880 def test_multiple_account_ids_validation (self ) -> None :
7981 """Test validation with multiple account IDs."""
80- tool = create_feedback_tool (api_key = "test_key" )
82+ tool = create_feedback_tool (api_key = "test_key" , base_url = TEST_BASE_URL )
8183
8284 with pytest .raises (StackOneError , match = "At least one account ID is required" ):
8385 tool .execute ({"feedback" : "Great tools!" , "account_id" : [], "tool_names" : ["test_tool" ]})
@@ -87,7 +89,7 @@ def test_multiple_account_ids_validation(self) -> None:
8789
8890 def test_invalid_account_id_type (self ) -> None :
8991 """Test validation with invalid account ID type (not string or list)."""
90- tool = create_feedback_tool (api_key = "test_key" )
92+ tool = create_feedback_tool (api_key = "test_key" , base_url = TEST_BASE_URL )
9193
9294 # Pydantic validates input types before our custom validator runs
9395 with pytest .raises (StackOneError , match = "(account_id|Input should be a valid)" ):
@@ -100,7 +102,7 @@ def test_invalid_account_id_type(self) -> None:
100102
101103 def test_invalid_json_input (self ) -> None :
102104 """Test that invalid JSON input raises appropriate error."""
103- tool = create_feedback_tool (api_key = "test_key" )
105+ tool = create_feedback_tool (api_key = "test_key" , base_url = TEST_BASE_URL )
104106
105107 with pytest .raises (StackOneError , match = "Invalid JSON" ):
106108 tool .execute ("not valid json {}" )
@@ -112,7 +114,7 @@ def test_invalid_json_input(self) -> None:
112114 @settings (max_examples = 50 )
113115 def test_whitespace_feedback_validation_pbt (self , whitespace : str ) -> None :
114116 """PBT: Test validation for various whitespace patterns in feedback."""
115- tool = create_feedback_tool (api_key = "test_key" )
117+ tool = create_feedback_tool (api_key = "test_key" , base_url = TEST_BASE_URL )
116118
117119 with pytest .raises (StackOneError , match = "non-empty" ):
118120 tool .execute ({"feedback" : whitespace , "account_id" : "acc_123456" , "tool_names" : ["test_tool" ]})
@@ -121,7 +123,7 @@ def test_whitespace_feedback_validation_pbt(self, whitespace: str) -> None:
121123 @settings (max_examples = 50 )
122124 def test_whitespace_account_id_validation_pbt (self , whitespace : str ) -> None :
123125 """PBT: Test validation for various whitespace patterns in account_id."""
124- tool = create_feedback_tool (api_key = "test_key" )
126+ tool = create_feedback_tool (api_key = "test_key" , base_url = TEST_BASE_URL )
125127
126128 with pytest .raises (StackOneError , match = "non-empty" ):
127129 tool .execute ({"feedback" : "Great!" , "account_id" : whitespace , "tool_names" : ["test_tool" ]})
@@ -130,7 +132,7 @@ def test_whitespace_account_id_validation_pbt(self, whitespace: str) -> None:
130132 @settings (max_examples = 50 )
131133 def test_whitespace_tool_names_validation_pbt (self , whitespace_list : list [str ]) -> None :
132134 """PBT: Test validation for lists containing only whitespace tool names."""
133- tool = create_feedback_tool (api_key = "test_key" )
135+ tool = create_feedback_tool (api_key = "test_key" , base_url = TEST_BASE_URL )
134136
135137 with pytest .raises (StackOneError , match = "At least one tool name" ):
136138 tool .execute ({"feedback" : "Great!" , "account_id" : "acc_123456" , "tool_names" : whitespace_list })
@@ -141,7 +143,7 @@ def test_whitespace_tool_names_validation_pbt(self, whitespace_list: list[str])
141143 @settings (max_examples = 50 )
142144 def test_whitespace_account_ids_list_validation_pbt (self , whitespace_list : list [str ]) -> None :
143145 """PBT: Test validation for lists containing only whitespace account IDs."""
144- tool = create_feedback_tool (api_key = "test_key" )
146+ tool = create_feedback_tool (api_key = "test_key" , base_url = TEST_BASE_URL )
145147
146148 with pytest .raises (StackOneError , match = "At least one valid account ID is required" ):
147149 tool .execute (
@@ -156,17 +158,17 @@ def test_whitespace_account_ids_list_validation_pbt(self, whitespace_list: list[
156158 @settings (max_examples = 50 )
157159 def test_invalid_json_input_pbt (self , invalid_json : str ) -> None :
158160 """PBT: Test that various invalid JSON inputs raise appropriate error."""
159- tool = create_feedback_tool (api_key = "test_key" )
161+ tool = create_feedback_tool (api_key = "test_key" , base_url = TEST_BASE_URL )
160162
161163 with pytest .raises (StackOneError , match = "Invalid JSON" ):
162164 tool .execute (invalid_json )
163165
164166 @respx .mock
165167 def test_json_string_input (self ) -> None :
166168 """Test that JSON string input is properly parsed."""
167- tool = create_feedback_tool (api_key = "test_key" )
169+ tool = create_feedback_tool (api_key = "test_key" , base_url = TEST_BASE_URL )
168170
169- route = respx .post ("https://api.stackone.com /ai/tool-feedback" ).mock (
171+ route = respx .post (f" { TEST_BASE_URL } /ai/tool-feedback" ).mock (
170172 return_value = httpx .Response (200 , json = {"message" : "Success" })
171173 )
172174
@@ -185,10 +187,10 @@ class TestFeedbackToolExecution:
185187 @respx .mock
186188 def test_single_account_execution (self ) -> None :
187189 """Test execution with single account ID."""
188- tool = create_feedback_tool (api_key = "test_key" )
190+ tool = create_feedback_tool (api_key = "test_key" , base_url = TEST_BASE_URL )
189191 api_response = {"message" : "Feedback successfully stored" , "trace_id" : "test-trace-id" }
190192
191- route = respx .post ("https://api.stackone.com /ai/tool-feedback" ).mock (
193+ route = respx .post (f" { TEST_BASE_URL } /ai/tool-feedback" ).mock (
192194 return_value = httpx .Response (200 , json = api_response )
193195 )
194196
@@ -213,10 +215,10 @@ def test_single_account_execution(self) -> None:
213215 @respx .mock
214216 def test_call_method_interface (self ) -> None :
215217 """Test that the .call() method works correctly."""
216- tool = create_feedback_tool (api_key = "test_key" )
218+ tool = create_feedback_tool (api_key = "test_key" , base_url = TEST_BASE_URL )
217219 api_response = {"message" : "Success" , "trace_id" : "test-trace-id" }
218220
219- route = respx .post ("https://api.stackone.com /ai/tool-feedback" ).mock (
221+ route = respx .post (f" { TEST_BASE_URL } /ai/tool-feedback" ).mock (
220222 return_value = httpx .Response (200 , json = api_response )
221223 )
222224
@@ -234,9 +236,9 @@ def test_call_method_interface(self) -> None:
234236 @respx .mock
235237 def test_api_error_handling (self ) -> None :
236238 """Test that API errors are handled properly."""
237- tool = create_feedback_tool (api_key = "test_key" )
239+ tool = create_feedback_tool (api_key = "test_key" , base_url = TEST_BASE_URL )
238240
239- route = respx .post ("https://api.stackone.com /ai/tool-feedback" ).mock (
241+ route = respx .post (f" { TEST_BASE_URL } /ai/tool-feedback" ).mock (
240242 return_value = httpx .Response (401 , json = {"error" : "Unauthorized" })
241243 )
242244
@@ -255,11 +257,11 @@ def test_api_error_handling(self) -> None:
255257 @respx .mock
256258 def test_multiple_account_ids_execution (self ) -> None :
257259 """Test execution with multiple account IDs - both success and mixed scenarios."""
258- tool = create_feedback_tool (api_key = "test_key" )
260+ tool = create_feedback_tool (api_key = "test_key" , base_url = TEST_BASE_URL )
259261 api_response = {"message" : "Feedback successfully stored" , "trace_id" : "test-trace-id" }
260262
261263 # Test all successful case
262- route = respx .post ("https://api.stackone.com /ai/tool-feedback" ).mock (
264+ route = respx .post (f" { TEST_BASE_URL } /ai/tool-feedback" ).mock (
263265 return_value = httpx .Response (200 , json = api_response )
264266 )
265267
@@ -302,7 +304,7 @@ def test_multiple_account_ids_execution(self) -> None:
302304 @respx .mock
303305 def test_multiple_account_ids_mixed_success (self ) -> None :
304306 """Test execution with multiple account IDs - mixed success and error."""
305- tool = create_feedback_tool (api_key = "test_key" )
307+ tool = create_feedback_tool (api_key = "test_key" , base_url = TEST_BASE_URL )
306308
307309 def custom_side_effect (request : httpx .Request ) -> httpx .Response :
308310 body = json .loads (request .content )
@@ -312,7 +314,7 @@ def custom_side_effect(request: httpx.Request) -> httpx.Response:
312314 else :
313315 return httpx .Response (401 , json = {"error" : "Unauthorized" })
314316
315- route = respx .post ("https://api.stackone.com /ai/tool-feedback" ).mock (side_effect = custom_side_effect )
317+ route = respx .post (f" { TEST_BASE_URL } /ai/tool-feedback" ).mock (side_effect = custom_side_effect )
316318
317319 result = tool .execute (
318320 {
@@ -338,7 +340,7 @@ def custom_side_effect(request: httpx.Request) -> httpx.Response:
338340 "status" : "error" ,
339341 "error" : (
340342 "Client error '401 Unauthorized' for url "
341- "'https://api.stackone.com /ai/tool-feedback'\n "
343+ f"' { TEST_BASE_URL } /ai/tool-feedback'\n "
342344 "For more information check: "
343345 "https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401"
344346 ),
@@ -351,7 +353,7 @@ def custom_side_effect(request: httpx.Request) -> httpx.Response:
351353
352354 def test_tool_integration (self ) -> None :
353355 """Test that feedback tool integrates properly with toolset."""
354- feedback_tool = create_feedback_tool (api_key = "test_key" )
356+ feedback_tool = create_feedback_tool (api_key = "test_key" , base_url = TEST_BASE_URL )
355357
356358 assert feedback_tool is not None
357359 assert feedback_tool .name == "tool_feedback"
@@ -376,7 +378,7 @@ def test_live_feedback_submission() -> None:
376378 if not api_key :
377379 pytest .skip ("STACKONE_API_KEY env var required for live feedback test" )
378380
379- base_url = os .getenv ("STACKONE_BASE_URL" , "https://api.stackone.com" )
381+ base_url = os .getenv ("STACKONE_BASE_URL" , DEFAULT_BASE_URL )
380382
381383 feedback_tool = create_feedback_tool (api_key = api_key , base_url = base_url )
382384 assert feedback_tool is not None , "Feedback tool must be available"
0 commit comments