Skip to content

Commit 77fddd5

Browse files
committed
Refactor: Actualizar tests de chat y añadir tests de dashboard
Este commit introduce varias refactorizaciones y adiciones en las aplicaciones de chat, dashboard y viajes. **Aplicación Chat:** * Refactorizados los tests en `accounts/tests/test_views.py`, `chat/tests/test_consumers.py`, `chat/tests/test_models.py`, `chat/tests/test_utils.py`, `chat/tests/test_views.py` y `rides/tests/test_integration.py`. * Actualizada la lógica de los tests para reflejar el cambio donde los objetos `Message` ahora se asocian directamente con un objeto `Chat` en lugar de un `Ride`. Los tests ahora obtienen y usan correctamente el objeto `chat` vinculado a un `ride` para la creación de mensajes y las comprobaciones de acceso. * Corregido `KeyError: 'chat_id'` en tests de consumers usando `chat.id`. * Corregido `IntegrityError` en tests de modelos asegurando la existencia del `Chat`. * Corregido `SynchronousOnlyOperation` en tests de consumers usando `database_sync_to_async`. * Corregido `AssertionError` en la conexión del pasajero asegurando que esté en los participantes del chat. * Corregido `KeyError: 'content'` en tests de consumers accediendo a la estructura anidada del mensaje. * Ajustadas las rutas de los mocks en `accounts/tests/test_views.py` para coincidir con la ubicación refactorizada de `create_stripe_onboarding_link`. **Aplicación Dashboard:** * Añadida una suite de tests completa para la aplicación `dashboard` en `dashboard/tests/`. * Creado `__init__.py`. * Añadido `test_constants.py`. * Añadido `test_utils.py` con `DashboardUtilsTests` para probar funciones de utilidad y serialización de datos. * Añadido `test_views.py` con `DashboardViewsTests` para probar vistas, control de acceso, uso de plantillas, datos de contexto y endpoints JSON API. * Refactorizado `dashboard/urls.py`: * Renombrados varios patrones de URL de API por consistencia (ej., `api_trips` a `get_trip_data_json`). * Añadidos patrones de URL que faltaban y eran requeridos por las vistas: `dashboard_data_api`, `get_chat_messages`, `report_detail` y `mark_report`. * Añadida la implementación de la función de vista `mark_report` que faltaba en `dashboard/views.py`, que maneja el marcado de reportes como leídos/no leídos. **Aplicación Rides:** * Ajuste menor de formato en la vista `book_ride` (`rides/views.py`). Estos cambios mejoran la robustez de la funcionalidad de chat alineando los tests con el modelo de datos actual, aumentan significativamente la cobertura de tests para la funcionalidad del dashboard y aseguran que las URLs y vistas del dashboard sean consistentes y completas.
1 parent 9a1197f commit 77fddd5

14 files changed

Lines changed: 769 additions & 57 deletions

File tree

codigo/accounts/tests/test_views.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# ==========================================
22
# Autor: Alejandro Gasca Mediel
33
# ==========================================
4+
45
from django.test import TestCase, Client
56
from django.contrib.auth.models import User
67
from django.urls import reverse
@@ -286,21 +287,21 @@ def test_onboarding_redirects_if_no_account(self):
286287
messages = list(get_messages(response.wsgi_request))
287288
self.assertTrue(any("configurar tu cuenta de pagos" in str(m) for m in messages))
288289

289-
@patch('accounts._utils.create_stripe_onboarding_link')
290+
@patch('accounts.views.create_stripe_onboarding_link')
290291
def test_onboarding_redirects_to_stripe(self, mock_link):
291292
"""
292293
Prueba que la vista de onboarding redirige a Stripe con el enlace generado.
293294
"""
294-
# Configurar el mock para que devuelva una URL específica
295+
295296
mock_url = 'https://onboarding.stripe.test/account/123'
296297
mock_link.return_value = mock_url
297298

299+
self.user.profile.stripe_account_id = 'acct_test_123'
300+
self.user.profile.save()
298301
response = self.client.get(reverse('accounts:complete_stripe_onboarding'))
299302

300-
# Verificar que la función mock fue llamada con el usuario correcto
301303
mock_link.assert_called_once_with(self.user)
302304

303-
# Verificar la redirección a la URL de Stripe
304305
self.assertEqual(response.status_code, 302)
305306
self.assertEqual(response.url, mock_url)
306307

