#!/usr/bin/env python3 """Tests for session backup module.""" import json import os import sys import tempfile import unittest from pathlib import Path sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) from tools.session_backup import SessionBackup class TestSessionBackup(unittest.TestCase): def setUp(self): self.tmp_home = tempfile.mkdtemp() self.tmp_backup = tempfile.mkdtemp() # Create fake home structure home = Path(self.tmp_home) (home / "memories").mkdir() (home / "sessions").mkdir() (home / "cron").mkdir() (home / "config.yaml").write_text("model: test\n") (home / "memories" / "MEMORY.md").write_text("# Memory\nTest entry\n") (home / "memories" / "USER.md").write_text("# User\nTest user\n") (home / "channel_directory.json").write_text("{}") (home / "cron" / "jobs.json").write_text("[]") (home / "sessions" / "sessions.json").write_text("[]") (home / "sessions" / "session_test1.json").write_text('{"id": "test1"}') (home / "sessions" / "session_test2.json").write_text('{"id": "test2"}') self.backup = SessionBackup( home_dir=self.tmp_home, backup_dir=self.tmp_backup, max_backups=3, ) def tearDown(self): import shutil shutil.rmtree(self.tmp_home, ignore_errors=True) shutil.rmtree(self.tmp_backup, ignore_errors=True) def test_create_backup(self): result = self.backup.create_backup("test") self.assertIn("filename", result) self.assertIn("test", result["filename"]) self.assertGreater(result["files_included"], 0) self.assertTrue(Path(result["path"]).exists()) def test_create_backup_includes_critical_files(self): result = self.backup.create_backup("test") # state.db and gateway_state.json don't exist in test fixture self.assertGreater(result["files_included"], 3) def test_list_backups(self): self.backup.create_backup("first") self.backup.create_backup("second") backups = self.backup.list_backups() self.assertEqual(len(backups), 2) self.assertIn("filename", backups[0]) self.assertIn("size", backups[0]) def test_list_backups_empty(self): backups = self.backup.list_backups() self.assertEqual(len(backups), 0) def test_rotation(self): for i in range(5): self.backup.create_backup(f"rot{i}") backups = self.backup.list_backups() self.assertLessEqual(len(backups), 3) # max_backups=3 def test_restore_dry_run(self): self.backup.create_backup("restore-test") backups = self.backup.list_backups() result = self.backup.restore_backup(backups[0]["filename"], dry_run=True) self.assertEqual(result["mode"], "dry_run") self.assertGreater(result["total_files"], 0) def test_restore_not_found(self): result = self.backup.restore_backup("nonexistent.tar.gz") self.assertIn("error", result) def test_check_freshness_no_backups(self): result = self.backup.check_freshness() self.assertFalse(result["fresh"]) self.assertIn("No backups", result["reason"]) def test_check_freshness_fresh(self): self.backup.create_backup("fresh") result = self.backup.check_freshness() self.assertTrue(result["fresh"]) self.assertLess(result["age_hours"], 1) def test_human_size(self): self.assertEqual(SessionBackup._human_size(500), "500.0B") self.assertEqual(SessionBackup._human_size(1024), "1.0KB") self.assertEqual(SessionBackup._human_size(1048576), "1.0MB") def test_missing_files_reported(self): result = self.backup.create_backup("missing") # state.db doesn't exist in test fixture self.assertIn("state.db", result["files_missing"]) if __name__ == "__main__": unittest.main()