Compare commits

..

No commits in common. "c7eaa0f02fa55881245b9800093eb6b2e54ca8b5" and "98a6e4b9e237ab5d50f52c6db437e927f34ee190" have entirely different histories.

99 changed files with 15043 additions and 11936 deletions

View file

@ -11,7 +11,6 @@ permissions:
jobs:
tests:
name: Test
uses: ./.github/workflows/test.yaml
push_to_registry:
name: Push Docker image to Docker Hub
@ -51,4 +50,4 @@ jobs:
max_attempts: 5
retry_wait_seconds: 2
warning_on_retry: false
command: curl -sSL --fail -m 10 https://checkout.augendre.info/ping/ | grep ${GITHUB_SHA::7} > /dev/null
command: curl -sSL --fail -m 10 https://checkout.augendre.info | grep ${GITHUB_SHA::7} > /dev/null

View file

@ -23,8 +23,6 @@ jobs:
run: |
pip install pip-tools
pip-sync requirements.txt requirements-dev.txt
sudo apt-get update
sudo apt-get install -y --no-install-recommends gettext
- name: Setup pre-commit cache
uses: actions/cache@v3
with:
@ -33,5 +31,5 @@ jobs:
- name: Check pre-commit
run: pre-commit run --show-diff-on-failure --color=always --all-files
- name: Test
run: inv test-cov
run: pytest --cov=. --cov-branch --cov-report term-missing:skip-covered
working-directory: ./src/

View file

@ -28,8 +28,7 @@ RUN useradd -M -d /app -u 1000 -g 1000 -s /bin/bash django
RUN apt-get update -y \
&& apt-get install -y --no-install-recommends \
libxml2 \
media-types \
gettext
media-types
# Fetch project requirements
##############################################
@ -53,7 +52,6 @@ ENV DB_BASE_DIR "/app/db"
RUN python -m pip install --no-cache-dir -r requirements.txt
WORKDIR /app/src
RUN python manage.py collectstatic --noinput --clear
RUN python manage.py compilemessages -l fr -l en
EXPOSE 8000

View file

@ -2,16 +2,10 @@
Simple interface to register baskets.
## Quick start
Clone, then
## Development
```shell
pip install -U pip pip-tools invoke
inv sync-dependencies
pre-commit install --install-hooks
inv test
./src/manage.py migrate
./src/manage.py generat_dummy_baskets
./src/manage.py createsuperuser
inv test-cov
inv beam
```
# Reuse

View file

@ -55,6 +55,7 @@ EMAIL_TIMEOUT = 30
ANYMAIL = {
"MAILGUN_API_KEY": env("MAILGUN_API_KEY"),
"MAILGUN_SENDER_DOMAIN": env("MAILGUN_SENDER_DOMAIN"),
"MAILGUN_API_URL": "https://api.eu.mailgun.net/v3",
}
EMAIL_BACKEND = "anymail.backends.mailgun.EmailBackend"
@ -128,7 +129,6 @@ TEMPLATES = [
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
"common.context_processors.app",
],
},
},
@ -228,26 +228,3 @@ CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5"
CRISPY_TEMPLATE_PACK = "bootstrap5"
MESSAGE_TAGS = {messages.ERROR: "danger"}
APP = {
"build": {
"date": "latest-date",
"commit": "latest-commit",
"describe": "latest-describe",
},
}
try:
with Path("/app/git/build-date").open() as f:
APP["build"]["date"] = f.read().strip()
except Exception: # noqa: S110
pass
try:
with Path("/app/git/git-commit").open() as f:
APP["build"]["commit"] = f.read().strip()
except Exception: # noqa: S110
pass
try:
with Path("/app/git/git-describe").open() as f:
APP["build"]["describe"] = f.read().strip()
except Exception: # noqa: S110
pass

View file

