feat: add Remnashop migration import

Add the Remnashop legacy importer, compatibility tables, admin toggles, referral and promo lookup compatibility, and tests for the migration flow.
This commit is contained in:
3252a8
2026-06-02 00:13:54 +03:00
parent 56796d9f22
commit 5e47a1496b
18 changed files with 1731 additions and 63 deletions
@@ -44,6 +44,13 @@ BACKUP_SETTINGS = (
"BACKUP_COMPOSE_ENABLED",
)
REMNASHOP_MIGRATION_SETTINGS = (
"MIGRATION_REMNASHOP_REFERRAL_CODE_COMPAT_ENABLED",
"MIGRATION_REMNASHOP_PROMO_CODE_COMPAT_ENABLED",
"MIGRATION_REMNASHOP_IMPORTED_AT",
"MIGRATION_REMNASHOP_NOTES",
)
ADMIN_TARIFF_SETTINGS_PAGE_KEYS = {
"admin_tariffs_trial_title",
"admin_tariffs_trial_subtitle",
@@ -204,6 +211,27 @@ def test_backup_settings_i18n_keys_exist():
assert field["i18n_description_key"] in messages
def test_remnashop_migration_settings_i18n_keys_exist():
manifest = _manifest_by_key()
for setting_key in REMNASHOP_MIGRATION_SETTINGS:
field = manifest[setting_key]
assert field["section"] == "migrations"
assert field["section_order"] == 13
assert field["subsection"] == "Remnashop"
assert field["i18n_subsection_key"] == "admin_settings_subsection_remnashop"
for language in ("ru", "en"):
messages = _locale(language)
assert "admin_settings_section_migrations" in messages
assert "admin_settings_subsection_remnashop" in messages
for setting_key in REMNASHOP_MIGRATION_SETTINGS:
field = manifest[setting_key]
assert field["i18n_label_key"] in messages
assert field["i18n_description_key"] in messages
def test_backup_required_numeric_settings_reject_empty_values():
with pytest.raises(ValueError):
coerce_value(get_field_by_key("BACKUP_INTERVAL_SECONDS"), "")
+44
View File
@@ -0,0 +1,44 @@
from datetime import datetime, timezone
from scripts.import_legacy import (
remnashop_months_from_plan_snapshot,
remnashop_pricing_amount,
remnashop_pricing_currency,
remnashop_sale_mode,
remnashop_traffic_gb_to_bytes,
remnashop_transaction_status,
)
def test_remnashop_pricing_helpers_read_final_amount_and_currency():
pricing = {"final_amount": "199.50", "currency": "rub"}
assert remnashop_pricing_amount(pricing) == 199.5
assert remnashop_pricing_currency(pricing) == "RUB"
def test_remnashop_traffic_limit_is_converted_from_gib():
assert remnashop_traffic_gb_to_bytes(10) == 10 * 1024**3
assert remnashop_traffic_gb_to_bytes(None) is None
def test_remnashop_status_and_sale_mode_mapping_matches_current_payment_model():
assert remnashop_transaction_status("COMPLETED", "YOOKASSA") == "succeeded"
assert remnashop_transaction_status("PENDING", "WATA") == "pending_wata"
assert remnashop_transaction_status("CANCELED", "WATA") == "canceled"
assert remnashop_sale_mode("NEW") == "subscription"
assert remnashop_sale_mode("RENEW") == "subscription"
assert remnashop_sale_mode("CHANGE") == "tariff_upgrade"
def test_remnashop_plan_months_prefers_snapshot_then_dates():
assert remnashop_months_from_plan_snapshot({"duration_days": 90}) == 3
assert remnashop_months_from_plan_snapshot({"months": 12}) == 12
assert (
remnashop_months_from_plan_snapshot(
{},
created_at=datetime(2026, 1, 1, tzinfo=timezone.utc),
expire_at=datetime(2026, 4, 1, tzinfo=timezone.utc),
)
== 3
)
+22 -1
View File
@@ -1,5 +1,11 @@
from db.migrator import MIGRATIONS
from db.models import SupportTicket, SupportTicketMessage, User
from db.models import (
LegacyImportMapping,
LegacyReferralCode,
SupportTicket,
SupportTicketMessage,
User,
)
def test_support_migration_is_registered_after_existing_revisions():
@@ -39,3 +45,18 @@ def test_trial_eligibility_reset_migration_and_model_are_registered():
"0032_add_telegram_notification_status"
)
assert "trial_eligibility_reset_at" in User.__table__.columns
def test_legacy_import_compatibility_migration_and_models_are_registered():
ids = [migration.id for migration in MIGRATIONS]
assert "0034_add_legacy_import_compatibility" in ids
assert ids.index("0034_add_legacy_import_compatibility") > ids.index(
"0033_add_trial_eligibility_reset_marker"
)
assert User.__table__.columns["referral_code"].type.length == 64
assert LegacyReferralCode.__tablename__ == "legacy_referral_codes"
assert LegacyImportMapping.__tablename__ == "legacy_import_mappings"
assert "uq_legacy_referral_source_code" in {
constraint.name for constraint in LegacyReferralCode.__table__.constraints
}
+4
View File
@@ -230,6 +230,8 @@ class UserDalMergeTests(unittest.IsolatedAsyncioTestCase):
)
self.assertIn("support_ticket_messages", update_tables)
self.assertIn("email_verification_codes", delete_tables)
self.assertIn("legacy_referral_codes", delete_tables)
self.assertIn("legacy_import_mappings", delete_tables)
session.delete.assert_awaited_once_with(user)
session.flush.assert_awaited_once()
@@ -366,6 +368,8 @@ class UserDalMergeTests(unittest.IsolatedAsyncioTestCase):
self.assertIn("payments", update_tables)
self.assertIn("promo_code_activations", update_tables)
self.assertIn("user_payment_methods", update_tables)
self.assertIn("legacy_referral_codes", update_tables)
self.assertIn("legacy_import_mappings", update_tables)
self.assertIn("message_logs", update_tables)
self.assertIn("users", update_tables)
self.assertIn("user_payment_methods", delete_tables)