44
55import pytest
66
7+ from fluidize .core .utils .exceptions import ProjectAlreadyExistsError
78from fluidize .managers .registry import RegistryManager
89from tests .fixtures .sample_projects import SampleProjects
910
@@ -35,6 +36,8 @@ def test_create_project_with_all_fields(self, projects_manager, mock_adapter):
3536
3637 sample_project = SampleProjects .standard_project ()
3738 mock_adapter .projects .upsert .return_value = sample_project
39+ # Mock retrieve to raise FileNotFoundError (project doesn't exist yet)
40+ mock_adapter .projects .retrieve .side_effect = FileNotFoundError ("Project not found" )
3841
3942 result = projects_manager .create (
4043 project_id = sample_project .id ,
@@ -65,6 +68,8 @@ def test_create_project_minimal(self, projects_manager, mock_adapter):
6568 project_id = "minimal-create"
6669 minimal_project = SampleProjects .minimal_project ()
6770 mock_adapter .projects .upsert .return_value = minimal_project
71+ # Mock retrieve to raise FileNotFoundError (project doesn't exist yet)
72+ mock_adapter .projects .retrieve .side_effect = FileNotFoundError ("Project not found" )
6873
6974 result = projects_manager .create (project_id )
7075
@@ -81,6 +86,8 @@ def test_create_project_partial_fields(self, projects_manager, mock_adapter):
8186
8287 sample_project = SampleProjects .standard_project ()
8388 mock_adapter .projects .upsert .return_value = sample_project
89+ # Mock retrieve to raise FileNotFoundError (project doesn't exist yet)
90+ mock_adapter .projects .retrieve .side_effect = FileNotFoundError ("Project not found" )
8491
8592 result = projects_manager .create (
8693 project_id = "partial-create" , label = "Partial Project" , description = "Only some fields provided"
@@ -120,6 +127,25 @@ def test_get_project_not_found(self, projects_manager, mock_adapter):
120127
121128 mock_adapter .projects .retrieve .assert_called_once_with (project_id )
122129
130+ def test_create_project_already_exists (self , projects_manager , mock_adapter ):
131+ """Test create method raises error when project already exists."""
132+ sample_project = SampleProjects .standard_project ()
133+ project_id = sample_project .id
134+
135+ # Mock get to return existing project (no FileNotFoundError)
136+ mock_adapter .projects .retrieve .return_value = sample_project
137+
138+ with pytest .raises (ProjectAlreadyExistsError ) as exc_info :
139+ projects_manager .create (project_id , label = "New Label" )
140+
141+ # Verify error message contains project ID
142+ assert project_id in str (exc_info .value )
143+ assert exc_info .value .project_id == project_id
144+
145+ # Verify retrieve was called but upsert was not
146+ mock_adapter .projects .retrieve .assert_called_once_with (project_id )
147+ mock_adapter .projects .upsert .assert_not_called ()
148+
123149 def test_list_projects_empty (self , projects_manager , mock_adapter ):
124150 """Test list method when no projects exist."""
125151 mock_adapter .projects .list .return_value = []
@@ -258,7 +284,8 @@ def test_update_filters_none_values(self, projects_manager, mock_adapter):
258284
259285 def test_adapter_error_propagation (self , projects_manager , mock_adapter ):
260286 """Test that adapter errors are properly propagated through manager methods."""
261- # Test create error
287+ # Test create error - first mock retrieve to return FileNotFoundError (project doesn't exist)
288+ mock_adapter .projects .retrieve .side_effect = FileNotFoundError ("Project not found" )
262289 mock_adapter .projects .upsert .side_effect = ValueError ("Invalid project data" )
263290
264291 with pytest .raises (ValueError , match = "Invalid project data" ):
@@ -290,14 +317,20 @@ def test_manager_adapter_delegation(self, mock_adapter):
290317 mock_adapter .projects .list .return_value = [test_project ]
291318
292319 # Call all manager methods
320+ # Mock retrieve to raise FileNotFoundError (project doesn't exist yet)
321+ mock_adapter .projects .retrieve .side_effect = [
322+ FileNotFoundError ("Project not found" ),
323+ test_project ,
324+ test_project ,
325+ ]
293326 manager .create ("test-create" )
294327 manager .get ("test-get" )
295328 manager .list ()
296329 manager .update ("test-update" , label = "Updated" )
297330
298331 # Verify adapter was called
299332 assert mock_adapter .projects .upsert .call_count == 2 # create + update
300- mock_adapter .projects .retrieve .assert_called_once ()
333+ assert mock_adapter .projects .retrieve .call_count == 2 # create (check if exists) + get
301334 mock_adapter .projects .list .assert_called_once ()
302335
303336 def test_manager_interface_compatibility (self , mock_adapter ):
@@ -327,6 +360,12 @@ def test_project_wrapper_return_types(self, mock_adapter):
327360 mock_adapter .projects .list .return_value = [sample_project ]
328361
329362 # Test create returns Project wrapper
363+ # Mock retrieve to raise FileNotFoundError for create (project doesn't exist yet)
364+ mock_adapter .projects .retrieve .side_effect = [
365+ FileNotFoundError ("Project not found" ),
366+ sample_project ,
367+ sample_project ,
368+ ]
330369 created_project = manager .create ("test-create" )
331370 assert isinstance (created_project , ProjectManager )
332371 assert created_project .id == sample_project .id
@@ -356,6 +395,8 @@ def test_project_wrapper_graph_property_access(self, mock_adapter):
356395 mock_adapter .projects .upsert .return_value = sample_project
357396 mock_adapter .graph = Mock () # Mock graph handler
358397
398+ # Mock retrieve to raise FileNotFoundError (project doesn't exist yet)
399+ mock_adapter .projects .retrieve .side_effect = FileNotFoundError ("Project not found" )
359400 project = manager .create ("test-graph-access" )
360401
361402 # Verify project has graph property
0 commit comments