Allow deleting effects

This commit is contained in:
Gabriel Augendre 2023-01-17 11:11:07 +01:00
parent ad5e690e21
commit 820ce5e376
5 changed files with 65 additions and 16 deletions

View file

@ -2,7 +2,20 @@
<div class="col"> <div class="col">
<div class="card {% if rounds == 0 %}text-bg-secondary{% endif %} effect" data-id="{{ effect.pk }}"> <div class="card {% if rounds == 0 %}text-bg-secondary{% endif %} effect" data-id="{{ effect.pk }}">
<div class="card-body"> <div class="card-body">
<h5 class="card-title">{{ effect.name }}</h5> <h5 class="card-title">
{% if party.game_master == request.user %}
<button
hx-get="{% url "party:delete_effect" pk=party.pk effect_pk=effect.pk %}"
hx-target="#effects"
hx-swap="outerHTML"
class="btn btn-sm btn-danger delete"
type="button"
>
<i class="fa-solid fa-trash"></i>
</button>
{% endif %}
{{ effect.name }}
</h5>
<h6 class="card-subtitle mb-2 {% if rounds != 0 %}text-muted{% endif %}"> <h6 class="card-subtitle mb-2 {% if rounds != 0 %}text-muted{% endif %}">
{{ effect.created_by.get_full_name|default:effect.created_by.username }} <i class="fa-solid fa-arrow-right"></i> {{ effect.created_by.get_full_name|default:effect.created_by.username }} <i class="fa-solid fa-arrow-right"></i>
{{ effect.target }} {{ effect.target }}

View file

@ -17,7 +17,7 @@
hx-swap="outerHTML" hx-swap="outerHTML"
type="button" type="button"
id="increase-rounds" id="increase-rounds"
class="btn btn-outline-secondary"> <i class="fa-solid fa-plus"></i> tours class="btn btn-outline-secondary"><i class="fa-solid fa-plus"></i> tours
</button> </button>
<button <button
hx-get="{% url "party:decrease_rounds" pk=party.pk %}" hx-get="{% url "party:decrease_rounds" pk=party.pk %}"
@ -25,7 +25,7 @@
hx-swap="outerHTML" hx-swap="outerHTML"
type="button" type="button"
id="decrease-rounds" id="decrease-rounds"
class="btn btn-outline-secondary"> <i class="fa-solid fa-minus"></i> tours class="btn btn-outline-secondary"><i class="fa-solid fa-minus"></i> tours
</button> </button>
</div> </div>
{% endif %} {% endif %}

View file

@ -4,6 +4,7 @@ import pytest
from django.urls import reverse from django.urls import reverse
from model_bakery import baker from model_bakery import baker
from pytest_django.live_server_helper import LiveServer from pytest_django.live_server_helper import LiveServer
from selenium.common import NoSuchElementException
from selenium.webdriver.common.by import By 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
@ -233,18 +234,25 @@ def test_gm_can_change_remaining_rounds(
) )
@pytest.mark.django_db
def test_gm_can_update_existing_effect(
selenium: WebDriver, live_server: LiveServer, initial_data: None
):
"""The GM of a group can update existing effect, except group and creator."""
@pytest.mark.django_db @pytest.mark.django_db
def test_gm_can_delete_any_existing_effect( def test_gm_can_delete_any_existing_effect(
selenium: WebDriver, live_server: LiveServer, initial_data: None selenium: WebDriver, live_server: LiveServer, initial_data: None
): ):
"""The GM of a group can delete any existing effect, running or terminated.""" """The GM of a group can delete any existing effect, running or terminated."""
user, password = "gm", "password"
gm = User.objects.create_user(user, password=password)
party = baker.make(Party, game_master=gm)
effects = baker.make(BattleEffect, _quantity=2, party=party)
assert BattleEffect.objects.count() == 2
go_to_party(selenium, live_server, party, user, password)
selenium.find_element(
By.CSS_SELECTOR, f'.effect[data-id="{effects[0].pk}"] .delete'
).click()
assert BattleEffect.objects.count() == 1
BattleEffect.objects.get(pk=effects[1].pk)
@pytest.mark.django_db @pytest.mark.django_db
@ -252,13 +260,28 @@ def test_player_cant_change_existing_running_effect(
selenium: WebDriver, live_server: LiveServer, initial_data: None selenium: WebDriver, live_server: LiveServer, initial_data: None
): ):
"""Members of the group can only view existing running effects, no update.""" """Members of the group can only view existing running effects, no update."""
user, password = "player", "password"
player = User.objects.create_user(user, password=password)
character = baker.make(Character, player=player)
party = baker.make(Party)
party.characters.set([character])
effects = baker.make(BattleEffect, _quantity=2, party=party)
go_to_party(selenium, live_server, party, user, password)
effect = effects[0]
effect_element = selenium.find_element(
By.CSS_SELECTOR, f'.effect[data-id="{effect.pk}"]'
)
assert effect.name in effect_element.text
assert effect.target in effect_element.text
assert effect.description in effect_element.text
@pytest.mark.django_db with pytest.raises(NoSuchElementException):
def test_player_can_delete_terminated_effect( selenium.find_element(By.CSS_SELECTOR, ".effect .delete")
selenium: WebDriver, live_server: LiveServer, initial_data: None with pytest.raises(NoSuchElementException):
): selenium.find_element(By.ID, "increase-rounds")
"""Members of the group can delete terminated effects.""" with pytest.raises(NoSuchElementException):
selenium.find_element(By.ID, "decrease-rounds")
def fill_effect(selenium, name, description, target, remaining_rounds): def fill_effect(selenium, name, description, target, remaining_rounds):

View file

@ -11,6 +11,11 @@ urlpatterns = [
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>/reset_stats/", views.party_reset_stats, name="reset_stats"),
path("<int:pk>/add_effect/", views.party_add_effect, name="add_effect"), path("<int:pk>/add_effect/", views.party_add_effect, name="add_effect"),
path(
"<int:pk>/delete_effect/<int:effect_pk>/",
views.party_delete_effect,
name="delete_effect",
),
path( path(
"<int:pk>/increase_rounds/", views.party_increase_rounds, name="increase_rounds" "<int:pk>/increase_rounds/", views.party_increase_rounds, name="increase_rounds"
), ),

View file

@ -5,7 +5,7 @@ from django.views.decorators.http import require_GET, require_http_methods
from character.models import Character, HarmfulState from character.models import Character, HarmfulState
from party.forms import BattleEffectForm, PartyForm from party.forms import BattleEffectForm, PartyForm
from party.models import Party from party.models import BattleEffect, Party
@require_GET @require_GET
@ -109,6 +109,14 @@ def party_decrease_rounds(request, pk):
return render(request, "party/snippets/effects.html", {"party": party}) return render(request, "party/snippets/effects.html", {"party": party})
@require_GET
@login_required
def party_delete_effect(request, pk, effect_pk):
party = get_object_or_404(Party.objects.managed_by(request.user), pk=pk)
BattleEffect.objects.filter(pk=effect_pk).delete()
return render(request, "party/snippets/effects.html", {"party": party})
@require_http_methods(["GET", "POST"]) @require_http_methods(["GET", "POST"])
@login_required @login_required
def party_change(request, pk): def party_change(request, pk):