@ -1,5 +0,0 @@
from django.conf import settings
def app(_):
return settings.APP

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,8 +1,9 @@
/*!
* Bootstrap Reboot v5.2.3 (https://getbootstrap.com/)
* Copyright 2011-2022 The Bootstrap Authors
* Copyright 2011-2022 Twitter, Inc.
* Bootstrap Reboot v5.1.3 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/
:root {
--bs-blue: #0d6efd;
@ -15,7 +16,6 @@
--bs-green: #198754;
--bs-teal: #20c997;
--bs-cyan: #0dcaf0;
--bs-black: #000;
--bs-white: #fff;
--bs-gray: #6c757d;
--bs-gray-dark: #343a40;
@ -48,7 +48,7 @@
--bs-black-rgb: 0, 0, 0;
--bs-body-color-rgb: 33, 37, 41;
--bs-body-bg-rgb: 255, 255, 255;
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
--bs-body-font-family: var(--bs-font-sans-serif);
@ -57,20 +57,6 @@
--bs-body-line-height: 1.5;
--bs-body-color: #212529;
--bs-body-bg: #fff;
--bs-border-width: 1px;
--bs-border-style: solid;
--bs-border-color: #dee2e6;
--bs-border-color-translucent: rgba(0, 0, 0, 0.175);
--bs-border-radius: 0.375rem;
--bs-border-radius-sm: 0.25rem;
--bs-border-radius-lg: 0.5rem;
--bs-border-radius-xl: 1rem;
--bs-border-radius-2xl: 2rem;
--bs-border-radius-pill: 50rem;
--bs-link-color: #0d6efd;
--bs-link-hover-color: #0a58ca;
--bs-code-color: #d63384;
--bs-highlight-bg: #fff3cd;
}
*,
@ -101,11 +87,15 @@ body {
hr {
margin: 1rem 0;
color: inherit;
background-color: currentColor;
border: 0;
border-top: 1px solid;
opacity: 0.25;
}
hr:not([size]) {
height: 1px;
}
h6, h5, h4, h3, h2, h1 {
margin-top: 0;
margin-bottom: 0.5rem;
@ -162,7 +152,8 @@ p {
margin-bottom: 1rem;
}
abbr[title] {
abbr[title],
abbr[data-bs-original-title] {
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
@ -218,8 +209,8 @@ small {
}
mark {
padding: 0.1875em;
background-color: var(--bs-highlight-bg);
padding: 0.2em;
background-color: #fcf8e3;
}
sub,
@ -239,11 +230,11 @@ sup {
}
a {
color: var(--bs-link-color);
color: #0d6efd;
text-decoration: underline;
}
a:hover {
color: var(--bs-link-hover-color);
color: #0a58ca;
}
a:not([href]):not([class]), a:not([href]):not([class]):hover {
@ -257,6 +248,8 @@ kbd,
samp {
font-family: var(--bs-font-monospace);
font-size: 1em;
direction: ltr /* rtl:ignore */;
unicode-bidi: bidi-override;
}
pre {
@ -274,7 +267,7 @@ pre code {
code {
font-size: 0.875em;
color: var(--bs-code-color);
color: #d63384;
word-wrap: break-word;
}
a > code {
@ -282,15 +275,16 @@ a > code {
}
kbd {
padding: 0.1875rem 0.375rem;
padding: 0.2rem 0.4rem;
font-size: 0.875em;
color: var(--bs-body-bg);
background-color: var(--bs-body-color);
border-radius: 0.25rem;
color: #fff;
background-color: #212529;
border-radius: 0.2rem;
}
kbd kbd {
padding: 0;
font-size: 1em;
font-weight: 700;
}
figure {
@ -369,8 +363,8 @@ select:disabled {
opacity: 1;
}
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
display: none !important;
[list]::-webkit-calendar-picker-indicator {
display: none;
}
button,
@ -456,11 +450,14 @@ legend + * {
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
::file-selector-button {
font: inherit;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,8 +1,9 @@
/*!
* Bootstrap Reboot v5.2.3 (https://getbootstrap.com/)
* Copyright 2011-2022 The Bootstrap Authors
* Copyright 2011-2022 Twitter, Inc.
* Bootstrap Reboot v5.1.3 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/
:root {
--bs-blue: #0d6efd;
@ -15,7 +16,6 @@
--bs-green: #198754;
--bs-teal: #20c997;
--bs-cyan: #0dcaf0;
--bs-black: #000;
--bs-white: #fff;
--bs-gray: #6c757d;
--bs-gray-dark: #343a40;
@ -48,7 +48,7 @@
--bs-black-rgb: 0, 0, 0;
--bs-body-color-rgb: 33, 37, 41;
--bs-body-bg-rgb: 255, 255, 255;
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
--bs-body-font-family: var(--bs-font-sans-serif);
@ -57,20 +57,6 @@
--bs-body-line-height: 1.5;
--bs-body-color: #212529;
--bs-body-bg: #fff;
--bs-border-width: 1px;
--bs-border-style: solid;
--bs-border-color: #dee2e6;
--bs-border-color-translucent: rgba(0, 0, 0, 0.175);
--bs-border-radius: 0.375rem;
--bs-border-radius-sm: 0.25rem;
--bs-border-radius-lg: 0.5rem;
--bs-border-radius-xl: 1rem;
--bs-border-radius-2xl: 2rem;
--bs-border-radius-pill: 50rem;
--bs-link-color: #0d6efd;
--bs-link-hover-color: #0a58ca;
--bs-code-color: #d63384;
--bs-highlight-bg: #fff3cd;
}
*,
@ -101,11 +87,15 @@ body {
hr {
margin: 1rem 0;
color: inherit;
background-color: currentColor;
border: 0;
border-top: 1px solid;
opacity: 0.25;
}
hr:not([size]) {
height: 1px;
}
h6, h5, h4, h3, h2, h1 {
margin-top: 0;
margin-bottom: 0.5rem;
@ -162,7 +152,8 @@ p {
margin-bottom: 1rem;
}
abbr[title] {
abbr[title],
abbr[data-bs-original-title] {
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
@ -218,8 +209,8 @@ small {
}
mark {
padding: 0.1875em;
background-color: var(--bs-highlight-bg);
padding: 0.2em;
background-color: #fcf8e3;
}
sub,
@ -239,11 +230,11 @@ sup {
}
a {
color: var(--bs-link-color);
color: #0d6efd;
text-decoration: underline;
}
a:hover {
color: var(--bs-link-hover-color);
color: #0a58ca;
}
a:not([href]):not([class]), a:not([href]):not([class]):hover {
@ -257,6 +248,8 @@ kbd,
samp {
font-family: var(--bs-font-monospace);
font-size: 1em;
direction: ltr ;
unicode-bidi: bidi-override;
}
pre {
@ -274,7 +267,7 @@ pre code {
code {
font-size: 0.875em;
color: var(--bs-code-color);
color: #d63384;
word-wrap: break-word;
}
a > code {
@ -282,15 +275,16 @@ a > code {
}
kbd {
padding: 0.1875rem 0.375rem;
padding: 0.2rem 0.4rem;
font-size: 0.875em;
color: var(--bs-body-bg);
background-color: var(--bs-body-color);
border-radius: 0.25rem;
color: #fff;
background-color: #212529;
border-radius: 0.2rem;
}
kbd kbd {
padding: 0;
font-size: 1em;
font-weight: 700;
}
figure {
@ -369,8 +363,8 @@ select:disabled {
opacity: 1;
}
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
display: none !important;
[list]::-webkit-calendar-picker-indicator {
display: none;
}
button,
@ -454,11 +448,14 @@ legend + * {
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
::file-selector-button {
font: inherit;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -5,7 +5,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Checkout</title>
<link href="{% static "vendor/bootstrap-5.2.3-dist/css/bootstrap.min.css" %}"
<link href="{% static "vendor/bootstrap-5.1.3-dist/css/bootstrap.min.css" %}"
rel="stylesheet">
<style>
body {
@ -13,9 +13,9 @@
touch-action: manipulation;
}
</style>
<script defer src="{% static "vendor/fontawesome-6.3.0-free/brands.min.js" %}"></script>
<script defer src="{% static "vendor/fontawesome-6.3.0-free/solid.min.js" %}"></script>
<script defer src="{% static "vendor/fontawesome-6.3.0-free/fontawesome.min.js" %}"></script>
<script defer src="{% static "vendor/fontawesome-6.1.1-free/brands.min.js" %}"></script>
<script defer src="{% static "vendor/fontawesome-6.1.1-free/solid.min.js" %}"></script>
<script defer src="{% static "vendor/fontawesome-6.1.1-free/fontawesome.min.js" %}"></script>
{% block extrahead %}
{% endblock %}
@ -27,7 +27,7 @@
{% block content %}
{% endblock %}
</div>
<script src="{% static "vendor/bootstrap-5.2.3-dist/js/bootstrap.bundle.min.js" %}"></script>
<script src="{% static "vendor/bootstrap-5.1.3-dist/js/bootstrap.bundle.min.js" %}"></script>
{% block extrascript %}
{% endblock %}
</body>

View file

@ -1,10 +0,0 @@
{% extends "common/base.html" %}
{% block content %}
<h1>Ping</h1>
<h2>Versions</h2>
<ul>
<li>Build date: {{ build.date }}</li>
<li>Commit: {{ build.commit }}</li>
<li>Version: {{ build.describe }}</li>
</ul>
{% endblock %}

View file

@ -1,10 +1,8 @@
from django.urls import path
from common import views
from common.views import home
app_name = "common"
urlpatterns = [
path("error_check/", views.error_check, name="error_check"),
path("ping/", views.ping, name="ping"),
path("", views.home, name="home"),
path("", home, name="home"),
]

View file

@ -1,14 +1,5 @@
from django.shortcuts import redirect, render
from django.shortcuts import redirect
def home(_request):
return redirect("purchase:new")
def ping(request):
return render(request, "common/ping.html", {})
def error_check(_request):
msg = "Error check"
raise ValueError(msg)

View file

@ -22,5 +22,4 @@ def firefox_options(firefox_options):
@pytest.fixture()
def selenium(selenium):
selenium.implicitly_wait(3)
selenium.set_window_size(3860, 2140)
return selenium

View file

@ -45,8 +45,7 @@ class Command(BaseCommand):
items_in_basket = len(products)
if items_in_basket < 1:
items_in_basket = 1
rng = np.random.default_rng()
selected_products = rng.choice(
selected_products = np.random.Generator(
products,
size=items_in_basket,
replace=False,

View file

@ -41,6 +41,6 @@
{% endblock %}
{% block extrascript %}
<script src="{% static 'vendor/htmx-1.8.6/htmx.min.js' %}" defer></script>
<script src="{% static 'vendor/htmx-1.8.0/htmx.min.js' %}" defer></script>
{% django_htmx_script %}
{% endblock %}

View file

@ -57,13 +57,13 @@ def compilemessages(ctx: Context) -> None:
ctx.run("./manage.py compilemessages -l en -l fr", pty=True, echo=True)
@task(pre=[compilemessages])
@task
def test(ctx: Context) -> None:
with ctx.cd(SRC_DIR):
ctx.run("pytest", pty=True, echo=True)
@task(pre=[compilemessages])
@task
def test_cov(ctx: Context) -> None:
with ctx.cd(SRC_DIR):
ctx.run(