Coverage for tests/test_account_manager.py: 100%

71 statements  

« prev     ^ index     » next       coverage.py v7.6.8, created at 2024-11-30 23:18 +0000

1import pytest 

2from unittest.mock import patch, MagicMock 

3from decimal import Decimal 

4from classes.account_manager import AccountManager 

5from config.database import Database 

6 

7@pytest.fixture 

8def mock_database_connection(): 

9 # Crea un mock de la conexión a la base de datos 

10 with patch.object(Database, 'get_connection') as mock_connection: 

11 mock_cursor = mock_connection.return_value.cursor.return_value 

12 mock_cursor.execute.return_value = None 

13 mock_connection.return_value.commit.return_value = None 

14 yield mock_connection 

15 

16def test_get_account_balances_success(mock_database_connection): 

17 # Prueba que se obtienen los balances correctamente para un usuario existente 

18 mock_cursor = mock_database_connection.return_value.cursor.return_value 

19 mock_cursor.fetchone.return_value = (Decimal("1000.00"), Decimal("500.00"), Decimal("200.00")) 

20 

21 balances = AccountManager.get_account_balances(1) 

22 assert balances == (Decimal("1000.00"), Decimal("500.00"), Decimal("200.00")) 

23 

24def test_get_account_balances_no_user(mock_database_connection): 

25 # Prueba que se devuelve None si el usuario no existe 

26 mock_cursor = mock_database_connection.return_value.cursor.return_value 

27 mock_cursor.fetchone.return_value = None 

28 

29 balances = AccountManager.get_account_balances(999) # Usuario no existente 

30 assert balances is None 

31 

32def test_update_balances_success(mock_database_connection): 

33 # Prueba que se actualizan los balances correctamente cuando hay suficientes fondos 

34 mock_cursor = mock_database_connection.return_value.cursor.return_value 

35 mock_cursor.fetchone.side_effect = [(Decimal("1000.00"),), (Decimal("500.00"),)] # Balances iniciales 

36 

37 result = AccountManager.update_balances(1, "USD", "EUR", Decimal("100.00"), Decimal("90.00")) 

38 

39 assert result is True 

40 mock_cursor.execute.assert_any_call("UPDATE Accounts SET BalanceUSD = ? WHERE UserId = ?", (Decimal("900.00"), 1)) 

41 mock_cursor.execute.assert_any_call("UPDATE Accounts SET BalanceEUR = ? WHERE UserId = ?", (Decimal("590.00"), 1)) 

42 

43def test_update_balances_insufficient_funds(mock_database_connection): 

44 # Prueba que la actualización falla si los fondos son insuficientes 

45 mock_cursor = mock_database_connection.return_value.cursor.return_value 

46 mock_cursor.fetchone.side_effect = [(Decimal("50.00"),), (Decimal("500.00"),)] # Simular retorno como tupla 

47 

48 result = AccountManager.update_balances(1, "USD", "EUR", Decimal("100.00"), Decimal("90.00")) 

49 

50 assert result is False 

51 mock_cursor.execute.assert_called_once_with("SELECT BalanceUSD FROM Accounts WHERE UserId = ?", (1,)) 

52 

53def test_update_balances_no_account(mock_database_connection): 

54 # Prueba que se devuelve un error si no se encuentra la cuenta del usuario 

55 mock_cursor = mock_database_connection.return_value.cursor.return_value 

56 mock_cursor.fetchone.side_effect = [None] # No se encuentra la cuenta 

57 

58 result = AccountManager.update_balances(1, "USD", "EUR", Decimal("100.00"), Decimal("90.00")) 

59 

60 assert "error" in result # Espera un mensaje de error 

61 assert result["error"] == "No se encontró la cuenta del usuario." 

62 

63def test_update_balances_database_error(mock_database_connection): 

64 # Prueba que se maneja correctamente un error de base de datos 

65 mock_cursor = mock_database_connection.return_value.cursor.return_value 

66 mock_cursor.fetchone.side_effect = Exception("Database error") 

67 

68 result = AccountManager.update_balances(1, "USD", "EUR", Decimal("100.00"), Decimal("90.00")) 

69 

70 assert "error" in result # Verifica que se maneje el error 

71 assert result["error"] == "Database error" 

72 

73def test_update_balances_print_messages(): 

74 with patch('builtins.print') as mock_print: 

75 # Mockear la conexión a la base de datos 

76 with patch('config.database.Database.get_connection') as mock_get_connection: 

77 mock_conn = MagicMock() 

78 mock_cursor = MagicMock() 

79 mock_get_connection.return_value = mock_conn 

80 mock_conn.cursor.return_value = mock_cursor 

81 

82 # Configurar los valores que devolverá el cursor 

83 mock_cursor.fetchone.side_effect = [ 

84 (Decimal('1000.00'),), # Balance de origen 

85 (Decimal('500.00'),) # Balance de destino 

86 ] 

87 

88 # Llamar al método bajo prueba 

89 result = AccountManager.update_balances( 

90 user_id=1, 

91 divisa_origen='USD', 

92 divisa_destino='EUR', 

93 monto=Decimal('100.00'), 

94 monto_convertido=Decimal('90.00') 

95 ) 

96 

97 # Definir los mensajes esperados 

98 expected_messages = [ 

99 "Iniciando actualización de balances para UserId: 1", 

100 "Divisa origen: USD, Divisa destino: EUR, Monto: 100.00, Monto convertido: 90.00", 

101 "Conexión a la base de datos establecida correctamente.", 

102 "Obteniendo balance de USD...", 

103 "Resultado de balance de USD: (Decimal('1000.00'),)", 

104 "Balance de origen convertido a Decimal: 1000.00", 

105 "Nuevo balance de USD: 900.00", 

106 "Balance de USD actualizado en la base de datos.", 

107 "Obteniendo balance de EUR...", 

108 "Resultado de balance de EUR: (Decimal('500.00'),)", 

109 "Balance de destino convertido a Decimal: 500.00", 

110 "Nuevo balance de EUR: 590.00", 

111 "Balance de EUR actualizado en la base de datos.", 

112 "Transacción confirmada (commit).", 

113 "Cerrando recursos...", 

114 "Cursor cerrado.", 

115 "Conexión cerrada." 

116 ] 

117 

118 # Obtener los mensajes realmente impresos 

119 actual_calls = mock_print.call_args_list 

120 actual_messages = [call.args[0] for call in actual_calls] 

121 

122 # Verificar que cada mensaje esperado esté en los mensajes impresos 

123 for expected_message in expected_messages: 

124 assert expected_message in actual_messages 

125 

126 # Verificar que el método devuelve True 

127 assert result is True 

128 

129def test_get_account_balances_handles_none_cursor_conn(): 

130 with patch('config.database.Database.get_connection') as mock_get_connection: 

131 mock_conn = MagicMock() 

132 mock_get_connection.return_value = mock_conn 

133 mock_conn.cursor.return_value = None 

134 

135 result = AccountManager.get_account_balances(1) 

136 assert result is None 

137 

138 mock_conn.cursor.assert_called_once() 

139 mock_conn.close.assert_called_once() 

140 

141#### 

142