- Introduced a new `spin_sessions` table to track user spin activities. - Updated the API to include a new endpoint for spinning games, allowing users to place bets and specify spin counts. - Enhanced game information structure and added validation for bets and spin counts. - Implemented the `Forest Fortune` slot game mechanics, including payline evaluation and scatter functionality. - Updated dependencies in `pyproject.toml` for development and added `httpx` for HTTP requests. - Added unit tests for the new slot mechanics and API endpoints to ensure functionality and reliability.
112 lines
3.8 KiB
Python
112 lines
3.8 KiB
Python
"""API tests for spin endpoint and wallet debit/credit."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import unittest
|
|
from decimal import Decimal
|
|
|
|
from fastapi.testclient import TestClient
|
|
from sqlalchemy import create_engine
|
|
from sqlalchemy.orm import sessionmaker
|
|
from sqlalchemy.pool import StaticPool
|
|
|
|
from app.core.database import Base, get_db
|
|
from app.main import create_app
|
|
|
|
|
|
class SpinApiTests(unittest.TestCase):
|
|
def setUp(self) -> None:
|
|
engine = create_engine(
|
|
"sqlite://",
|
|
connect_args={"check_same_thread": False},
|
|
poolclass=StaticPool,
|
|
)
|
|
TestingSession = sessionmaker(bind=engine, autocommit=False, autoflush=False)
|
|
Base.metadata.create_all(bind=engine)
|
|
|
|
def override_get_db():
|
|
db = TestingSession()
|
|
try:
|
|
yield db
|
|
finally:
|
|
db.close()
|
|
|
|
self.app = create_app()
|
|
self.app.dependency_overrides[get_db] = override_get_db
|
|
self.client = TestClient(self.app)
|
|
self.TestingSession = TestingSession
|
|
|
|
login = self.client.post(
|
|
"/auth/dev-login",
|
|
json={"telegram_id": 424242, "username": "tester", "first_name": "Test"},
|
|
)
|
|
self.assertEqual(login.status_code, 200)
|
|
token = login.json()["access_token"]
|
|
self.headers = {"Authorization": f"Bearer {token}"}
|
|
|
|
agree = self.client.post("/me/agreement", headers=self.headers)
|
|
self.assertEqual(agree.status_code, 200)
|
|
|
|
deposit = self.client.post("/wallet/deposit", headers=self.headers, json={"amount": 1000})
|
|
self.assertEqual(deposit.status_code, 200)
|
|
self.assertEqual(Decimal(deposit.json()["balance"]), Decimal("1000.00"))
|
|
|
|
def test_list_games_includes_forest(self) -> None:
|
|
res = self.client.get("/games")
|
|
self.assertEqual(res.status_code, 200)
|
|
slugs = {g["slug"]: g for g in res.json()}
|
|
self.assertIn("forest-fortune", slugs)
|
|
self.assertEqual(slugs["forest-fortune"]["status"], "available")
|
|
self.assertEqual(slugs["forest-fortune"]["max_spin_count"], 1000)
|
|
|
|
def test_spin_debit_and_credit(self) -> None:
|
|
res = self.client.post(
|
|
"/games/forest-fortune/spin",
|
|
headers=self.headers,
|
|
json={"bet": 10, "spin_count": 3},
|
|
)
|
|
self.assertEqual(res.status_code, 200, res.text)
|
|
body = res.json()
|
|
self.assertEqual(body["spin_count"], 3)
|
|
self.assertEqual(Decimal(body["total_bet"]), Decimal("30.00"))
|
|
self.assertEqual(len(body["spins"]), 3)
|
|
expected = Decimal("1000.00") - Decimal(body["total_bet"]) + Decimal(body["total_win"])
|
|
self.assertEqual(Decimal(body["balance"]), expected)
|
|
|
|
def test_reject_spin_count_over_limit(self) -> None:
|
|
res = self.client.post(
|
|
"/games/forest-fortune/spin",
|
|
headers=self.headers,
|
|
json={"bet": 1, "spin_count": 1001},
|
|
)
|
|
self.assertEqual(res.status_code, 422)
|
|
|
|
def test_reject_spin_count_zero_via_validation(self) -> None:
|
|
res = self.client.post(
|
|
"/games/forest-fortune/spin",
|
|
headers=self.headers,
|
|
json={"bet": 1, "spin_count": 0},
|
|
)
|
|
self.assertEqual(res.status_code, 422)
|
|
|
|
def test_insufficient_balance(self) -> None:
|
|
res = self.client.post(
|
|
"/games/forest-fortune/spin",
|
|
headers=self.headers,
|
|
json={"bet": 500, "spin_count": 10},
|
|
)
|
|
self.assertEqual(res.status_code, 400)
|
|
self.assertIn("Insufficient", res.json()["detail"])
|
|
|
|
def test_coming_soon_unavailable(self) -> None:
|
|
res = self.client.post(
|
|
"/games/raven-reels/spin",
|
|
headers=self.headers,
|
|
json={"bet": 1, "spin_count": 1},
|
|
)
|
|
self.assertEqual(res.status_code, 503)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|