feat: add tariff config and database schema
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import unittest
|
||||
import json
|
||||
|
||||
from pydantic import ValidationError
|
||||
|
||||
@@ -26,3 +27,56 @@ class SettingsTests(unittest.TestCase):
|
||||
self.assertTrue(settings.WEBAPP_SESSION_SECRET)
|
||||
self.assertTrue(settings.WEBHOOK_SECRET_TOKEN)
|
||||
self.assertEqual(settings.WEBAPP_SESSION_TTL_SECONDS, 86400)
|
||||
|
||||
def test_tariffs_config_missing_uses_legacy_fallback(self):
|
||||
settings = Settings(
|
||||
_env_file=None,
|
||||
BOT_TOKEN="token",
|
||||
POSTGRES_USER="app_user",
|
||||
POSTGRES_PASSWORD="app_password",
|
||||
TARIFFS_CONFIG_PATH="missing-tariffs.json",
|
||||
TRAFFIC_PACKAGES="10:199",
|
||||
)
|
||||
|
||||
self.assertIsNone(settings.tariffs_config)
|
||||
self.assertTrue(settings.traffic_sale_mode)
|
||||
|
||||
def test_existing_tariffs_config_disables_legacy_traffic_mode(self):
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
path = Path(tmpdir) / "tariffs.json"
|
||||
path.write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"default_tariff": "standard",
|
||||
"tariffs": [
|
||||
{
|
||||
"key": "standard",
|
||||
"names": {"ru": "Стандарт"},
|
||||
"descriptions": {},
|
||||
"squad_uuids": ["uuid"],
|
||||
"billing_model": "period",
|
||||
"monthly_gb": 100,
|
||||
"prices_rub": {"1": 150},
|
||||
"prices_stars": {"1": 0},
|
||||
"enabled_periods": [1],
|
||||
"enabled": True,
|
||||
}
|
||||
],
|
||||
}
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
settings = Settings(
|
||||
_env_file=None,
|
||||
BOT_TOKEN="token",
|
||||
POSTGRES_USER="app_user",
|
||||
POSTGRES_PASSWORD="app_password",
|
||||
TARIFFS_CONFIG_PATH=str(path),
|
||||
TRAFFIC_PACKAGES="10:199",
|
||||
)
|
||||
|
||||
self.assertIsNotNone(settings.tariffs_config)
|
||||
self.assertFalse(settings.traffic_sale_mode)
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
import json
|
||||
import unittest
|
||||
|
||||
|
||||
from config.tariffs_config import TariffsConfig, load_tariffs_config
|
||||
|
||||
|
||||
def _valid_config():
|
||||
return {
|
||||
"default_tariff": "standard",
|
||||
"topup_packages_default": {
|
||||
"rub": [{"gb": 10, "price": 99}],
|
||||
"stars": [{"gb": 10, "price": 2500}],
|
||||
},
|
||||
"tariffs": [
|
||||
{
|
||||
"key": "standard",
|
||||
"names": {"ru": "Стандарт", "en": "Standard"},
|
||||
"descriptions": {"ru": "Base"},
|
||||
"squad_uuids": ["uuid-1"],
|
||||
"billing_model": "period",
|
||||
"monthly_gb": 500,
|
||||
"prices_rub": {"1": 150},
|
||||
"prices_stars": {"1": 0},
|
||||
"enabled_periods": [1],
|
||||
"enabled": True,
|
||||
},
|
||||
{
|
||||
"key": "traffic",
|
||||
"names": {"ru": "Гигабайты"},
|
||||
"descriptions": {},
|
||||
"squad_uuids": ["uuid-1"],
|
||||
"billing_model": "traffic",
|
||||
"traffic_packages": {"rub": [{"gb": 10, "price": 199}], "stars": []},
|
||||
"enabled": True,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
class TariffsConfigTests(unittest.TestCase):
|
||||
def test_valid_tariffs_config_loads(self):
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
path = Path(tmpdir) / "tariffs.json"
|
||||
path.write_text(json.dumps(_valid_config()), encoding="utf-8")
|
||||
|
||||
config = load_tariffs_config(path)
|
||||
|
||||
self.assertIsNotNone(config)
|
||||
self.assertEqual(config.default.key, "standard")
|
||||
self.assertEqual(config.require("traffic").rub_per_gb_for_conversion(), 19.9)
|
||||
|
||||
def test_missing_config_returns_none(self):
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
self.assertIsNone(load_tariffs_config(Path(tmpdir) / "missing.json"))
|
||||
|
||||
def test_duplicate_keys_rejected(self):
|
||||
data = _valid_config()
|
||||
data["tariffs"][1]["key"] = "standard"
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
TariffsConfig.model_validate(data)
|
||||
|
||||
def test_default_must_be_enabled(self):
|
||||
data = _valid_config()
|
||||
data["default_tariff"] = "missing"
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
TariffsConfig.model_validate(data)
|
||||
|
||||
def test_period_price_required_for_enabled_period(self):
|
||||
data = _valid_config()
|
||||
data["tariffs"][0]["prices_rub"] = {"1": 0}
|
||||
data["tariffs"][0]["prices_stars"] = {"1": 0}
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
TariffsConfig.model_validate(data)
|
||||
|
||||
def test_traffic_without_rub_needs_conversion_rate(self):
|
||||
data = _valid_config()
|
||||
data["tariffs"][1]["traffic_packages"] = {"rub": [], "stars": [{"gb": 10, "price": 2500}]}
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
TariffsConfig.model_validate(data)
|
||||
Reference in New Issue
Block a user