Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add chat to game-event page #96

Merged
merged 1 commit into from
Jun 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 127 additions & 57 deletions game_event/templates/game_event/game-event.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,70 +4,140 @@
<!DOCTYPE html>
<html>
<head>
<link href="/static/css/chat.css" rel="stylesheet" />

<title>Game Event</title>
<link rel="stylesheet" type="text/css" href="{% static 'css/game-event.css' %}">
<script>
setTimeout(function() {
location.reload();
}, 5000);
</script>

</head>
<body>
{% if time %}
<h1>Event Details</h1>
<p>Time: {{ time }}</p>
<p>Level: {{ level_of_game }}</p>
<p>Min Players: {{ min_number_of_players }}</p>
<p>Max Players: {{ max_number_of_players }}</p>
<p>Court: {{ court }} {{ neighborhood }}</p>
<p>Game: {{ ball_game }}</p>
<h2>Players:</h2>
<table class="nice-table">
<thead>
<tr>
<th> </th>
<th>Name</th>
<th>Brings Ball</th>
</tr>
</thead>
<tbody>
{% for player in event_players %}
<tr>
<td>
<img src="{% static 'images/favicon.ico' %}" alt="Ball Image" class="ball-image">
</td>
<td>{{ player.first_name }} {{ player.last_name }}</td>
<td>
{% if player.brings_ball == True %}
Yes
{% if time %}
<h1>Event Details</h1>
<p>Time: {{ time }}</p>
<p>Level: {{ level_of_game }}</p>
<p>Min Players: {{ min_number_of_players }}</p>
<p>Max Players: {{ max_number_of_players }}</p>
<p>Court: {{ court }} {{ neighborhood }}</p>
<p>Game: {{ ball_game }}</p>
<h2>Players:</h2>
<table class="nice-table">
<thead>
<tr>
<th> </th>
<th>Name</th>
<th>Brings Ball</th>
</tr>
</thead>
<tbody>
{% for player in event_players %}
<tr>
<td>
<img src="{% static 'images/favicon.ico' %}" alt="Ball Image" class="ball-image">
</td>
<td>{{ player.first_name }} {{ player.last_name }}</td>
<td>
{% if player.brings_ball == True %}
Yes
{% else %}
No
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div>
{% if in_event %}
<a href="/game-events/remove-from-event/{{ id }}/"
class="round-button"
onclick="window.open(this.href, 'Remove Event', 'width=400,height=250,left='+((screen.width-400)/2)+',top='+((screen.height-515)/2)); return false;">
Remove Event
</a>
<div class="top-right">
<h1>Chat With Players!</h1>
<body>

{% if all_messages %}
<div id="savedText">
<div class="message-box">
{% for message in all_messages %}

{% if message.user_id.user.username == request.user.username %}
<div class="message-container">
<span class="message-time">{{ message.time_sent|date:"F d, H:i" }}</span>
<span class="name">{{ message.user_id.user.username }}</span><br>
<p><span class="message">{{ message.text }}</span></p>
</div>

{% else %}
<div class="message-other-user-container">
<span class="message-other-time">{{ message.time_sent|date:"F d, H:i" }}</span>
<span class="name-other">{{ message.user_id.user.username }}</span><br>
<p><span class="message-other">{{ message.text }}</span></p>
</div>
{% endif %}
{% endfor %}


</div>
</div>

{% else %}
No
<div id="savedText" style="display: none;">
<textarea id="savedTextbox" rows="12" cols="50" readonly></textarea>
</div>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>

<div class="input">
<form method="POST" action="{% url 'save_text_message' id=id %}">
{% csrf_token %}
<input type="text" id="mytextbox" name="mytextbox" placeholder="Type your message here!">
<button onclick="saveText(); showSaveBox();">Send</button>
</div>
</form>
<script>
function saveText() {
var textbox = document.getElementById('mytextbox');
var savedTextbox = document.getElementById('savedTextbox');

}
function showSaveBox() {
var savedTextDiv = document.getElementById('savedText');
savedTextDiv.style.display = 'block';
}

