Add party reset stats

Closes #23
This commit is contained in:
Gabriel Augendre 2022-11-19 10:23:01 +01:00
parent ba3916c4b6
commit 12d6ee7a91
7 changed files with 74 additions and 5 deletions

View file

@ -147,13 +147,12 @@ def test_delete_character(selenium: WebDriver, live_server: LiveServer):
@pytest.mark.django_db @pytest.mark.django_db
@pytest.mark.parametrize("profile_name", ["Magicien", "Druide", "Guerrier"])
def test_reset_stats_view( def test_reset_stats_view(
profile_name: str, selenium: WebDriver, live_server: LiveServer, initial_data: None selenium: WebDriver, live_server: LiveServer, initial_data: None
): ):
username, password = "user", "some_password" username, password = "user", "some_password"
player = User.objects.create_user(username, password=password) player = User.objects.create_user(username, password=password)
profile = Profile.objects.get(name__iexact=profile_name) profile = Profile.objects.get(name__iexact="Magicien")
character = create_hurt_character(player, profile) character = create_hurt_character(player, profile)
login(selenium, live_server, username, password) login(selenium, live_server, username, password)

View file

@ -1,5 +1,6 @@
from django.db import models from django.db import models
from django.db.models import Q from django.db.models import Q
from django.urls import reverse
from django_extensions.db.models import TimeStampedModel from django_extensions.db.models import TimeStampedModel
from character.models import Character from character.models import Character
@ -53,3 +54,10 @@ class Party(UniquelyNamedModel, TimeStampedModel, models.Model):
class Meta(UniquelyNamedModel.Meta, TimeStampedModel.Meta): class Meta(UniquelyNamedModel.Meta, TimeStampedModel.Meta):
verbose_name = "Groupe" verbose_name = "Groupe"
verbose_name_plural = "Groupes" verbose_name_plural = "Groupes"
def get_absolute_url(self) -> str:
return reverse("party:details", kwargs={"pk": self.pk})
def reset_stats(self):
for character in self.characters.all():
character.reset_stats()

View file

@ -7,6 +7,9 @@
{% block content %} {% block content %}
<h1>{{ party.name }}</h1> <h1>{{ party.name }}</h1>
<p>MJ : {{ party.game_master.get_full_name|default:party.game_master.username }}</p> <p>MJ : {{ party.game_master.get_full_name|default:party.game_master.username }}</p>
<p>
<a href="{% url "party:reset_stats" pk=party.pk %}" id="reset-stats">Réinitialiser les stats</a>
</p>
<h2>Personnages</h2> <h2>Personnages</h2>
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 row-cols-xl-4 g-4"> <div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 row-cols-xl-4 g-4">
{% for character in party.characters.all %} {% for character in party.characters.all %}

View file

@ -0,0 +1,17 @@
{% extends "common/base.html" %}
{% block title %}Réinitialisation des stats des membres de {{ party.name }}{% endblock %}
{% block content %}
<h1>Réinitialisation des stats des membres de {{ party.name }}</h1>
<form action="{% url "party:reset_stats" pk=party.pk %}" method=post>
{% csrf_token %}
<p>
Êtes-vous certain de vouloir réinitialiser les stats de tous les membres de {{ party.name }} ?<br>
Cette action est irréversible.
</p>
<button class="btn btn-primary" type="submit">
<i class="fa-solid fa-suitcase-medical"></i> Réinitialiser les stats
</button>
</form>
{% endblock %}

View file

@ -7,8 +7,8 @@ from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.webdriver import WebDriver from selenium.webdriver.firefox.webdriver import WebDriver
from selenium.webdriver.support.select import Select from selenium.webdriver.support.select import Select
from character.models import Character from character.models import Character, Profile
from character.tests.test_interactions import login from character.tests.test_interactions import create_hurt_character, login
from common.models import User from common.models import User
from party.models import Party from party.models import Party
@ -90,3 +90,31 @@ def test_gm_observe_invited_character_in_two_groups(
).click() ).click()
title = selenium.find_element(By.TAG_NAME, "h1").text.strip() title = selenium.find_element(By.TAG_NAME, "h1").text.strip()
assert title == character.name assert title == character.name
@pytest.mark.django_db
def test_reset_stats_view(
selenium: WebDriver, live_server: LiveServer, initial_data: None
):
user, password = "gm", "password"
gm = User.objects.create_user(user, password=password)
assert Profile.objects.count() > 1
for profile in Profile.objects.all():
player = User.objects.create_user(f"user{profile}", password="password")
create_hurt_character(player, profile)
party = baker.make(Party, game_master=gm)
party.characters.set(Character.objects.all())
login(selenium, live_server, user, password)
url = reverse("party:details", kwargs={"pk": party.pk})
selenium.get(live_server.url + url)
selenium.find_element(By.ID, "reset-stats").click()
selenium.find_element(By.CSS_SELECTOR, "[type=submit]").click()
assert selenium.current_url == live_server.url + party.get_absolute_url()
for character in Character.objects.all():
assert character.health_remaining == character.health_max
assert character.mana_remaining == character.mana_max
assert character.recovery_points_remaining == character.recovery_points_max
assert character.luck_points_remaining == character.luck_points_max

View file

@ -9,6 +9,7 @@ urlpatterns = [
path("<int:pk>/", views.party_details, name="details"), path("<int:pk>/", views.party_details, name="details"),
path("<int:pk>/change/", views.party_change, name="change"), path("<int:pk>/change/", views.party_change, name="change"),
path("<int:pk>/delete/", views.party_delete, name="delete"), path("<int:pk>/delete/", views.party_delete, name="delete"),
path("<int:pk>/reset_stats/", views.party_reset_stats, name="reset_stats"),
path("<int:pk>/leave/<int:character_pk>/", views.party_leave, name="leave"), path("<int:pk>/leave/<int:character_pk>/", views.party_leave, name="leave"),
path("<int:pk>/join/<int:character_pk>/", views.party_join, name="join"), path("<int:pk>/join/<int:character_pk>/", views.party_join, name="join"),
path("<int:pk>/refuse/<int:character_pk>/", views.party_refuse, name="refuse"), path("<int:pk>/refuse/<int:character_pk>/", views.party_refuse, name="refuse"),

View file

@ -55,6 +55,19 @@ def party_delete(request, pk):
return render(request, "party/party_delete.html", context) return render(request, "party/party_delete.html", context)
@login_required
def party_reset_stats(request, pk):
party = get_object_or_404(Party.objects.managed_by(request.user), pk=pk)
context = {"party": party}
if request.method == "POST":
name = party.name
party.reset_stats()
message = f"Les stats de tous les membres de {name} ont été réinitialisées."
messages.success(request, message)
return redirect(party)
return render(request, "party/party_reset_stats.html", context)
@login_required @login_required
def party_change(request, pk): def party_change(request, pk):
party = get_object_or_404(Party.objects.managed_by(request.user), pk=pk) party = get_object_or_404(Party.objects.managed_by(request.user), pk=pk)