@@ -117,11 +117,14 @@ def test_search_endpoint_calls_bubble_from_dict(self):
117117
118118 def test_workspace_tabs_endpoint_calls_bubble_from_dict (self ):
119119 from app import create_app
120- import api .workspaces as workspaces_mod
120+ import services .workspace_db as workspace_db_mod
121+ from models import Bubble
121122 app = create_app ()
122123 app .config ["TESTING" ] = True
123124 app .config ["EXCLUSION_RULES" ] = []
124- with patch .object (workspaces_mod .Bubble , "from_dict" , wraps = workspaces_mod .Bubble .from_dict ) as spy :
125+ with patch .object (
126+ workspace_db_mod .Bubble , "from_dict" , wraps = Bubble .from_dict
127+ ) as spy :
125128 client = app .test_client ()
126129 response = client .get (f"/api/workspaces/{ WORKSPACE_ID } /tabs" )
127130 self .assertEqual (response .status_code , 200 )
@@ -163,17 +166,20 @@ def test_bubble_schema_drift_is_logged_not_swallowed_silently(self):
163166 msg = "drift log must include the offending bubble id" )
164167
165168 def test_workspace_tabs_endpoint_calls_composer_from_dict (self ):
166- # Brad's most-important finding: list_workspaces() at api/workspaces.py:605
167- # validates each composer with Composer.from_dict, but get_workspace_tabs()
168- # in the same file used raw json.loads. Schema drift would have been hidden
169- # from one of the two primary conversation-browsing paths. This test pins
170- # that BOTH paths must now validate via the model.
169+ # Brad's most-important finding: list_workspaces() validates each composer
170+ # with Composer.from_dict, but get_workspace_tabs() used raw json.loads.
171+ # Schema drift would have been hidden from one of the two primary
172+ # conversation-browsing paths. This test pins that BOTH paths must now
173+ # validate via the model.
171174 from app import create_app
172- import api .workspaces as workspaces_mod
175+ import services .workspace_tabs as workspace_tabs_mod
176+ from models import Composer
173177 app = create_app ()
174178 app .config ["TESTING" ] = True
175179 app .config ["EXCLUSION_RULES" ] = []
176- with patch .object (workspaces_mod .Composer , "from_dict" , wraps = workspaces_mod .Composer .from_dict ) as spy :
180+ with patch .object (
181+ workspace_tabs_mod .Composer , "from_dict" , wraps = Composer .from_dict
182+ ) as spy :
177183 client = app .test_client ()
178184 response = client .get (f"/api/workspaces/{ WORKSPACE_ID } /tabs" )
179185 self .assertEqual (response .status_code , 200 )
@@ -220,8 +226,13 @@ def test_composers_endpoint_calls_workspace_from_dict(self):
220226
221227 def test_workspace_display_name_calls_workspace_from_dict (self ):
222228 from services .workspace_resolver import lookup_workspace_display_name
223- import api .workspaces as workspaces_mod
224- with patch .object (workspaces_mod .Workspace , "from_dict" , wraps = workspaces_mod .Workspace .from_dict ) as spy :
229+ import services .workspace_resolver as workspace_resolver_mod
230+ from models import Workspace
231+ with patch .object (
232+ workspace_resolver_mod .Workspace ,
233+ "from_dict" ,
234+ wraps = Workspace .from_dict ,
235+ ) as spy :
225236 name = lookup_workspace_display_name (self .workspace_path , WORKSPACE_ID )
226237 self .assertIsInstance (name , str )
227238 self .assertGreaterEqual (
0 commit comments