</script>
{% if messages %}
<div class="row my-4">
<div class="col">
<div class="alert alert-danger" role="alert">
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
</div>
</div>
</div>
{% endif %}

</body>


</div>
{% else %}
<a href="/game-events/join-event/{{ id }}/"
class="round-button"
onclick="window.open(this.href, 'Join Event', 'width=400,height=250,left='+((screen.width-400)/2)+',top='+((screen.height-515)/2)); return false;">
Join Event
</a>
{% endif %}
</div>
{% else %}
<div>
{% if in_event %}
<a href="/game-events/remove-from-event/{{ id }}/"
class="round-button"
onclick="window.open(this.href, 'Remove Event', 'width=400,height=250,left='+((screen.width-400)/2)+',top='+((screen.height-515)/2)); return false;">
Remove Event
</a>
{% else %}
<a href="/game-events/join-event/{{ id }}/"
class="round-button"
onclick="window.open(this.href, 'Join Event', 'width=400,height=250,left='+((screen.width-400)/2)+',top='+((screen.height-515)/2)); return false;">
Join Event
</a>
{% endif %}
<h1> Event Does not exist. </h1>
</div>
{% else %}
<div>
<h1> Event Does not exist. </h1>
</div>
{% endif %}
</body>
{% endif %}
</body>
</html>
{%endblock%}
4 changes: 3 additions & 1 deletion game_event/urls.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.urls import path
from . import views
from message.views import save_text_message


urlpatterns = [
Expand All @@ -9,4 +10,5 @@
path('<id>/', views.game_event, name='game_event'),
path('join-event/<id>/', views.join_event, name='join_event'),
path('process-answer-game-event/<id>/', views.process_answer_game_event, name='process_answer_game_event'),
path('remove-from-event/<id>/', views.remove_from_event, name='remove_from_event')]
path('remove-from-event/<id>/', views.remove_from_event, name='remove_from_event'),
path('save-text-message/<id>/', save_text_message, name='save_text_message')]
5 changes: 4 additions & 1 deletion game_event/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from django.utils import timezone
from django.core.exceptions import ValidationError
from django.contrib import messages
from message.models import Message
from datetime import date


Expand Down Expand Up @@ -96,6 +97,7 @@ def game_event(request, id):
for entry in GameEventPlayer.objects.filter(game_event=event)
]
in_event = GameEventPlayer.objects.filter(game_event=event, player=player).exists()
all_messages = Message.objects.filter(game_event_id=event)
context = {
'id': event.id,
'time': event.time,
Expand All @@ -106,7 +108,8 @@ def game_event(request, id):
'neighborhood': event.court.neighborhood,
'ball_game': event.ball_game,
'in_event': in_event,
'event_players': event_players
'event_players': event_players,
'all_messages': all_messages
}
return render(request, 'game_event/game-event.html', context)

Expand Down
25 changes: 25 additions & 0 deletions message/models.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,36 @@
from django.db import models
from player.models import Player
from game_event.models import GameEvent
from game_event_player.models import GameEventPlayer
from django.core.validators import MinLengthValidator
from django.core.exceptions import ValidationError


class Message(models.Model):
user_id = models.ForeignKey(Player, on_delete=models.CASCADE)
game_event_id = models.ForeignKey(GameEvent, on_delete=models.CASCADE)
time_sent = models.DateTimeField(auto_now_add=True)
text = models.CharField(max_length=255, validators=[MinLengthValidator(1)])

@staticmethod
def create(player, game_event, text):
Message.validate_message(player, game_event, text)
message = Message(user_id=player,
game_event_id=game_event,
text=text)

message.save()
return message

@staticmethod
def validate_message(player, game_event, text):
game_event = GameEvent.objects.get(pk=game_event.pk)
player_participates = GameEventPlayer.objects.filter(player=player, game_event=game_event).exists()
errors = []
if player_participates is False:
errors.append("Just players from this event can send messages on chat")
if text.strip() == '':
errors.append("Message can't be empty")

if errors:
raise ValidationError("\n".join(errors))
92 changes: 92 additions & 0 deletions message/tests.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
from player.models import Player
from game_event.models import GameEvent
from game_event_player.models import GameEventPlayer
from message.models import Message
from django.core.exceptions import ValidationError
from django.utils import timezone
from django.urls import reverse
import pytest


TEST_ID = 2
TEST_TIME = timezone.now()
TEST_LEVEL = 3
Expand Down Expand Up @@ -81,3 +84,92 @@ def test_create_message_with_empty_text(self, player, game_event):
time_sent=TEST_TIME,
text=""
).full_clean()


@pytest.mark.django_db
class TestMessageViews:

def test_success_send_message(self, client, game_event, player):
client.force_login(player.user)
game_event_id = game_event.id
url = reverse('process_answer_game_event', args=[game_event_id])
client.post(url, {'answer': 'yes'})
count_before = Message.objects.count()
url = reverse('save_text_message', args=[game_event_id])
response = client.post(url, {'mytextbox': 'Test message'})

assert response.status_code == 302
assert Message.objects.count() == count_before + 1
message = Message.objects.last()
assert message.user_id == player
assert message.game_event_id == game_event
assert message.text == 'Test message'

def test_messages_persist_after_join_and_remove(self, client, game_event, player):
client.force_login(player.user)
game_event_id = game_event.id
url = reverse('process_answer_game_event', args=[game_event_id])
response = client.post(url, {'answer': 'yes'})
assert response.status_code == 200
url = reverse('save_text_message', args=[game_event_id])
client.post(url, {'mytextbox': 'hi from user'})
reverse('remove_from_event', args=[game_event_id])
player_messages = [entry.text for entry in Message.objects.filter(game_event_id=game_event)]
assert 'hi from user' in player_messages

def test_success_create_message_function(self, game_event, player):
text = 'test message'
GameEventPlayer.objects.create(game_event=game_event, player=player)
count_before = Message.objects.count()
message = Message.create(player, game_event, text)
assert Message.objects.count() == count_before + 1
assert message.text == 'test message'

def test_fail_create_message_function(self, game_event, player):
text = 'test message'
count_before = Message.objects.count()
with pytest.raises(ValidationError):
Message.create(player, game_event, text)
assert Message.objects.count() == count_before

def test_success_validate_message(self, game_event, player):
GameEventPlayer.objects.create(game_event=game_event, player=player)
text = 'test message'
e = Message.validate_message(player, game_event, text)
assert e is None

@pytest.mark.parametrize(
"text, expected_errors",
[
('test message', ["Just players from this event can send messages on chat"]),
('', ["Message can't be empty", "Just players from this event can send messages on chat"]),
(' ', ["Message can't be empty", "Just players from this event can send messages on chat"]),
]
)
def test_fail_validate_message(self, game_event, player, text, expected_errors):
with pytest.raises(ValidationError) as current_errors:
Message.validate_message(player, game_event, text)
errors = current_errors.value.messages[0].split("\n")
assert set(errors) == set(expected_errors)

def test_failed_send_empty_message(self, client, game_event, player):
client.force_login(player.user)
game_event_id = game_event.id
url = reverse('process_answer_game_event', args=[game_event_id])
response = client.post(url, {'answer': 'yes'})
count_before = Message.objects.count()
url = reverse('save_text_message', args=[game_event_id])
response = client.post(url, {'mytextbox': ''})
assert response.status_code == 302
assert Message.objects.count() == count_before

def test_failed_send_message_invalid_player(self, client, game_event, player):
client.force_login(player.user)
game_event_id = game_event.id
count_before = Message.objects.count()
reverse('remove_from_event', args=[game_event_id])
url = reverse('save_text_message', args=[game_event_id])
response = client.post(url, {'mytextbox': 'Test message'})

assert response.status_code == 302
assert Message.objects.count() == count_before
Loading