@@ -185,3 +185,82 @@ def test_save_viewable_workflow_from_object(client: FlaskClient) -> None:
185185 assert isinstance (data_id , str ) and len (data_id ) > 0
186186 assert response .get_json ()["geode_object_type" ] == "EdgedCurve3D"
187187 assert response .get_json ()["viewable_file" ].endswith (".vtp" )
188+
189+
190+ def test_import_extension_route (client : FlaskClient , tmp_path : Path ) -> None :
191+ """Test importing a .vext extension file."""
192+ route = "/opengeodeweb_back/import_extension"
193+ original_data_folder = client .application .config ["DATA_FOLDER_PATH" ]
194+ client .application .config ["DATA_FOLDER_PATH" ] = os .path .join (
195+ str (tmp_path ), "extension_test_data"
196+ )
197+ vext_path = tmp_path / "test-extension-1.0.0.vext"
198+ with zipfile .ZipFile (vext_path , "w" , compression = zipfile .ZIP_DEFLATED ) as zipf :
199+ zipf .writestr (
200+ "dist/test-extension-extension.es.js" ,
201+ "export const metadata = { id: 'test-extension', name: 'Test Extension' };" ,
202+ )
203+ zipf .writestr ("dist/test-extension-back" , "#!/bin/bash\n echo 'mock backend'" )
204+ zipf .writestr ("dist/test-extension.css" , ".test { color: red; }" )
205+ with open (vext_path , "rb" ) as f :
206+ response = client .post (
207+ route ,
208+ data = {"file" : (f , "test-extension-1.0.0.vext" )},
209+ content_type = "multipart/form-data" ,
210+ )
211+ assert response .status_code == 200
212+ json_data = response .get_json ()
213+ assert "extension_name" in json_data
214+ assert "frontend_path" in json_data
215+ assert "backend_path" in json_data
216+ assert "extension_folder" in json_data
217+ assert json_data ["extension_name" ] == "test-extension"
218+ extensions_folder = os .path .join (
219+ client .application .config ["DATA_FOLDER_PATH" ], "extensions"
220+ )
221+ extension_path = os .path .join (extensions_folder , "test-extension" )
222+ assert os .path .exists (extension_path )
223+ dist_path = os .path .join (extension_path , "dist" )
224+ assert os .path .exists (dist_path )
225+ frontend_js = json_data ["frontend_path" ]
226+ assert os .path .exists (frontend_js )
227+ assert frontend_js .endswith ("-extension.es.js" )
228+ backend_exec = json_data ["backend_path" ]
229+ assert os .path .exists (backend_exec )
230+ assert os .access (backend_exec , os .X_OK )
231+ client .application .config ["DATA_FOLDER_PATH" ] = original_data_folder
232+
233+
234+ def test_import_extension_invalid_file (client : FlaskClient , tmp_path : Path ) -> None :
235+ """Test importing an invalid .vext file (missing dist folder)."""
236+ route = "/opengeodeweb_back/import_extension"
237+ original_data_folder = client .application .config ["DATA_FOLDER_PATH" ]
238+ client .application .config ["DATA_FOLDER_PATH" ] = os .path .join (
239+ str (tmp_path ), "extension_invalid_test"
240+ )
241+ vext_path = tmp_path / "invalid-extension.vext"
242+ with zipfile .ZipFile (vext_path , "w" ) as zipf :
243+ zipf .writestr ("README.md" , "This is invalid" )
244+ with open (vext_path , "rb" ) as f :
245+ response = client .post (
246+ route ,
247+ data = {"file" : (f , "invalid-extension.vext" )},
248+ content_type = "multipart/form-data" ,
249+ )
250+ assert response .status_code == 400
251+ client .application .config ["DATA_FOLDER_PATH" ] = original_data_folder
252+
253+
254+ def test_import_extension_wrong_extension (client : FlaskClient , tmp_path : Path ) -> None :
255+ """Test uploading a file with wrong extension."""
256+ route = "/opengeodeweb_back/import_extension"
257+ wrong_file = tmp_path / "not-an-extension.zip"
258+ with open (wrong_file , "wb" ) as f :
259+ f .write (b"test content" )
260+ with open (wrong_file , "rb" ) as f :
261+ response = client .post (
262+ route ,
263+ data = {"file" : (f , "not-an-extension.zip" )},
264+ content_type = "multipart/form-data" ,
265+ )
266+ assert response .status_code == 400
0 commit comments