@@ -60,6 +60,40 @@ def mock_io_error_response(mock_client: BaseFakeClient) -> None:
6060 )
6161
6262
63+ def make_component_run_response () -> dict [str , Any ]:
64+ return {"prompt" : "Generated prompt text" , "metadata" : {"some_key" : "some_value" }}
65+
66+
67+ @pytest .fixture
68+ def mock_successful_run_response (mock_client : BaseFakeClient ) -> None :
69+ """Configure the mock client to return a successful component run response."""
70+ mock_client .responses ["v1/haystack/components/run" ] = TransportResponse (
71+ status_code = 200 ,
72+ json = make_component_run_response (),
73+ text = json .dumps (make_component_run_response ()),
74+ )
75+
76+
77+ @pytest .fixture
78+ def mock_run_error_response (mock_client : BaseFakeClient ) -> None :
79+ """Configure the mock client to return an error response for component run."""
80+ mock_client .responses ["v1/haystack/components/run" ] = TransportResponse (
81+ status_code = 500 ,
82+ json = {"message" : "Internal server error" },
83+ text = "Internal server error" ,
84+ )
85+
86+
87+ @pytest .fixture
88+ def mock_successful_workspace_run_response (mock_client : BaseFakeClient ) -> None :
89+ """Configure the mock client to return a successful workspace component run response."""
90+ mock_client .responses ["v1/workspaces/test-workspace/haystack/components/run" ] = TransportResponse (
91+ status_code = 200 ,
92+ json = make_component_run_response (),
93+ text = json .dumps (make_component_run_response ()),
94+ )
95+
96+
6397def test_initialization (mock_client : BaseFakeClient ) -> None :
6498 """Test HaystackServiceResource initialization."""
6599 resource = HaystackServiceResource (client = mock_client )
@@ -115,3 +149,143 @@ async def test_get_component_input_output_error(
115149 resource = HaystackServiceResource (client = mock_client )
116150 with pytest .raises (UnexpectedAPIError ):
117151 await resource .get_component_input_output ("Agent" )
152+
153+
154+ @pytest .mark .asyncio
155+ async def test_run_component_success (
156+ mock_client : BaseFakeClient ,
157+ mock_successful_run_response : None ,
158+ ) -> None :
159+ """Test successful component run."""
160+ resource = HaystackServiceResource (client = mock_client )
161+ result = await resource .run_component (
162+ component_type = "haystack.components.builders.PromptBuilder" ,
163+ init_params = {"some_parameter" : "some_value" },
164+ input_data = {"question" : "What does it do" },
165+ input_types = {"question" : "str" },
166+ )
167+
168+ assert result == make_component_run_response ()
169+ request = mock_client .requests [- 1 ]
170+ assert request ["method" ] == "POST"
171+ assert request ["endpoint" ] == "v1/haystack/components/run"
172+ assert request ["headers" ] == {
173+ "accept" : "application/json" ,
174+ "content-type" : "application/json" ,
175+ }
176+ assert request ["data" ] == {
177+ "component_type" : "haystack.components.builders.PromptBuilder" ,
178+ "init_params" : {"some_parameter" : "some_value" },
179+ "input" : {"question" : "What does it do" },
180+ "input_types" : {"question" : "str" },
181+ }
182+
183+
184+ @pytest .mark .asyncio
185+ async def test_run_component_minimal_params (
186+ mock_client : BaseFakeClient ,
187+ mock_successful_run_response : None ,
188+ ) -> None :
189+ """Test component run with minimal parameters."""
190+ resource = HaystackServiceResource (client = mock_client )
191+ result = await resource .run_component (component_type = "haystack.components.builders.PromptBuilder" )
192+
193+ assert result == make_component_run_response ()
194+ request = mock_client .requests [- 1 ]
195+ assert request ["method" ] == "POST"
196+ assert request ["endpoint" ] == "v1/haystack/components/run"
197+ assert request ["headers" ] == {
198+ "accept" : "application/json" ,
199+ "content-type" : "application/json" ,
200+ }
201+ assert request ["data" ] == {
202+ "component_type" : "haystack.components.builders.PromptBuilder" ,
203+ "init_params" : {},
204+ "input" : {},
205+ }
206+
207+
208+ @pytest .mark .asyncio
209+ async def test_run_component_without_input_types (
210+ mock_client : BaseFakeClient ,
211+ mock_successful_run_response : None ,
212+ ) -> None :
213+ """Test component run without input_types (should be inferred)."""
214+ resource = HaystackServiceResource (client = mock_client )
215+ result = await resource .run_component (
216+ component_type = "haystack.components.builders.PromptBuilder" ,
217+ init_params = {"template" : "Hello {{name}}" },
218+ input_data = {"name" : "World" },
219+ )
220+
221+ assert result == make_component_run_response ()
222+ request = mock_client .requests [- 1 ]
223+ assert "input_types" not in request ["data" ]
224+
225+
226+ @pytest .mark .asyncio
227+ async def test_run_component_error (
228+ mock_client : BaseFakeClient ,
229+ mock_run_error_response : None ,
230+ ) -> None :
231+ """Test error handling in component run."""
232+ resource = HaystackServiceResource (client = mock_client )
233+
234+ with pytest .raises (UnexpectedAPIError ):
235+ await resource .run_component (component_type = "haystack.components.builders.PromptBuilder" )
236+
237+
238+ @pytest .mark .asyncio
239+ async def test_run_component_with_workspace (
240+ mock_client : BaseFakeClient ,
241+ mock_successful_workspace_run_response : None ,
242+ ) -> None :
243+ """Test component run with workspace parameter."""
244+ resource = HaystackServiceResource (client = mock_client )
245+ result = await resource .run_component (
246+ component_type = "haystack.components.builders.PromptBuilder" ,
247+ init_params = {"template" : "Hello {{name}}" },
248+ input_data = {"name" : "World" },
249+ workspace = "test-workspace" ,
250+ )
251+
252+ assert result == make_component_run_response ()
253+ request = mock_client .requests [- 1 ]
254+ assert request ["method" ] == "POST"
255+ assert request ["endpoint" ] == "v1/workspaces/test-workspace/haystack/components/run"
256+ assert request ["headers" ] == {
257+ "accept" : "application/json" ,
258+ "content-type" : "application/json" ,
259+ }
260+ assert request ["data" ] == {
261+ "component_type" : "haystack.components.builders.PromptBuilder" ,
262+ "init_params" : {"template" : "Hello {{name}}" },
263+ "input" : {"name" : "World" },
264+ }
265+
266+
267+ @pytest .mark .asyncio
268+ async def test_run_component_with_workspace_and_input_types (
269+ mock_client : BaseFakeClient ,
270+ mock_successful_workspace_run_response : None ,
271+ ) -> None :
272+ """Test component run with workspace and input_types parameters."""
273+ resource = HaystackServiceResource (client = mock_client )
274+ result = await resource .run_component (
275+ component_type = "haystack.components.builders.PromptBuilder" ,
276+ init_params = {"template" : "Hello {{name}}" },
277+ input_data = {"name" : "World" },
278+ input_types = {"name" : "str" },
279+ workspace = "test-workspace" ,
280+ )
281+
282+ assert result == make_component_run_response ()
283+ request = mock_client .requests [- 1 ]
284+ assert request ["method" ] == "POST"
285+ assert request ["endpoint" ] == "v1/workspaces/test-workspace/haystack/components/run"
286+ assert request ["data" ] == {
287+ "component_type" : "haystack.components.builders.PromptBuilder" ,
288+ "init_params" : {"template" : "Hello {{name}}" },
289+ "input" : {"name" : "World" },
290+ "input_types" : {"name" : "str" },
291+ }
0 commit comments