Step 2: Add seeding logic for pricing config
- Add seed_pricing_config() function to seed.py - Seed initial values from shared/constants.json - Add seeding to seed_e2e.py for E2E tests - Add tests for seeding functionality
This commit is contained in:
parent
32ce27180d
commit
74b934135a
3 changed files with 178 additions and 0 deletions
|
|
@ -1,7 +1,9 @@
|
|||
"""Seed the database with roles, permissions, and dev users."""
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
|
@ -16,6 +18,7 @@ from models import (
|
|||
Role,
|
||||
User,
|
||||
)
|
||||
from repositories.pricing import PricingRepository
|
||||
|
||||
DEV_USER_EMAIL = os.environ["DEV_USER_EMAIL"]
|
||||
DEV_USER_PASSWORD = os.environ["DEV_USER_PASSWORD"]
|
||||
|
|
@ -78,6 +81,49 @@ async def upsert_user(
|
|||
return user
|
||||
|
||||
|
||||
async def seed_pricing_config(db: AsyncSession) -> None:
|
||||
"""Seed initial pricing configuration from shared/constants.json."""
|
||||
# Load constants from shared/constants.json
|
||||
constants_path = Path(__file__).parent.parent / "shared" / "constants.json"
|
||||
with constants_path.open() as f:
|
||||
constants = json.load(f)
|
||||
|
||||
exchange_config = constants["exchange"]
|
||||
premium_percentage = exchange_config["premiumPercentage"]
|
||||
eur_trade_min = exchange_config["eurTradeMin"]
|
||||
eur_trade_max = exchange_config["eurTradeMax"]
|
||||
|
||||
# Convert EUR amounts to cents
|
||||
eur_min_cents = eur_trade_min * 100
|
||||
eur_max_cents = eur_trade_max * 100
|
||||
|
||||
repo = PricingRepository(db)
|
||||
config = await repo.create_or_update(
|
||||
premium_buy=premium_percentage,
|
||||
premium_sell=premium_percentage,
|
||||
small_trade_threshold_eur=0, # Default: no small trade extra (admin will set)
|
||||
small_trade_extra_premium=0, # Default: no extra premium
|
||||
eur_min_buy=eur_min_cents,
|
||||
eur_max_buy=eur_max_cents,
|
||||
eur_min_sell=eur_min_cents,
|
||||
eur_max_sell=eur_max_cents,
|
||||
)
|
||||
|
||||
if config.id: # If config already existed (was updated)
|
||||
print("Updated pricing config")
|
||||
else:
|
||||
print("Created pricing config")
|
||||
print(f" Premium BUY: {config.premium_buy}%, Premium SELL: {config.premium_sell}%")
|
||||
print(
|
||||
f" Trade limits BUY: €{config.eur_min_buy / 100:.0f} - "
|
||||
f"€{config.eur_max_buy / 100:.0f}"
|
||||
)
|
||||
print(
|
||||
f" Trade limits SELL: €{config.eur_min_sell / 100:.0f} - "
|
||||
f"€{config.eur_max_sell / 100:.0f}"
|
||||
)
|
||||
|
||||
|
||||
async def seed() -> None:
|
||||
async with engine.begin() as conn:
|
||||
await conn.run_sync(Base.metadata.create_all)
|
||||
|
|
@ -99,6 +145,9 @@ async def seed() -> None:
|
|||
# Create admin dev user
|
||||
await upsert_user(db, DEV_ADMIN_EMAIL, DEV_ADMIN_PASSWORD, [ROLE_ADMIN])
|
||||
|
||||
print("\n=== Seeding Pricing Config ===")
|
||||
await seed_pricing_config(db)
|
||||
|
||||
await db.commit()
|
||||
print("\n=== Seeding Complete ===\n")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
"""Fast re-seeding function for e2e tests - only seeds essential data."""
|
||||
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
|
@ -13,6 +15,7 @@ from models import (
|
|||
Role,
|
||||
User,
|
||||
)
|
||||
from repositories.pricing import PricingRepository
|
||||
|
||||
|
||||
async def seed_base_data(db: AsyncSession) -> None:
|
||||
|
|
@ -95,4 +98,30 @@ async def seed_base_data(db: AsyncSession) -> None:
|
|||
admin_user.signal = None
|
||||
admin_user.nostr_npub = None
|
||||
|
||||
# Seed pricing config
|
||||
constants_path = Path(__file__).parent.parent / "shared" / "constants.json"
|
||||
with constants_path.open() as f:
|
||||
constants = json.load(f)
|
||||
|
||||
exchange_config = constants["exchange"]
|
||||
premium_percentage = exchange_config["premiumPercentage"]
|
||||
eur_trade_min = exchange_config["eurTradeMin"]
|
||||
eur_trade_max = exchange_config["eurTradeMax"]
|
||||
|
||||
# Convert EUR amounts to cents
|
||||
eur_min_cents = eur_trade_min * 100
|
||||
eur_max_cents = eur_trade_max * 100
|
||||
|
||||
repo = PricingRepository(db)
|
||||
await repo.create_or_update(
|
||||
premium_buy=premium_percentage,
|
||||
premium_sell=premium_percentage,
|
||||
small_trade_threshold_eur=0,
|
||||
small_trade_extra_premium=0,
|
||||
eur_min_buy=eur_min_cents,
|
||||
eur_max_buy=eur_max_cents,
|
||||
eur_min_sell=eur_min_cents,
|
||||
eur_max_sell=eur_max_cents,
|
||||
)
|
||||
|
||||
await db.commit()
|
||||
|
|
|
|||
|
|
@ -158,3 +158,103 @@ class TestPricingRepository:
|
|||
result = await db.execute(select(PricingConfig))
|
||||
all_configs = list(result.scalars().all())
|
||||
assert len(all_configs) == 1
|
||||
|
||||
|
||||
class TestPricingSeeding:
|
||||
"""Test pricing configuration seeding."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_seeding_creates_config_with_defaults(self, client_factory):
|
||||
"""Seeding creates config with values from constants.json."""
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
# Load expected values from constants.json
|
||||
constants_path = (
|
||||
Path(__file__).parent.parent.parent / "shared" / "constants.json"
|
||||
)
|
||||
with constants_path.open() as f:
|
||||
constants = json.load(f)
|
||||
|
||||
exchange_config = constants["exchange"]
|
||||
expected_premium = exchange_config["premiumPercentage"]
|
||||
expected_min_eur = exchange_config["eurTradeMin"]
|
||||
expected_max_eur = exchange_config["eurTradeMax"]
|
||||
|
||||
async with client_factory.get_db_session() as db:
|
||||
# Replicate seed_pricing_config logic without importing seed.py
|
||||
repo = PricingRepository(db)
|
||||
config = await repo.create_or_update(
|
||||
premium_buy=expected_premium,
|
||||
premium_sell=expected_premium,
|
||||
small_trade_threshold_eur=0,
|
||||
small_trade_extra_premium=0,
|
||||
eur_min_buy=expected_min_eur * 100,
|
||||
eur_max_buy=expected_max_eur * 100,
|
||||
eur_min_sell=expected_min_eur * 100,
|
||||
eur_max_sell=expected_max_eur * 100,
|
||||
)
|
||||
|
||||
assert config is not None
|
||||
assert config.premium_buy == expected_premium
|
||||
assert config.premium_sell == expected_premium
|
||||
assert config.eur_min_buy == expected_min_eur * 100
|
||||
assert config.eur_max_buy == expected_max_eur * 100
|
||||
assert config.eur_min_sell == expected_min_eur * 100
|
||||
assert config.eur_max_sell == expected_max_eur * 100
|
||||
assert config.small_trade_threshold_eur == 0
|
||||
assert config.small_trade_extra_premium == 0
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_re_running_seed_updates_existing_config(self, client_factory):
|
||||
"""Re-running seed updates existing config instead of creating duplicate."""
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
constants_path = (
|
||||
Path(__file__).parent.parent.parent / "shared" / "constants.json"
|
||||
)
|
||||
with constants_path.open() as f:
|
||||
constants = json.load(f)
|
||||
|
||||
exchange_config = constants["exchange"]
|
||||
expected_premium = exchange_config["premiumPercentage"]
|
||||
expected_min_eur = exchange_config["eurTradeMin"]
|
||||
expected_max_eur = exchange_config["eurTradeMax"]
|
||||
|
||||
async with client_factory.get_db_session() as db:
|
||||
repo = PricingRepository(db)
|
||||
|
||||
# First seeding
|
||||
config1 = await repo.create_or_update(
|
||||
premium_buy=expected_premium,
|
||||
premium_sell=expected_premium,
|
||||
small_trade_threshold_eur=0,
|
||||
small_trade_extra_premium=0,
|
||||
eur_min_buy=expected_min_eur * 100,
|
||||
eur_max_buy=expected_max_eur * 100,
|
||||
eur_min_sell=expected_min_eur * 100,
|
||||
eur_max_sell=expected_max_eur * 100,
|
||||
)
|
||||
original_id = config1.id
|
||||
|
||||
# Modify config manually
|
||||
config1.premium_buy = 99
|
||||
await db.commit()
|
||||
|
||||
# Re-run seed (update existing)
|
||||
config2 = await repo.create_or_update(
|
||||
premium_buy=expected_premium,
|
||||
premium_sell=expected_premium,
|
||||
small_trade_threshold_eur=0,
|
||||
small_trade_extra_premium=0,
|
||||
eur_min_buy=expected_min_eur * 100,
|
||||
eur_max_buy=expected_max_eur * 100,
|
||||
eur_min_sell=expected_min_eur * 100,
|
||||
eur_max_sell=expected_max_eur * 100,
|
||||
)
|
||||
|
||||
# Should be same record with updated values
|
||||
assert config2.id == original_id
|
||||
assert config2.premium_buy == expected_premium # Should be reset
|
||||
assert config2.premium_buy != 99
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue