2023-01-17 10:55:10 +01:00
|
|
|
import random
|
|
|
|
|
2022-11-16 12:42:41 +01:00
|
|
|
import pytest
|
|
|
|
from django.urls import reverse
|
|
|
|
from model_bakery import baker
|
|
|
|
from pytest_django.live_server_helper import LiveServer
|
2023-01-17 11:11:07 +01:00
|
|
|
from selenium.common import NoSuchElementException
|
2022-11-16 12:42:41 +01:00
|
|
|
from selenium.webdriver.common.by import By
|
|
|
|
from selenium.webdriver.firefox.webdriver import WebDriver
|
|
|
|
from selenium.webdriver.support.select import Select
|
|
|
|
|
2022-11-19 10:23:01 +01:00
|
|
|
from character.models import Character, Profile
|
|
|
|
from character.tests.test_interactions import create_hurt_character, login
|
2022-11-16 12:42:41 +01:00
|
|
|
from common.models import User
|
2023-01-16 18:02:14 +01:00
|
|
|
from party.models import BattleEffect, Party
|
2022-11-16 12:42:41 +01:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.django_db
|
2023-01-16 18:02:14 +01:00
|
|
|
def test_add_character_to_existing_group(
|
|
|
|
selenium: WebDriver, live_server: LiveServer, initial_data: None
|
|
|
|
):
|
2022-11-16 12:42:41 +01:00
|
|
|
username, password = "gm", "password"
|
|
|
|
gm = User.objects.create_user(username, password=password)
|
|
|
|
player = User.objects.create_user("player")
|
|
|
|
character = baker.make(Character, player=player)
|
|
|
|
party = baker.make(Party, game_master=gm)
|
|
|
|
|
2022-11-19 09:45:30 +01:00
|
|
|
login(selenium, live_server, username, password)
|
2022-11-16 12:42:41 +01:00
|
|
|
|
|
|
|
selenium.get(live_server.url + reverse("party:list"))
|
|
|
|
selenium.find_element(
|
|
|
|
By.CSS_SELECTOR, f".party[data-id='{party.pk}'] .edit"
|
|
|
|
).click()
|
|
|
|
invited = Select(selenium.find_element(By.ID, "id_invited_characters"))
|
|
|
|
invited.select_by_index(0)
|
|
|
|
selenium.find_element(By.CSS_SELECTOR, "[type=submit]").click()
|
|
|
|
|
|
|
|
assert selenium.current_url == live_server.url + reverse("party:list")
|
|
|
|
party.refresh_from_db()
|
|
|
|
assert set(party.invited_characters.all()) == {character}
|
2022-11-16 12:47:56 +01:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.django_db
|
|
|
|
def test_gm_observe_invited_character_in_group(
|
2023-01-16 18:02:14 +01:00
|
|
|
selenium: WebDriver, live_server: LiveServer, initial_data: None
|
2022-11-16 12:47:56 +01:00
|
|
|
):
|
|
|
|
username, password = "gm", "password"
|
|
|
|
gm = User.objects.create_user(username, password=password)
|
|
|
|
player = User.objects.create_user("player")
|
|
|
|
party = baker.make(Party, game_master=gm)
|
|
|
|
character = baker.make(Character, player=player)
|
|
|
|
party.invited_characters.add(character)
|
|
|
|
|
2022-11-19 09:45:30 +01:00
|
|
|
login(selenium, live_server, username, password)
|
2022-11-16 12:47:56 +01:00
|
|
|
|
|
|
|
selenium.get(live_server.url + reverse("party:list"))
|
|
|
|
selenium.find_element(
|
|
|
|
By.CSS_SELECTOR, f".party[data-id='{party.pk}'] .access"
|
|
|
|
).click()
|
|
|
|
selenium.find_element(
|
|
|
|
By.CSS_SELECTOR, f".character[data-id='{character.pk}'] .observe"
|
|
|
|
).click()
|
|
|
|
title = selenium.find_element(By.TAG_NAME, "h1").text.strip()
|
|
|
|
assert title == character.name
|
2022-11-16 15:21:29 +01:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.django_db
|
|
|
|
def test_gm_observe_invited_character_in_two_groups(
|
2023-01-16 18:02:14 +01:00
|
|
|
selenium: WebDriver, live_server: LiveServer, initial_data: None
|
2022-11-16 15:21:29 +01:00
|
|
|
):
|
|
|
|
username, password = "gm", "password"
|
|
|
|
gm = User.objects.create_user(username, password=password)
|
|
|
|
player = User.objects.create_user("player")
|
|
|
|
party = baker.make(Party, game_master=gm)
|
|
|
|
other_party = baker.make(Party, game_master=gm)
|
|
|
|
character = baker.make(Character, player=player)
|
|
|
|
party.invited_characters.add(character)
|
|
|
|
other_party.invited_characters.add(character)
|
|
|
|
|
2022-11-19 09:45:30 +01:00
|
|
|
login(selenium, live_server, username, password)
|
2022-11-16 15:21:29 +01:00
|
|
|
|
|
|
|
selenium.get(live_server.url + reverse("party:list"))
|
|
|
|
selenium.find_element(
|
|
|
|
By.CSS_SELECTOR, f".party[data-id='{party.pk}'] .access"
|
|
|
|
).click()
|
|
|
|
selenium.find_element(
|
|
|
|
By.CSS_SELECTOR, f".character[data-id='{character.pk}'] .observe"
|
|
|
|
).click()
|
|
|
|
title = selenium.find_element(By.TAG_NAME, "h1").text.strip()
|
|
|
|
assert title == character.name
|
2022-11-19 10:23:01 +01:00
|
|
|
|
|
|
|
|
|
|
|
@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
|
2023-01-16 18:02:14 +01:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.django_db
|
|
|
|
def test_player_can_add_effect_to_group(
|
|
|
|
selenium: WebDriver, live_server: LiveServer, initial_data: None
|
|
|
|
):
|
|
|
|
"""Any member of a group can add effects to the group."""
|
|
|
|
user, password = "player", "password"
|
|
|
|
player = User.objects.create_user(user, password=password)
|
|
|
|
character = baker.make(Character, player=player)
|
|
|
|
party = baker.make(Party)
|
|
|
|
party.characters.add(character)
|
|
|
|
|
|
|
|
assert BattleEffect.objects.count() == 0
|
|
|
|
|
2023-01-17 09:51:55 +01:00
|
|
|
name = "Agrandissement"
|
|
|
|
target = "Joueur 4"
|
|
|
|
description = (
|
2023-01-16 18:02:14 +01:00
|
|
|
"Le Magicien ou une cible volontaire (au contact) voit sa taille augmenter de "
|
|
|
|
"50% pendant [5 + Mod. d'INT] tours. Il gagne +2 aux DM au contact et aux "
|
|
|
|
"tests de FOR. Pataud, il subit un malus de -2 aux tests de DEX."
|
|
|
|
)
|
2023-01-17 09:51:55 +01:00
|
|
|
remaining_rounds = "8"
|
2023-01-16 18:02:14 +01:00
|
|
|
|
2023-01-17 10:55:10 +01:00
|
|
|
go_to_party(selenium, live_server, party, user, password)
|
2023-01-17 09:51:55 +01:00
|
|
|
fill_effect(selenium, name, description, target, remaining_rounds)
|
|
|
|
assert_effect_is_created(name, description, target, remaining_rounds)
|
2023-01-16 18:02:14 +01:00
|
|
|
# Todo: assert effect is displayed
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.django_db
|
|
|
|
def test_gm_can_add_effect_to_group(
|
|
|
|
selenium: WebDriver, live_server: LiveServer, initial_data: None
|
|
|
|
):
|
|
|
|
"""The GM of a group can add effects to the group."""
|
|
|
|
user, password = "gm", "password"
|
|
|
|
gm = User.objects.create_user(user, password=password)
|
|
|
|
party = baker.make(Party, game_master=gm)
|
|
|
|
|
|
|
|
assert BattleEffect.objects.count() == 0
|
|
|
|
|
2023-01-17 09:51:55 +01:00
|
|
|
name = "Brûlé"
|
|
|
|
target = "Boss 2"
|
|
|
|
description = (
|
2023-01-16 18:02:14 +01:00
|
|
|
"Le Magicien choisit une cible située à moins de 30 mètres. Si son attaque "
|
|
|
|
"magique réussit, la cible encaisse [1d6 + Mod. d'INT] DM et la flèche "
|
|
|
|
"enflamme ses vêtements. Chaque tour de combat suivant, le feu inflige 1d6 "
|
|
|
|
"dégâts supplémentaires. Sur un résultat de 1 à 2, les flammes s'éteignent et "
|
|
|
|
"le sort prend fin."
|
|
|
|
)
|
2023-01-17 09:51:55 +01:00
|
|
|
remaining_rounds = "-1"
|
2023-01-16 18:02:14 +01:00
|
|
|
|
2023-01-17 10:55:10 +01:00
|
|
|
go_to_party(selenium, live_server, party, user, password)
|
2023-01-17 09:51:55 +01:00
|
|
|
fill_effect(selenium, name, description, target, remaining_rounds)
|
|
|
|
assert_effect_is_created(name, description, target, remaining_rounds)
|
2023-01-16 18:02:14 +01:00
|
|
|
# Todo: assert effect is displayed
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.django_db
|
|
|
|
def test_gm_can_change_remaining_rounds(
|
|
|
|
selenium: WebDriver, live_server: LiveServer, initial_data: None
|
|
|
|
):
|
|
|
|
"""The GM of a group can increase or decrease the remaining rounds of effects."""
|
2023-01-17 10:55:10 +01:00
|
|
|
user, password = "gm", "password"
|
|
|
|
gm = User.objects.create_user(user, password=password)
|
|
|
|
party = baker.make(Party, game_master=gm)
|
|
|
|
|
|
|
|
active_not_nearly_terminated = baker.make( # noqa: F841
|
|
|
|
BattleEffect,
|
|
|
|
_quantity=7,
|
|
|
|
remaining_rounds=lambda: random.randint(2, 12),
|
|
|
|
party=party,
|
|
|
|
)
|
|
|
|
active_nearly_terminated = baker.make( # noqa: F841
|
|
|
|
BattleEffect, _quantity=3, remaining_rounds=1, party=party
|
|
|
|
)
|
|
|
|
terminated = baker.make( # noqa: F841
|
|
|
|
BattleEffect, _quantity=5, remaining_rounds=0, party=party
|
|
|
|
)
|
|
|
|
permanent = baker.make( # noqa: F841
|
|
|
|
BattleEffect, _quantity=2, remaining_rounds=-1, party=party
|
|
|
|
)
|
|
|
|
not_party = baker.make(BattleEffect, _quantity=4, remaining_rounds=55) # noqa: F841
|
|
|
|
|
|
|
|
go_to_party(selenium, live_server, party, user, password)
|
|
|
|
selenium.find_element(By.ID, "increase-rounds").click()
|
|
|
|
assert BattleEffect.objects.filter(party=party).permanent().count() == 2
|
|
|
|
assert (
|
|
|
|
BattleEffect.objects.filter(party=party, remaining_rounds__gt=1).count() == 10
|
|
|
|
)
|
|
|
|
assert BattleEffect.objects.filter(party=party, remaining_rounds=1).count() == 5
|
|
|
|
assert BattleEffect.objects.filter(party=party).terminated().count() == 0
|
|
|
|
assert (
|
|
|
|
BattleEffect.objects.exclude(party=party).filter(remaining_rounds=55).count()
|
|
|
|
== 4
|
|
|
|
)
|
|
|
|
|
|
|
|
selenium.find_element(By.ID, "decrease-rounds").click()
|
|
|
|
assert BattleEffect.objects.filter(party=party).permanent().count() == 2
|
|
|
|
assert BattleEffect.objects.filter(party=party, remaining_rounds__gt=1).count() == 7
|
|
|
|
assert BattleEffect.objects.filter(party=party, remaining_rounds=1).count() == 3
|
|
|
|
assert BattleEffect.objects.filter(party=party).terminated().count() == 5
|
|
|
|
assert (
|
|
|
|
BattleEffect.objects.exclude(party=party).filter(remaining_rounds=55).count()
|
|
|
|
== 4
|
|
|
|
)
|
|
|
|
|
|
|
|
selenium.find_element(By.ID, "decrease-rounds").click()
|
|
|
|
assert BattleEffect.objects.filter(party=party).permanent().count() == 2
|
|
|
|
assert BattleEffect.objects.filter(party=party).active().count() == 7
|
|
|
|
assert BattleEffect.objects.filter(party=party, remaining_rounds=1).count() == 0
|
|
|
|
assert BattleEffect.objects.filter(party=party).terminated().count() == 8
|
|
|
|
assert (
|
|
|
|
BattleEffect.objects.exclude(party=party).filter(remaining_rounds=55).count()
|
|
|
|
== 4
|
|
|
|
)
|
2023-01-16 18:02:14 +01:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.django_db
|
|
|
|
def test_gm_can_delete_any_existing_effect(
|
|
|
|
selenium: WebDriver, live_server: LiveServer, initial_data: None
|
|
|
|
):
|
|
|
|
"""The GM of a group can delete any existing effect, running or terminated."""
|
2023-01-17 11:11:07 +01:00
|
|
|
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)
|
2023-01-16 18:02:14 +01:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.django_db
|
|
|
|
def test_player_cant_change_existing_running_effect(
|
|
|
|
selenium: WebDriver, live_server: LiveServer, initial_data: None
|
|
|
|
):
|
|
|
|
"""Members of the group can only view existing running effects, no update."""
|
2023-01-17 11:11:07 +01:00
|
|
|
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)
|
2023-01-16 18:02:14 +01:00
|
|
|
|
2023-01-17 11:11:07 +01:00
|
|
|
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
|
|
|
|
|
|
|
|
with pytest.raises(NoSuchElementException):
|
|
|
|
selenium.find_element(By.CSS_SELECTOR, ".effect .delete")
|
|
|
|
with pytest.raises(NoSuchElementException):
|
|
|
|
selenium.find_element(By.ID, "increase-rounds")
|
|
|
|
with pytest.raises(NoSuchElementException):
|
|
|
|
selenium.find_element(By.ID, "decrease-rounds")
|
2023-01-17 09:51:55 +01:00
|
|
|
|
|
|
|
|
|
|
|
def fill_effect(selenium, name, description, target, remaining_rounds):
|
|
|
|
selenium.find_element(By.ID, "add-effect").click()
|
|
|
|
selenium.find_element(By.ID, "id_name").send_keys(name)
|
|
|
|
selenium.find_element(By.ID, "id_target").send_keys(target)
|
|
|
|
selenium.find_element(By.ID, "id_description").send_keys(description)
|
|
|
|
rounds_element = selenium.find_element(By.ID, "id_remaining_rounds")
|
|
|
|
rounds_element.clear()
|
|
|
|
rounds_element.send_keys(remaining_rounds)
|
|
|
|
selenium.find_element(By.CSS_SELECTOR, "button[type=submit]").click()
|
|
|
|
|
|
|
|
|
|
|
|
def assert_effect_is_created(name, description, target, remaining_rounds):
|
|
|
|
assert BattleEffect.objects.count() == 1
|
|
|
|
effect = BattleEffect.objects.first()
|
|
|
|
assert effect.name == name
|
|
|
|
assert effect.target == target
|
|
|
|
assert effect.description == description
|
|
|
|
assert str(effect.remaining_rounds) == remaining_rounds
|
2023-01-17 10:55:10 +01:00
|
|
|
|
|
|
|
|
|
|
|
def go_to_party(selenium, live_server, party, user, password):
|
|
|
|
login(selenium, live_server, user, password)
|
|
|
|
url = reverse("party:details", kwargs={"pk": party.pk})
|
|
|
|
selenium.get(live_server.url + url)
|