codigo/chat/_utils.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# ==========================================
22
# Autor: Alejandro Gasca Mediel
33
# ==========================================
4+
5+
46
"""
57
Utilidades para la aplicación de chat.
68
"""
@@ -34,9 +36,9 @@ def get_messages_for_chat(chat):
3436
messages_data = []
3537

3638
for message in messages:
37-
# Format date as day/month/year
39+
3840
date_str = message.created_at.strftime('%d/%m/%Y')
39-
# Format time as hour:minute
41+
4042
time_str = message.created_at.strftime('%H:%M')
4143

4244
messages_data.append({
@@ -112,9 +114,9 @@ def synchronize_chat_participants(ride):
112114
if not hasattr(ride, 'chat') or not ride.chat:
113115
return
114116

115-
# Añadir el conductor
117+
116118
ride.chat.participants.add(ride.driver)
117119

118-
# Añadir todos los pasajeros
120+
119121
for passenger in ride.passengers.all():
120122
ride.chat.participants.add(passenger)

codigo/chat/tests/test_consumers.py

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,58 +18,65 @@
1818
import pytest
1919

2020
class ChatConsumerTests(TestCase):
21+
@database_sync_to_async
22+
def get_ride_and_chat(self, ride_id):
23+
from rides.models import Ride
24+
ride = Ride.objects.get(id=ride_id)
25+
chat = ride.chat
26+
return ride, chat
27+
2128
async def test_chat_consumer_connection(self):
2229
"""Prueba la conexión del consumidor de chat"""
2330
driver = await self.create_user(DRIVER_USERNAME, DRIVER_PASSWORD)
2431
passenger = await self.create_user(PASSENGER_USERNAME, PASSENGER_PASSWORD)
2532
ride = await self.create_ride(driver, passenger)
26-
33+
ride, chat = await self.get_ride_and_chat(ride.id)
2734
communicator = WebsocketCommunicator(
2835
ChatConsumer.as_asgi(),
29-
WS_CHAT_PATH.format(ride.id)
36+
WS_CHAT_PATH.format(chat.id)
3037
)
3138
communicator.scope["user"] = driver
32-
communicator.scope["url_route"] = {"kwargs": {"ride_id": str(ride.id)}}
33-
39+
communicator.scope["url_route"] = {"kwargs": {"chat_id": str(chat.id)}}
3440
connected, _ = await communicator.connect()
3541
self.assertTrue(connected)
36-
3742
await communicator.disconnect()
38-
43+
44+
@database_sync_to_async
45+
def ensure_passenger_in_chat(self, ride, passenger):
46+
chat = ride.chat
47+
chat.participants.add(passenger)
48+
chat.save()
49+
3950
async def test_chat_consumer_receive_message(self):
4051
"""Prueba el envío y recepción de mensajes en el consumidor"""
4152
driver = await self.create_user(DRIVER_USERNAME, DRIVER_PASSWORD)
4253
passenger = await self.create_user(PASSENGER_USERNAME, PASSENGER_PASSWORD)
4354
ride = await self.create_ride(driver, passenger)
44-
55+
ride, chat = await self.get_ride_and_chat(ride.id)
4556
driver_comm = WebsocketCommunicator(
4657
ChatConsumer.as_asgi(),
47-
WS_CHAT_PATH.format(ride.id)
58+
WS_CHAT_PATH.format(chat.id)
4859
)
4960
driver_comm.scope["user"] = driver
50-
driver_comm.scope["url_route"] = {"kwargs": {"ride_id": str(ride.id)}}
51-
61+
driver_comm.scope["url_route"] = {"kwargs": {"chat_id": str(chat.id)}}
5262
passenger_comm = WebsocketCommunicator(
5363
ChatConsumer.as_asgi(),
54-
WS_CHAT_PATH.format(ride.id)
64+
WS_CHAT_PATH.format(chat.id)
5565
)
5666
passenger_comm.scope["user"] = passenger
57-
passenger_comm.scope["url_route"] = {"kwargs": {"ride_id": str(ride.id)}}
58-
67+
passenger_comm.scope["url_route"] = {"kwargs": {"chat_id": str(chat.id)}}
68+
await self.ensure_passenger_in_chat(ride, passenger)
5969
await driver_comm.connect()
6070
await passenger_comm.connect()
61-
6271
await driver_comm.send_json_to({
6372
'message': DRIVER_MESSAGE
6473
})
65-
6674
response = await passenger_comm.receive_json_from()
67-
self.assertEqual(response['content'], DRIVER_MESSAGE)
68-
self.assertEqual(response['sender'], DRIVER_USERNAME)
69-
75+
self.assertEqual(response['message']['content'], DRIVER_MESSAGE)
76+
self.assertEqual(response['message']['sender'], DRIVER_USERNAME)
7077
await driver_comm.disconnect()
7178
await passenger_comm.disconnect()
72-
79+
7380
@database_sync_to_async
7481
def create_user(self, username, password):
7582
"""Utilidad para crear usuarios de forma asíncrona"""
@@ -78,7 +85,7 @@ def create_user(self, username, password):
7885
email=f'{username}@example.com',
7986
password=password
8087
)
81-
88+
8289
@database_sync_to_async
8390
def create_ride(self, driver, passenger):
8491
"""Utilidad para crear viajes de forma asíncrona"""

codigo/chat/tests/test_models.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,32 +35,38 @@ def setUp(self):
3535
total_seats=RIDE_TOTAL_SEATS,
3636
price=RIDE_PRICE
3737
)
38-
38+
self.ride.refresh_from_db()
39+
if not hasattr(self.ride, 'chat') or self.ride.chat is None:
40+
from chat.models import Chat
41+
chat = Chat.objects.create()
42+
self.ride.chat = chat
43+
self.ride.save()
44+
self.ride.refresh_from_db()
3945
self.ride.passengers.add(self.passenger)
4046

