Skip to content

Commit

Permalink
Misc tidying and fixing (#62)
Browse files Browse the repository at this point in the history
* Update Node, flake8, syrupy, and poetry.

* Fix erroneous fieldset snapshot tests

* Remove TBXFORMS_ALLOW_HTML_LABEL, TBXFORMS_ALLOW_HTML_HELP_TEXT, and TBXFORMS_ALLOW_HTML_BUTTON and associated conditional escaping of values.
  • Loading branch information
kbayliss committed Feb 5, 2024
1 parent e06e26b commit 288b688
Show file tree
Hide file tree
Showing 50 changed files with 804 additions and 706 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Expand Up @@ -37,7 +37,7 @@ jobs:
python-version: ${{ matrix.python }}
- uses: snok/install-poetry@v1
with:
version: '1.4.1'
version: '1.7.1'
virtualenvs-create: true
virtualenvs-in-project: true
- id: poetry-cache
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
@@ -1 +1 @@
16
20
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Expand Up @@ -20,7 +20,7 @@ repos:
hooks:
- id: isort
- repo: https://github.com/PyCQA/flake8
rev: 4.0.1
rev: 5.0.4
hooks:
- id: flake8
- repo: https://github.com/python/black
Expand Down
25 changes: 20 additions & 5 deletions CONTRIBUTING.md
Expand Up @@ -8,7 +8,7 @@ We welcome all support, whether on bug reports, code, design, reviews, tests, do

### Installation

With Python 3.8 or up, Node 16, [pre-commit](https://pre-commit.com/) and [Poetry 1.4.1](https://python-poetry.org/docs/#installing-with-the-official-installer)
With Python 3.8 or up, Node 20, [pre-commit](https://pre-commit.com/), and [Poetry 1.7.1](https://python-poetry.org/docs/#installing-with-the-official-installer)

```bash
git clone git@github.com:torchbox/tbxforms.git
Expand All @@ -18,16 +18,31 @@ pre-commit install
npm install
```

### Python testing
### Testing

Run the Python tests with `poetry run pytest`.
This project uses [pytest 7.0.x](https://docs.pytest.org/en/7.0.x/) and [tox](https://github.com/tox-dev/tox) for backend testing.

If your changes cause snapshot tests to fail, verify that the changes you have caused are expected. Update the snapshots with `poetry run pytest --snapshot-update`.
Generally you should use `tox`, though for quick testing during development you may want to just run `pytest` for ease.

#### Run tests using single package versions

`poetry run pytest` will run tests in whatever Python/package versions you have activated/installed.

#### Run tests against all supported package versions

`poetry run tox` will run tests against our supported package matrix.

#### Updating snapshots

If your changes cause the snapshot tests to fail:

1. Verify that the changes you have caused are expected - don't just blindly update the snapshots, they're there for a reason.
2. Run `poetry run pytest --snapshot-update` to update the snapshots.

## Publishing

1. `pre-commit` - run linters
2. `pytest` - run backend tests
2. `poetry run tox` - run backend tests against our supported package matrix.
3. Bump project version in pyproject.toml and package.json
4. Update CHANGELOG headings (add a new heading beneath the "Unreleased" heading)
5. `poetry lock --no-update` - Lock python packages
Expand Down
11 changes: 0 additions & 11 deletions README.md
Expand Up @@ -336,17 +336,6 @@ Layout(

## Customising behaviour

### Allow HTML markup within labels and help text

Markup within labels and help text is disabled by default, though can be
enabled via:

```python
TBXFORMS_ALLOW_HTML_LABEL = False
TBXFORMS_ALLOW_HTML_HELP_TEXT = False
TBXFORMS_ALLOW_HTML_BUTTON = False
```

### Change the default label and legend classes

Possible values for the `label_size` and `legend_size`:
Expand Down
655 changes: 300 additions & 355 deletions poetry.lock

Large diffs are not rendered by default.

11 changes: 5 additions & 6 deletions pyproject.toml
Expand Up @@ -7,7 +7,6 @@ authors = [
]
license = "BSD-2-Clause"
readme = "README.md"
homepage = ""
repository = "https://github.com/torchbox/tbxforms/"
classifiers = [
"Development Status :: 3 - Alpha",
Expand Down Expand Up @@ -66,14 +65,14 @@ pre-commit = "2.15.0"
beautifulsoup4 = ">=4.8,<4.10.0"
coverage = "6.1.1"
pymdown-extensions = "9.0"
syrupy = "4.0.1"
syrupy = "4.6.0"
tox = ">=4.4,<4.5"

# Linters etc.
black = "22.3.0"
black = "22.3.0" # Match version in .pre-commit-config
detect-secrets = "~0.13"
flake8 = "5.0.4"
isort = "5.10.1"
flake8 = "5.0.4" # Match version in .pre-commit-config
isort = "5.12.0" # Match version in .pre-commit-config
djlint = "1.23.3"

# Testing
Expand Down Expand Up @@ -101,5 +100,5 @@ extension = "html"
profile = "django"

[build-system]
requires = ["poetry-core==1.5.1"]
requires = ["poetry-core==1.8.1"]
build-backend = "poetry.core.masonry.api"
23 changes: 0 additions & 23 deletions tbxforms/forms.py
@@ -1,7 +1,5 @@
from django import forms as django_forms
from django.apps import apps
from django.conf import settings
from django.utils.html import conditional_escape

from tbxforms.fields import DateInputField
from tbxforms.helper import FormHelper
Expand Down Expand Up @@ -31,27 +29,6 @@ def __init__(self, *args, **kwargs):
self.helper.label_size = Size.MEDIUM
self.helper.legend_size = Size.MEDIUM

# Escape HTML within `label` and `help_text` unless it's set to allow.
# NB. Also see https://github.com/torchbox/tbxforms/blob/main/tbxforms/layout/buttons.py#L102 # noqa: E501
for field_name, field in self.fields.items():
if all(
[
field.label,
not getattr(settings, "TBXFORMS_ALLOW_HTML_LABEL", False),
]
):
field.label = conditional_escape(field.label)

if all(
[
field.help_text,
not getattr(
settings, "TBXFORMS_ALLOW_HTML_HELP_TEXT", False
),
]
):
field.help_text = conditional_escape(field.help_text)


if "FormBuilder" in locals():

Expand Down
16 changes: 2 additions & 14 deletions tbxforms/layout/buttons.py
@@ -1,6 +1,3 @@
from django.conf import settings
from django.utils.html import conditional_escape

from crispy_forms.layout import BaseInput


Expand Down Expand Up @@ -97,21 +94,12 @@ def warning(cls, name, value, disabled=False, css_class="", **kwargs):
)

def __init__(self, name, value, disabled=False, css_class="", **kwargs):
self.css_class = css_class

if disabled:
kwargs["disabled"] = "disabled"
kwargs["aria-disabled"] = "true"

# Escape HTML within button `value`'s unless it's set to allow.
# NB. Also see https://github.com/torchbox/tbxforms/blob/main/tbxforms/forms.py#L39 # noqa: E501
if all(
[
value,
not getattr(settings, "TBXFORMS_ALLOW_HTML_BUTTON", False),
]
):
value = conditional_escape(value)

self.css_class = css_class
super().__init__(name, value, **kwargs)


Expand Down
34 changes: 13 additions & 21 deletions tests/forms.py
Expand Up @@ -4,25 +4,17 @@
from tbxforms.fields import DateInputField
from tbxforms.forms import TbxFormsMixin
from tbxforms.layout import (
Button,
Field,
Fieldset,
Layout,
)


class ButtonForm(TbxFormsMixin, forms.Form):
# A "([factory], [factory_args])" tuple specifies the button to display
button_spec = (Button.primary, ("name", "Title"))

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper.layout = Layout(
self.button_spec[0](*self.button_spec[1]),
)
class BaseTestForm(TbxFormsMixin, forms.Form):
pass


class CheckboxForm(TbxFormsMixin, forms.Form):
class CheckboxForm(BaseTestForm):
accept = forms.BooleanField(
label="I accept the terms of service",
help_text="Please read the terms of service.",
Expand All @@ -36,7 +28,7 @@ def __init__(self, *args, **kwargs):
)


class CheckboxesForm(TbxFormsMixin, forms.Form):
class CheckboxesForm(BaseTestForm):
method = forms.ChoiceField(
choices=(
("email", "Email"),
Expand All @@ -56,7 +48,7 @@ def __init__(self, *args, **kwargs):
)


class CheckboxesChoiceForm(TbxFormsMixin, forms.Form):
class CheckboxesChoiceForm(BaseTestForm):
METHODS = (
Choice("email", "Email"),
Choice(
Expand All @@ -83,7 +75,7 @@ def __init__(self, *args, **kwargs):
)


class DateInputForm(TbxFormsMixin, forms.Form):
class DateInputForm(BaseTestForm):
date = DateInputField(
label="When was your passport issued?",
help_text="For example, 12 11 2007",
Expand All @@ -97,7 +89,7 @@ def __init__(self, *args, **kwargs):
)


class FileUploadForm(TbxFormsMixin, forms.Form):
class FileUploadForm(BaseTestForm):
file = forms.FileField(
label="Upload a file",
help_text="Select the CSV file to upload.",
Expand All @@ -113,7 +105,7 @@ def __init__(self, *args, **kwargs):
)


class RadiosForm(TbxFormsMixin, forms.Form):
class RadiosForm(BaseTestForm):
method = forms.ChoiceField(
choices=(
("email", "Email"),
Expand All @@ -133,7 +125,7 @@ def __init__(self, *args, **kwargs):
)


class RadiosChoiceForm(TbxFormsMixin, forms.Form):
class RadiosChoiceForm(BaseTestForm):
METHODS = (
Choice("email", "Email", hint="Do not give a work email address"),
Choice("phone", "Phone", divider="Or"),
Expand All @@ -155,7 +147,7 @@ def __init__(self, *args, **kwargs):
)


class SelectForm(TbxFormsMixin, forms.Form):
class SelectForm(BaseTestForm):
method = forms.ChoiceField(
choices=(
("", "Choose"),
Expand All @@ -176,7 +168,7 @@ def __init__(self, *args, **kwargs):
)


class TextInputForm(TbxFormsMixin, forms.Form):
class TextInputForm(BaseTestForm):
name = forms.CharField(
label="Name",
help_text="Help text",
Expand All @@ -190,7 +182,7 @@ def __init__(self, *args, **kwargs):
)


class TextareaForm(TbxFormsMixin, forms.Form):
class TextareaForm(BaseTestForm):
description = forms.CharField(
label="Description",
widget=forms.Textarea,
Expand All @@ -205,7 +197,7 @@ def __init__(self, *args, **kwargs):
)


class FieldsetForm(TbxFormsMixin, forms.Form):
class FieldsetForm(BaseTestForm):
name = forms.CharField(label="Name")
email = forms.CharField(label="Email")

Expand Down
@@ -0,0 +1,3 @@
<button name="name"
class="extra-css-class tbxforms-button tbxforms-button--secondary"
id="button-id-name">Title</button>
@@ -0,0 +1,3 @@
<button name="name"
class="extra-css-class tbxforms-button tbxforms-button--warning"
id="button-id-name">Title</button>
@@ -0,0 +1,3 @@
<button name="name"
class=" tbxforms-button tbxforms-button--secondary"
id="new_id">Title</button>
@@ -0,0 +1,3 @@
<button name="name"
class=" tbxforms-button tbxforms-button--warning"
id="new_id">Title</button>
@@ -0,0 +1,5 @@
<button name="name"
class=" tbxforms-button tbxforms-button--secondary"
id="button-id-name"
aria-disabled="true"
disabled="disabled">Title</button>
@@ -0,0 +1,5 @@
<button name="name"
class=" tbxforms-button tbxforms-button--warning"
id="button-id-name"
aria-disabled="true"
disabled="disabled">Title</button>
@@ -0,0 +1,4 @@
<button name="name"
class=" tbxforms-button tbxforms-button--secondary"
id="button-id-name"
key="value">Title</button>
@@ -0,0 +1,4 @@
<button name="name"
class=" tbxforms-button tbxforms-button--warning"
id="button-id-name"
key="value">Title</button>
@@ -0,0 +1,5 @@
<button name="name"
class=" tbxforms-button tbxforms-button--primary"
id="button-id-name">
<strong>Value</strong>
</button>
@@ -0,0 +1,5 @@
<button name="name"
class=" tbxforms-button tbxforms-button--secondary"
id="button-id-name">
<strong>Value</strong>
</button>
@@ -0,0 +1,5 @@
<button name="name"
class=" tbxforms-button tbxforms-button--warning"
id="button-id-name">
<strong>Value</strong>
</button>
@@ -0,0 +1,3 @@
<button name="name"
class=" tbxforms-button tbxforms-button--primary"
id="button-id-name">&lt;strong&gt;Value&lt;/strong&gt;</button>
@@ -0,0 +1,3 @@
<button name="name"
class=" tbxforms-button tbxforms-button--secondary"
id="button-id-name">&lt;strong&gt;Value&lt;/strong&gt;</button>
@@ -0,0 +1,3 @@
<button name="name"
class=" tbxforms-button tbxforms-button--warning"
id="button-id-name">&lt;strong&gt;Value&lt;/strong&gt;</button>
@@ -1,5 +1,5 @@
<form class="tbxforms" method="post">
<fieldset class="tbxforms-form-group tbxforms-fieldset">
<fieldset class="tbxforms-form-group tbxforms-fieldset" key="value">
<legend class="tbxforms-fieldset__legend">Contact</legend>
<div id="div_id_name" class="tbxforms-form-group">
<label for="id_name" class="tbxforms-label tbxforms-label--m">Name</label>
Expand Down
@@ -1,6 +1,6 @@
<form class="tbxforms" method="post">
<fieldset class="tbxforms-form-group tbxforms-fieldset">
<legend class="tbxforms-fieldset__legend">Contact</legend>
<legend class="tbxforms-fieldset__legend tbxforms-fieldset__legend--l">Contact</legend>
<div id="div_id_name" class="tbxforms-form-group">
<label for="id_name" class="tbxforms-label tbxforms-label--m">Name</label>
<input type="text"
Expand Down
@@ -1,5 +1,5 @@
<form class="tbxforms" method="post">
<fieldset class="tbxforms-form-group tbxforms-fieldset">
<fieldset class="tbxforms-form-group tbxforms-fieldset extra-css-class">
<legend class="tbxforms-fieldset__legend">Contact</legend>
<div id="div_id_name" class="tbxforms-form-group">
<label for="id_name" class="tbxforms-label tbxforms-label--m">Name</label>
Expand Down

0 comments on commit 288b688

Please sign in to comment.