@@ -0,0 +1,112 @@
|
||||
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()
|
||||
Reference in New Issue
Block a user