4147
def test_message_creation(self):
4248
"""Prueba la creación de mensajes"""
49+
chat = self.ride.chat
4350
message = Message.objects.create(
44-
ride=self.ride,
51+
chat=chat,
4552
sender=self.driver,
4653
content=DRIVER_MESSAGE,
4754
is_read=False
4855
)
49-
50-
self.assertEqual(message.ride, self.ride)
56+
self.assertEqual(message.chat, chat)
5157
self.assertEqual(message.sender, self.driver)
5258
self.assertEqual(message.content, DRIVER_MESSAGE)
5359
self.assertFalse(message.is_read)
5460
self.assertIsNotNone(message.created_at)
5561

5662
def test_message_string_representation(self):
5763
"""Prueba la representación en cadena del mensaje"""
64+
chat = self.ride.chat
5865
message = Message.objects.create(
59-
ride=self.ride,
66+
chat=chat,
6067
sender=self.driver,
6168
content=DRIVER_MESSAGE,
6269
is_read=False
6370
)
64-
6571
expected = DRIVER_MESSAGE
6672
self.assertEqual(str(message), expected)

codigo/chat/tests/test_utils.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from chat.models import Message
1111
from rides.models import Ride
1212
from chat.public import user_has_chat_access, get_user_chats
13-
from chat._utils import format_message_for_api, get_messages_for_ride, can_send_message
13+
from chat._utils import format_message_for_api, can_send_message
1414
from .test_constants import *
1515

1616
class ChatUtilsTests(TestCase):
@@ -45,28 +45,28 @@ def setUp(self):
4545
)
4646

4747
self.ride.passengers.add(self.passenger)
48-
48+
self.ride.refresh_from_db()
49+
chat = self.ride.chat
50+
chat.participants.add(self.passenger) # Asegura que el pasajero está en el chat
4951
Message.objects.create(
50-
ride=self.ride,
52+
chat=chat,
5153
sender=self.driver,
5254
content=DRIVER_MESSAGE,
5355
is_read=True
5456
)
55-
5657
Message.objects.create(
57-
ride=self.ride,
58+
chat=chat,
5859
sender=self.passenger,
5960
content=PASSENGER_MESSAGE,
6061
is_read=False
6162
)
63+
self.chat = chat
6264

6365
def test_user_has_chat_access(self):
6466
"""Prueba que verifica quién tiene acceso al chat"""
65-
self.assertTrue(user_has_chat_access(self.driver, self.ride))
66-
67-
self.assertTrue(user_has_chat_access(self.passenger, self.ride))
68-
69-
self.assertFalse(user_has_chat_access(self.other_user, self.ride))
67+
self.assertTrue(user_has_chat_access(self.driver, self.chat))
68+
self.assertTrue(user_has_chat_access(self.passenger, self.chat))
69+
self.assertFalse(user_has_chat_access(self.other_user, self.chat))
7070

