mirror of
https://github.com/Crocmagnon/charasheet.git
synced 2024-11-23 06:58:02 +01:00
Compare commits
No commits in common. "0c51954ddb5a79ae96d9e47b87a509ebb46cd4b8" and "580ba311a16ba1bee0e1982fea97d04634944d31" have entirely different histories.
0c51954ddb
...
580ba311a1
5 changed files with 31 additions and 130 deletions
|
@ -30,6 +30,10 @@ RUN apt-get update -y \
|
||||||
libxml2 \
|
libxml2 \
|
||||||
media-types
|
media-types
|
||||||
|
|
||||||
|
# Fetch project requirements
|
||||||
|
##############################################
|
||||||
|
COPY --chown=django:django --from=git /git-describe /git-commit /build-date /app/git/
|
||||||
|
|
||||||
# Create directory structure
|
# Create directory structure
|
||||||
##############################################
|
##############################################
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
@ -49,10 +53,6 @@ RUN python -m pip install --no-cache-dir -r requirements.txt
|
||||||
WORKDIR /app/src
|
WORKDIR /app/src
|
||||||
RUN python manage.py collectstatic --noinput --clear
|
RUN python manage.py collectstatic --noinput --clear
|
||||||
|
|
||||||
# Copy git info
|
|
||||||
##############################################
|
|
||||||
COPY --chown=django:django --from=git /git-describe /git-commit /build-date /app/git/
|
|
||||||
|
|
||||||
EXPOSE 8000
|
EXPOSE 8000
|
||||||
|
|
||||||
WORKDIR /app/src
|
WORKDIR /app/src
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
|
|
||||||
Manage your RPG party & character using an interactive web app accessible from any browser.
|
Manage your RPG party & character using an interactive web app accessible from any browser.
|
||||||
|
|
||||||
[![Test, build, publish & deploy](https://github.com/Crocmagnon/charasheet/actions/workflows/publish.yaml/badge.svg)](https://github.com/Crocmagnon/charasheet/actions/workflows/publish.yaml)
|
|
||||||
|
|
||||||
## Quick start
|
## Quick start
|
||||||
Clone, then
|
Clone, then
|
||||||
```shell
|
```shell
|
||||||
|
|
|
@ -262,36 +262,32 @@
|
||||||
<th scope="row">
|
<th scope="row">
|
||||||
Points de vie
|
Points de vie
|
||||||
{% if character|managed_by:user %}
|
{% if character|managed_by:user %}
|
||||||
<form id="health-controls"
|
<div class="btn-group btn-group-sm float-end" role="group">
|
||||||
hx-post="{% url "character:health_change" pk=character.pk %}"
|
<button
|
||||||
hx-target="#health-remaining"
|
hx-get="{% url "character:health_change" pk=character.pk %}?value=ko"
|
||||||
hx-swap="innerHTML"
|
hx-target="#health-remaining"
|
||||||
style="display: inline">
|
hx-swap="innerHTML"
|
||||||
{% csrf_token %}
|
type="button"
|
||||||
<div style="width: inherit" class="input-group input-group-sm float-end" role="group">
|
class="btn btn-outline-danger"><i class="fa-solid fa-battery-empty"></i></button>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
hx-get="{% url "character:health_change" pk=character.pk %}?value=-1"
|
||||||
name="action"
|
hx-target="#health-remaining"
|
||||||
value="ko"
|
hx-swap="innerHTML"
|
||||||
class="btn btn-outline-danger"><i class="fa-solid fa-battery-empty"></i></button>
|
type="button"
|
||||||
<button
|
class="btn btn-danger"><i class="fa-solid fa-minus"></i></button>
|
||||||
type="submit"
|
<button
|
||||||
name="action"
|
hx-get="{% url "character:health_change" pk=character.pk %}?value=1"
|
||||||
value="negative"
|
hx-target="#health-remaining"
|
||||||
class="btn btn-danger"><i class="fa-solid fa-minus"></i></button>
|
hx-swap="innerHTML"
|
||||||
<input aria-label="points de vie à ajouter/retirer" type="text" name="value" style="width: 50px" class="form-control" value="1">
|
type="button"
|
||||||
<button
|
class="btn btn-success"><i class="fa-solid fa-plus"></i></button>
|
||||||
type="submit"
|
<button
|
||||||
name="action"
|
hx-get="{% url "character:health_change" pk=character.pk %}?value=max"
|
||||||
value="positive"
|
hx-target="#health-remaining"
|
||||||
class="btn btn-success"><i class="fa-solid fa-plus"></i></button>
|
hx-swap="innerHTML"
|
||||||
<button
|
type="button"
|
||||||
type="submit"
|
class="btn btn-outline-success"><i class="fa-solid fa-battery-full"></i></button>
|
||||||
name="action"
|
</div>
|
||||||
value="max"
|
|
||||||
class="btn btn-outline-success"><i class="fa-solid fa-battery-full"></i></button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</th>
|
</th>
|
||||||
<td><span id="health-remaining">{{ character.health_remaining }}</span> / {{ character.health_max }}</td>
|
<td><span id="health-remaining">{{ character.health_remaining }}</span> / {{ character.health_max }}</td>
|
||||||
|
|
|
@ -93,70 +93,6 @@ def test_create_character(selenium: WebDriver, live_server: LiveServer):
|
||||||
assert getattr(character, name) == value
|
assert getattr(character, name) == value
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db()
|
|
||||||
def test_change_health(selenium: WebDriver, live_server: LiveServer):
|
|
||||||
call_command("loaddata", "initial_data")
|
|
||||||
username, password = "user1", "some_password"
|
|
||||||
player = User.objects.create_user(username, password=password)
|
|
||||||
character = baker.make(Character, player=player)
|
|
||||||
character.health_remaining = character.health_max
|
|
||||||
character.save()
|
|
||||||
login(selenium, live_server, username, password)
|
|
||||||
selenium.find_element(
|
|
||||||
By.CSS_SELECTOR,
|
|
||||||
f".character[data-id='{character.id}'] .btn-success",
|
|
||||||
).click()
|
|
||||||
assert selenium.find_element(By.ID, "health-remaining").text == str(
|
|
||||||
character.health_remaining,
|
|
||||||
)
|
|
||||||
|
|
||||||
controls = selenium.find_element(By.ID, "health-controls")
|
|
||||||
|
|
||||||
controls.find_element(By.CSS_SELECTOR, "button[type='submit'][value='ko']").click()
|
|
||||||
assert selenium.find_element(By.ID, "health-remaining").text == "0"
|
|
||||||
|
|
||||||
controls.find_element(By.CSS_SELECTOR, "button[type='submit'][value='max']").click()
|
|
||||||
assert selenium.find_element(By.ID, "health-remaining").text == str(
|
|
||||||
character.health_max,
|
|
||||||
)
|
|
||||||
|
|
||||||
controls.find_element(
|
|
||||||
By.CSS_SELECTOR,
|
|
||||||
"button[type='submit'][value='positive']",
|
|
||||||
).click()
|
|
||||||
assert selenium.find_element(By.ID, "health-remaining").text == str(
|
|
||||||
character.health_max,
|
|
||||||
)
|
|
||||||
|
|
||||||
controls.find_element(
|
|
||||||
By.CSS_SELECTOR,
|
|
||||||
"button[type='submit'][value='negative']",
|
|
||||||
).click()
|
|
||||||
assert selenium.find_element(By.ID, "health-remaining").text == str(
|
|
||||||
character.health_max - 1,
|
|
||||||
)
|
|
||||||
|
|
||||||
health_input = controls.find_element(By.CSS_SELECTOR, "input[name='value']")
|
|
||||||
health_input.clear()
|
|
||||||
health_input.send_keys("5")
|
|
||||||
|
|
||||||
controls.find_element(
|
|
||||||
By.CSS_SELECTOR,
|
|
||||||
"button[type='submit'][value='positive']",
|
|
||||||
).click()
|
|
||||||
assert selenium.find_element(By.ID, "health-remaining").text == str(
|
|
||||||
character.health_max,
|
|
||||||
)
|
|
||||||
|
|
||||||
controls.find_element(
|
|
||||||
By.CSS_SELECTOR,
|
|
||||||
"button[type='submit'][value='negative']",
|
|
||||||
).click()
|
|
||||||
assert selenium.find_element(By.ID, "health-remaining").text == str(
|
|
||||||
character.health_max - 5,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db()
|
@pytest.mark.django_db()
|
||||||
def test_list_characters(selenium: WebDriver, live_server: LiveServer):
|
def test_list_characters(selenium: WebDriver, live_server: LiveServer):
|
||||||
# Load fixtures
|
# Load fixtures
|
||||||
|
|
|
@ -123,11 +123,7 @@ def character_health_change(request, pk: int):
|
||||||
),
|
),
|
||||||
pk=pk,
|
pk=pk,
|
||||||
)
|
)
|
||||||
value = post_updated_value(
|
value = get_updated_value(request, character.health_remaining, character.health_max)
|
||||||
request,
|
|
||||||
character.health_remaining,
|
|
||||||
character.health_max,
|
|
||||||
)
|
|
||||||
character.health_remaining = value
|
character.health_remaining = value
|
||||||
character.save(update_fields=["health_remaining"])
|
character.save(update_fields=["health_remaining"])
|
||||||
response = HttpResponse(value)
|
response = HttpResponse(value)
|
||||||
|
@ -236,31 +232,6 @@ def character_luck_points_change(request, pk: int):
|
||||||
return HttpResponse(value)
|
return HttpResponse(value)
|
||||||
|
|
||||||
|
|
||||||
def post_updated_value(
|
|
||||||
request,
|
|
||||||
remaining_value: float,
|
|
||||||
max_value: float,
|
|
||||||
) -> int:
|
|
||||||
action = request.POST.get("action")
|
|
||||||
if action == "ko":
|
|
||||||
return 0
|
|
||||||
if action == "max":
|
|
||||||
return int(max_value)
|
|
||||||
|
|
||||||
multiplier = 0
|
|
||||||
if action == "positive":
|
|
||||||
multiplier = 1
|
|
||||||
elif action == "negative":
|
|
||||||
multiplier = -1
|
|
||||||
|
|
||||||
form_value = int(request.POST.get("value"))
|
|
||||||
remaining_value += form_value * multiplier
|
|
||||||
remaining_value = min([max_value, remaining_value])
|
|
||||||
remaining_value = max([0, remaining_value])
|
|
||||||
|
|
||||||
return int(remaining_value)
|
|
||||||
|
|
||||||
|
|
||||||
def get_updated_value(
|
def get_updated_value(
|
||||||
request,
|
request,
|
||||||
remaining_value: float,
|
remaining_value: float,
|
||||||
|
|
Loading…
Reference in a new issue