import os import tempfile import unittest from pathlib import Path from app.services.factory_reset import ( FACTORY_RESET_CONFIRM_PHRASE, assert_safe_factory_reset_target, factory_reset_preview, validate_factory_reset_request, ) class FactoryResetSafetyTests(unittest.TestCase): def setUp(self) -> None: self._tmp = tempfile.mkdtemp(prefix="wesp-factory-reset-") self.base = Path(self._tmp) self.data = self.base / "data" self.data.mkdir(parents=True) (self.data / "recipes.db").write_bytes(b"x" * 10) def test_preview_lists_existing_files(self) -> None: preview = factory_reset_preview(self.data, self.base) self.assertTrue(preview["has_anything_to_reset"]) paths = {f["path"] for f in preview["files"]} self.assertIn("recipes.db", paths) self.assertEqual(preview["confirm_phrase"], FACTORY_RESET_CONFIRM_PHRASE) def test_rejects_data_dir_outside_base(self) -> None: other = Path(tempfile.mkdtemp(prefix="wesp-factory-reset-other-")) with self.assertRaises(ValueError): assert_safe_factory_reset_target(other / "data", self.base) def test_rejects_non_data_directory_name(self) -> None: wrong = self.base / "storage" wrong.mkdir() with self.assertRaises(ValueError): assert_safe_factory_reset_target(wrong, self.base) def test_validate_phrase(self) -> None: ok, err, _, _ = validate_factory_reset_request( {"confirmation_phrase": FACTORY_RESET_CONFIRM_PHRASE} ) self.assertTrue(ok) self.assertEqual(err, "") bad, err2, _, _ = validate_factory_reset_request({"confirmation_phrase": "wrong"}) self.assertFalse(bad) self.assertIn(FACTORY_RESET_CONFIRM_PHRASE, err2) class FactoryResetAdminApiTests(unittest.TestCase): def setUp(self) -> None: from tests.test_admin_panel_access_and_users import AdminPanelTestConfig from app import create_app, db from app.models import WebUser from werkzeug.security import generate_password_hash self.app = create_app(AdminPanelTestConfig) self.client = self.app.test_client() self.ctx = self.app.app_context() self.ctx.push() os.makedirs(AdminPanelTestConfig.DATA_DIR, exist_ok=True) db.create_all() db.session.add( WebUser( login="admin", password_hash=generate_password_hash("admin-secret"), is_superuser=True, ) ) db.session.commit() from app.services.setup_state import mark_setup_complete mark_setup_complete(self.app) login = self.client.post( "/api/auth/login", json={"login": "admin", "password": "admin-secret"} ) self.assertEqual(login.status_code, 200) def tearDown(self) -> None: from app import db db.session.remove() db.drop_all() self.ctx.pop() def test_preview_requires_superuser_session(self) -> None: from app.services.setup_state import mark_setup_complete mark_setup_complete(self.app) anon = self.app.test_client() r = anon.get("/api/admin/factory-reset/preview") self.assertIn(r.status_code, (401, 403)) def test_preview_ok(self) -> None: r = self.client.get("/api/admin/factory-reset/preview") self.assertEqual(r.status_code, 200) body = r.get_json() self.assertEqual(body.get("status"), "success") self.assertIn("confirm_phrase", body) def test_post_rejects_bad_phrase(self) -> None: r = self.client.post( "/api/admin/factory-reset", json={"confirmation_phrase": "нет"}, ) self.assertEqual(r.status_code, 400) if __name__ == "__main__": unittest.main()