Release v0.1.2

This commit is contained in:
2026-06-25 19:58:20 +02:00
parent 15794e920e
commit 02564047e9
73 changed files with 4073 additions and 478 deletions

View File

@@ -12,6 +12,7 @@ from govoplan_core.db.base import Base
from govoplan_core.db.migrations import (
REVISION_AUTH_RBAC,
REVISION_FILE_FOLDERS,
REVISION_HIERARCHICAL_SETTINGS,
alembic_config,
migrate_database,
)
@@ -151,6 +152,85 @@ class DatabaseMigrationTests(unittest.TestCase):
self.assertEqual(system_owner_count, 1 if user_count else 0)
finally:
engine.dispose()
def test_repairs_current_schema_stamped_at_file_folders(self) -> None:
with tempfile.TemporaryDirectory(prefix="msm-current-schema-marker-test-") as directory:
database = Path(directory) / "current-schema-marker.db"
url = f"sqlite:///{database}"
command.upgrade(alembic_config(database_url=url), REVISION_HIERARCHICAL_SETTINGS)
engine = create_engine(url)
try:
with engine.begin() as connection:
connection.execute(
text(
"""
INSERT INTO mail_server_profiles
(id, tenant_id, scope_type, scope_id, name, slug, description, is_active,
smtp_config, smtp_password_encrypted, imap_config, imap_password_encrypted,
created_by_user_id, updated_by_user_id, created_at, updated_at)
VALUES
('profile-1', NULL, 'system', 'system', 'System Mail', 'system-mail', NULL, 1,
:smtp_config, NULL, :imap_config, NULL,
NULL, NULL, '2026-06-25 15:00:00', '2026-06-25 15:00:00')
"""
),
{
"smtp_config": '{"host":"smtp.example.test","port":587,"security":"starttls","username":"smtp-user","enabled":true}',
"imap_config": '{"host":"imap.example.test","port":993,"security":"ssl","username":"imap-user","enabled":true}',
},
)
connection.execute(
text("UPDATE alembic_version SET version_num = :revision"),
{"revision": REVISION_FILE_FOLDERS},
)
with engine.connect() as connection:
self.assertEqual(
MigrationContext.configure(connection).get_current_revision(),
REVISION_FILE_FOLDERS,
)
profile_columns = {
column["name"]
for column in inspect(connection).get_columns("mail_server_profiles")
}
self.assertNotIn("smtp_username", profile_columns)
self.assertNotIn("imap_username", profile_columns)
finally:
engine.dispose()
result = migrate_database(database_url=url)
self.assertEqual(result.previous_revision, REVISION_FILE_FOLDERS)
self.assertEqual(result.reconciled_revision, REVISION_HIERARCHICAL_SETTINGS)
engine = create_engine(url)
try:
with engine.connect() as connection:
self.assertEqual(
MigrationContext.configure(connection).get_current_revision(),
result.current_revision,
)
profile_columns = {
column["name"]
for column in inspect(connection).get_columns("mail_server_profiles")
}
profile = connection.execute(text(
"""
SELECT smtp_username, smtp_config, imap_username, imap_config
FROM mail_server_profiles
WHERE id = 'profile-1'
"""
)).mappings().one()
self.assertIn("smtp_username", profile_columns)
self.assertIn("imap_username", profile_columns)
self.assertEqual(profile["smtp_username"], "smtp-user")
self.assertEqual(profile["imap_username"], "imap-user")
self.assertNotIn("username", profile["smtp_config"])
self.assertNotIn("enabled", profile["smtp_config"])
self.assertNotIn("username", profile["imap_config"])
self.assertNotIn("enabled", profile["imap_config"])
finally:
engine.dispose()
def test_migrates_legacy_login_identity_and_bootstraps_system_owner(self) -> None:
with tempfile.TemporaryDirectory(prefix="msm-account-migration-test-") as directory:
database = Path(directory) / "accounts.db"