import sys import os import unittest from unittest.mock import MagicMock, patch # Вставляем путь к проекту в sys.path sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) # 1. Глобальный мок для psycopg2, пула соединений и функции get_conn, # чтобы избежать реального подключения к БД во время импорта и выполнения тестов. import psycopg2 psycopg2.connect = MagicMock() import psycopg2.pool psycopg2.pool.ThreadedConnectionPool = MagicMock() import db # Мокаем get_conn как контекстный менеджер mock_conn = MagicMock() mock_cur = MagicMock() mock_conn.cursor.return_value = mock_cur # Для RealDictCursor mock_cur_dict = MagicMock() mock_conn.cursor.return_value = mock_cur_dict mock_get_conn = MagicMock() mock_get_conn.return_value.__enter__.return_value = mock_conn db.get_conn = mock_get_conn # 2. Импортируем тестируемые модули после настройки моков from games.betting import place_bet from games.casino import play_casino from games.economy import economy class TestPrecision(unittest.TestCase): @patch('games.betting.get_user_length') @patch('games.betting.update_user_length') def test_place_bet_exact_balance(self, mock_update_user_length, mock_get_user_length): # Баланс 0.199999988 (32-bit float представление 0.2) mock_get_user_length.return_value = 0.199999988 mock_update_user_length.return_value = 0.0 match = { "id": "match_123", "home": "Team A", "away": "Team B", "odds": {"Team A": 2.0, "Team B": 1.8} } # Ставка ровно 0.2 должна быть успешной благодаря округлению round(amount, 2) <= round(current, 2) success, message = place_bet(12345, match, "dota2", "Team A", 0.2) self.assertTrue(success) self.assertIn("Ставка принята!", message) # Ставка 0.21 при балансе 0.199999988 должна быть отклонена success_fail, message_fail = place_bet(12345, match, "dota2", "Team A", 0.21) self.assertFalse(success_fail) self.assertIn("Не хватает, фраер", message_fail) @patch('games.casino.economy.get_user_balance') @patch('games.casino.spin_slots') @patch('games.casino.economy.update_balance') def test_casino_exact_balance(self, mock_update, mock_spin, mock_get_user_balance): # Баланс 0.199999988 mock_get_user_balance.return_value = 0.199999988 mock_spin.return_value = (["🍒", "🍒", "🍇"], 2) mock_update.return_value = 0.0 # Ставка ровно 0.2 в казино должна быть успешной result = play_casino(12345, 0.2) self.assertNotIn("Столько нет, фраер", result) # Ставка 0.21 при балансе 0.199999988 должна быть отклонена result_fail = play_casino(12345, 0.21) self.assertIn("Столько нет, фраер", result_fail) @patch('games.economy.economy.get_user_balance') @patch('games.economy.economy.get_setting') def test_economy_deposit_exact_balance(self, mock_get_setting, mock_get_user_balance): # Баланс 9.999999 (32-bit float представление 10.0), минимальный вклад 10.0 mock_get_user_balance.return_value = 9.999999 mock_get_setting.side_effect = lambda key: "10.0" if key == "deposit_min_amount" else "7.5" # Вклад на 10.0 при балансе 9.999999 (эквивалентен 10.0) должен пройти успешно благодаря округлению success, msg = economy.create_deposit(12345, 10.0, 30) self.assertTrue(success) self.assertEqual(msg, "Вклад успешно открыт!") # Вклад на 10.01 должен быть отклонен из-за нехватки баланса success_fail, msg_fail = economy.create_deposit(12345, 10.01, 30) self.assertFalse(success_fail) self.assertIn("Недостаточно средств", msg_fail) # Вклад на 9.99 должен быть отклонен из-за минимальной суммы success_fail2, msg_fail2 = economy.create_deposit(12345, 9.99, 30) self.assertFalse(success_fail2) self.assertIn("Минимальная сумма вклада", msg_fail2) @patch('games.economy.economy.get_user_balance') def test_economy_transfer_exact_balance(self, mock_get_user_balance): # При балансе 9.999999 (эквивалентен 10.0) лимит перевода (20%) составляет ровно 2.0. mock_get_user_balance.return_value = 9.999999 # Перевод ровно 2.0 должен пройти успешно success = economy.transfer_money(12345, 67890, 2.0, "Test transfer") self.assertTrue(success) # Перевод 2.01 должен превысить 20% лимит (2.0) и отклониться success_fail = economy.transfer_money(12345, 67890, 2.01, "Test transfer") self.assertFalse(success_fail) if __name__ == '__main__': unittest.main()