7171
def test_get_user_chats_for_driver(self):
7272
"""Prueba obtener los chats del conductor"""

codigo/chat/tests/test_views.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,17 @@ def setUp(self):
4747
)
4848

4949
self.ride.passengers.add(self.passenger)
50-
50+
self.ride.refresh_from_db()
51+
chat = self.ride.chat
5152
Message.objects.create(
52-
ride=self.ride,
53+
chat=chat,
5354
sender=self.driver,
5455
content=DRIVER_MESSAGE,
5556
is_read=True
5657
)
5758

5859
Message.objects.create(
59-
ride=self.ride,
60+
chat=chat,
6061
sender=self.passenger,
6162
content=PASSENGER_MESSAGE,
6263
is_read=False

codigo/dashboard/tests/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
"""
2+
Tests para el módulo de dashboard.
3+
"""
4+
from dashboard.tests.test_constants import *
5+
from dashboard.tests.test_utils import DashboardUtilsTests
6+
from dashboard.tests.test_views import DashboardViewsTests
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# ==========================================
2+
# Autor: Alejandro Gasca Mediel
3+
# ==========================================
4+
"""
5+
Constantes para las pruebas del dashboard.
6+
"""
7+
from django.utils import timezone
8+
from datetime import timedelta
9+
10+
# Usuarios
11+
ADMIN_USERNAME = 'admin_test'
12+
ADMIN_EMAIL = 'admin@test.com'
13+
ADMIN_PASSWORD = 'admin12345'
14+
15+
REGULAR_USERNAME = 'user_test'
16+
REGULAR_EMAIL = 'user@test.com'
17+
REGULAR_PASSWORD = 'user12345'
18+
19+
# Periodos
20+
TEST_PERIOD_TODAY = 'today'
21+
TEST_PERIOD_WEEK = 'week'
22+
TEST_PERIOD_MONTH = 'month'
23+
TEST_PERIOD_YEAR = 'year'
24+
TEST_PERIOD_ALL = 'all'
25+
26+
# URLs y templates
27+
URL_DASHBOARD = 'dashboard:dashboard'
28+
URL_RIDE_MANAGEMENT = 'dashboard:ride_management'
29+
URL_USER_MANAGEMENT = 'dashboard:user_management'
30+
URL_CHAT_MANAGEMENT = 'dashboard:chat_management'
31+
URL_TRIP_STATS = 'dashboard:trip_stats'
32+
URL_MSG_STATS = 'dashboard:msg_stats' # Corregido
33+
URL_REPORT_STATS = 'dashboard:report_stats'
34+
URL_USER_STATS = 'dashboard:user_stats'
35+
36+
37+
# URLs para APIs
38+
URL_API_TRIPS = 'dashboard:api_trips'
39+
URL_API_MESSAGES = 'dashboard:api_messages'
40+
URL_API_REPORTS = 'dashboard:api_reports'
41+
URL_API_USERS = 'dashboard:api_users'
42+
URL_API_PAYMENTS = 'dashboard:api_payments'
43+
URL_GET_CHAT_MESSAGES = 'dashboard:get_chat_messages'
44+
45+
TEMPLATE_DASHBOARD = 'dashboard/dashboard.html'
46+
TEMPLATE_RIDE_MANAGEMENT = 'dashboard/ride_management.html'
47+
TEMPLATE_USER_MANAGEMENT = 'dashboard/user_management.html'
48+
TEMPLATE_CHAT_MANAGEMENT = 'dashboard/chat_management.html'
49+
TEMPLATE_TRIP_STATS = 'dashboard/trip_stats.html'
50+
TEMPLATE_MSG_STATS = 'dashboard/msg_stats.html'
51+
TEMPLATE_REPORT_STATS = 'dashboard/report_stats.html'
52+
TEMPLATE_USER_STATS = 'dashboard/user_stats.html'
53+
TEMPLATE_REPORT_DETAIL = 'dashboard/report_detail.html'
54+
55+
# Fechas
56+
DAYS_FUTURE = 5
57+
DAYS_PAST = 5
58+
59+
# Datos de prueba
60+
TEST_ORIGIN = 'Madrid'
61+
TEST_DESTINATION = 'Barcelona'
62+
TEST_SEATS = 3
63+
TEST_PRICE = 25.0

0 commit comments

Comments
 (0)