113 lines
3.8 KiB
Python
113 lines
3.8 KiB
Python
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()
|