mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-10-10 14:52:53 +00:00
Port to Django 5.2 (#635)
* Port to Django 5.2 * Pin pluggy to 1.2.0 Any newer and the mystery importlib metadata error appears. Weird! >_> * Update for premailer changed default * Update view logic for is_ajax being changed to a template context processor * Port a few more tests to pytest proper Having two distinct test flavours is giving me a headache * Version 1 dockerfile Makes a VERY big image, I suspect we can optimise this a lot... * Optimise dockerfile a little lot a bit * fix(users): change logout link to POST request * fix(tests): fix some syntax errors in test code still got lots of failed tests :( * fix: replace deprecated Django APIs * ci: update Dockerfile * ci: update Dockerfile * fix(dependencies+tests): update EoL/vulnerable dependencies and improve test stability * Upgrade Python from 3.10 to 3.12 * Update frontend dependencies, replace node-sass with sass * chore(logging): ignore dangling obj reference warning from pypdf * ci: update compose.yml for prod deployment - Add Nginx as a reverse proxy - Add cert-selfsign.sh for generating self-signed certificates - Add certbot-issue.sh for Let's Encrypt certificate issuance and renewal - Add cron-install.sh and cron-uninstall.sh for system cron management - Add .env.example as an environment variable template * style: reformat code * ci: add more sleep trying to pass tests * ci: ignore browser-based tests during ci testing * fix: create home for the new user during Dockerfile building * chore: remove heroku conf file * fix: RIGS not franken anymore * fix: restore is_ajax as a boolean and split out the context processor * test: remove Selenium interaction tests and their CI workarounds * fix: harden production settings (CSRF origins, env casts, ADMINS) and drop dead debug toolbar code * deploy: serve static files from nginx, pin PGDATA, and make cert scripts loud on failure * build: switch .dockerignore to an allowlist * build: drop unused dependencies, soft-pin the rest and target Python 3.14 * build: move image to Python 3.14 / Node 24 and force DEBUG off * ci: add dependabot config for uv, npm, docker and actions * build: narrow Sass deprecation silencing to @import and require Node 24 * build: provide placeholder env for collectstatic now that DEBUG is off in the image * deploy: add plain-HTTP nginx config for local development and use it in compose * deploy: remove self-signed cert script * build: make the image multi-arch with official node and python base images * ci: lint and test on PRs, build the image on PRs and push it to GHCR on master * docs: add local running and sample data instructions * fix: report a form error instead of crashing when big power has no Power MIC * fix: upgrade pypdf and urllib3 to patched releases * fix: apply non-breaking npm audit fixes * fix: strip whitespace in ALLOWED_HOSTS and drop misleading HSTS preload * deploy: add a pyrigs healthcheck and make nginx wait for it * build: pin the uv image version * fix: correct the check-in person picker condition and use BeautifulSoup's string argument * refactor: replace unique_together with UniqueConstraint * build: replace pycodestyle with ruff and fix what it found Removes unused imports and variables, and fixes a few real problems it surfaced: - EventCheckIn.active() referenced an undefined name and raised NameError; it now returns whether the check-in has no end time - RIGS.admin defined EventChecklistAdmin twice; the second is now PowerTestRecordAdmin - RIGS/tests/conftest.py used date/timedelta without importing them - the signal-registering imports in apps.py are kept with noqa pycodestyle config in setup.cfg is dropped. * style: format the codebase with ruff * style: normalise line endings, trailing whitespace and end-of-file newlines * ci: run ruff and file hygiene through prek, and document it --------- Co-authored-by: Hang <me@hangxu.me> Co-authored-by: Joe Banks <joe@jb3.dev>
This commit is contained in:
@@ -5,7 +5,6 @@ from datetime import date
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.test import TestCase
|
||||
from django.test.utils import override_settings
|
||||
from django.utils.safestring import SafeText
|
||||
from RIGS.templatetags.markdown_tags import markdown_filter
|
||||
from django.urls import reverse, reverse_lazy
|
||||
@@ -13,7 +12,8 @@ from django.utils import timezone
|
||||
from pytest_django.asserts import assertRedirects, assertNotContains, assertContains
|
||||
|
||||
from PyRIGS.tests.base import assert_times_almost_equal, assert_oembed, login
|
||||
from RIGS import models
|
||||
from django.forms.models import model_to_dict
|
||||
from RIGS import forms, models
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
@@ -21,8 +21,9 @@ pytestmark = pytest.mark.django_db
|
||||
class TestAdminMergeObjects(TestCase):
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
cls.profile = models.Profile.objects.create(username="testuser1", email="1@test.com", is_superuser=True,
|
||||
is_active=True, is_staff=True)
|
||||
cls.profile = models.Profile.objects.create(
|
||||
username="testuser1", email="1@test.com", is_superuser=True, is_active=True, is_staff=True
|
||||
)
|
||||
cls.persons = {
|
||||
1: models.Person.objects.create(name="Person 1"),
|
||||
2: models.Person.objects.create(name="Person 2"),
|
||||
@@ -42,28 +43,44 @@ class TestAdminMergeObjects(TestCase):
|
||||
}
|
||||
|
||||
cls.events = {
|
||||
1: models.Event.objects.create(name="TE E1", start_date=date.today(), person=cls.persons[1],
|
||||
organisation=cls.organisations[3], venue=cls.venues[2]),
|
||||
2: models.Event.objects.create(name="TE E2", start_date=date.today(), person=cls.persons[2],
|
||||
organisation=cls.organisations[2], venue=cls.venues[3]),
|
||||
3: models.Event.objects.create(name="TE E3", start_date=date.today(), person=cls.persons[3],
|
||||
organisation=cls.organisations[1], venue=cls.venues[1]),
|
||||
4: models.Event.objects.create(name="TE E4", start_date=date.today(), person=cls.persons[3],
|
||||
organisation=cls.organisations[3], venue=cls.venues[3]),
|
||||
1: models.Event.objects.create(
|
||||
name="TE E1",
|
||||
start_date=date.today(),
|
||||
person=cls.persons[1],
|
||||
organisation=cls.organisations[3],
|
||||
venue=cls.venues[2],
|
||||
),
|
||||
2: models.Event.objects.create(
|
||||
name="TE E2",
|
||||
start_date=date.today(),
|
||||
person=cls.persons[2],
|
||||
organisation=cls.organisations[2],
|
||||
venue=cls.venues[3],
|
||||
),
|
||||
3: models.Event.objects.create(
|
||||
name="TE E3",
|
||||
start_date=date.today(),
|
||||
person=cls.persons[3],
|
||||
organisation=cls.organisations[1],
|
||||
venue=cls.venues[1],
|
||||
),
|
||||
4: models.Event.objects.create(
|
||||
name="TE E4",
|
||||
start_date=date.today(),
|
||||
person=cls.persons[3],
|
||||
organisation=cls.organisations[3],
|
||||
venue=cls.venues[3],
|
||||
),
|
||||
}
|
||||
|
||||
def setUp(self):
|
||||
self.profile.set_password('testuser')
|
||||
self.profile.set_password("testuser")
|
||||
self.profile.save()
|
||||
self.assertTrue(self.client.login(username=self.profile.username, password='testuser'))
|
||||
self.assertTrue(self.client.login(username=self.profile.username, password="testuser"))
|
||||
|
||||
def test_merge_confirmation(self):
|
||||
change_url = reverse('admin:RIGS_venue_changelist')
|
||||
data = {
|
||||
'action': 'merge',
|
||||
'_selected_action': [str(val.pk) for key, val in self.venues.items()]
|
||||
|
||||
}
|
||||
change_url = reverse("admin:RIGS_venue_changelist")
|
||||
data = {"action": "merge", "_selected_action": [str(val.pk) for key, val in self.venues.items()]}
|
||||
response = self.client.post(change_url, data, follow=True)
|
||||
|
||||
self.assertContains(response, "The following objects will be merged")
|
||||
@@ -71,23 +88,25 @@ class TestAdminMergeObjects(TestCase):
|
||||
self.assertContains(response, venue.name)
|
||||
|
||||
def test_merge_no_master(self):
|
||||
change_url = reverse('admin:RIGS_venue_changelist')
|
||||
data = {'action': 'merge',
|
||||
'_selected_action': [str(val.pk) for key, val in self.venues.items()],
|
||||
'post': 'yes',
|
||||
}
|
||||
change_url = reverse("admin:RIGS_venue_changelist")
|
||||
data = {
|
||||
"action": "merge",
|
||||
"_selected_action": [str(val.pk) for key, val in self.venues.items()],
|
||||
"post": "yes",
|
||||
}
|
||||
response = self.client.post(change_url, data, follow=True)
|
||||
|
||||
self.assertContains(response, "An error occured")
|
||||
|
||||
def test_venue_merge(self):
|
||||
change_url = reverse('admin:RIGS_venue_changelist')
|
||||
change_url = reverse("admin:RIGS_venue_changelist")
|
||||
|
||||
data = {'action': 'merge',
|
||||
'_selected_action': [str(self.venues[1].pk), str(self.venues[2].pk)],
|
||||
'post': 'yes',
|
||||
'master': self.venues[1].pk
|
||||
}
|
||||
data = {
|
||||
"action": "merge",
|
||||
"_selected_action": [str(self.venues[1].pk), str(self.venues[2].pk)],
|
||||
"post": "yes",
|
||||
"master": self.venues[1].pk,
|
||||
}
|
||||
|
||||
response = self.client.post(change_url, data, follow=True)
|
||||
self.assertContains(response, "Objects successfully merged")
|
||||
@@ -110,13 +129,14 @@ class TestAdminMergeObjects(TestCase):
|
||||
self.assertEqual(updatedEvent.venue, self.venues[1])
|
||||
|
||||
def test_person_merge(self):
|
||||
change_url = reverse('admin:RIGS_person_changelist')
|
||||
change_url = reverse("admin:RIGS_person_changelist")
|
||||
|
||||
data = {'action': 'merge',
|
||||
'_selected_action': [str(self.persons[1].pk), str(self.persons[2].pk)],
|
||||
'post': 'yes',
|
||||
'master': self.persons[1].pk
|
||||
}
|
||||
data = {
|
||||
"action": "merge",
|
||||
"_selected_action": [str(self.persons[1].pk), str(self.persons[2].pk)],
|
||||
"post": "yes",
|
||||
"master": self.persons[1].pk,
|
||||
}
|
||||
|
||||
response = self.client.post(change_url, data, follow=True)
|
||||
self.assertContains(response, "Objects successfully merged")
|
||||
@@ -139,13 +159,14 @@ class TestAdminMergeObjects(TestCase):
|
||||
self.assertEqual(updatedEvent.person, self.persons[1])
|
||||
|
||||
def test_organisation_merge(self):
|
||||
change_url = reverse('admin:RIGS_organisation_changelist')
|
||||
change_url = reverse("admin:RIGS_organisation_changelist")
|
||||
|
||||
data = {'action': 'merge',
|
||||
'_selected_action': [str(self.organisations[1].pk), str(self.organisations[2].pk)],
|
||||
'post': 'yes',
|
||||
'master': self.organisations[1].pk
|
||||
}
|
||||
data = {
|
||||
"action": "merge",
|
||||
"_selected_action": [str(self.organisations[1].pk), str(self.organisations[2].pk)],
|
||||
"post": "yes",
|
||||
"master": self.organisations[1].pk,
|
||||
}
|
||||
|
||||
response = self.client.post(change_url, data, follow=True)
|
||||
self.assertContains(response, "Objects successfully merged")
|
||||
@@ -171,31 +192,33 @@ class TestAdminMergeObjects(TestCase):
|
||||
class TestInvoiceDelete(TestCase):
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
cls.profile = models.Profile.objects.create(username="testuser1", email="1@test.com", is_superuser=True,
|
||||
is_active=True, is_staff=True)
|
||||
cls.vatrate = models.VatRate.objects.create(start_at='2014-03-05', rate=0.20, comment='test1')
|
||||
cls.profile = models.Profile.objects.create(
|
||||
username="testuser1", email="1@test.com", is_superuser=True, is_active=True, is_staff=True
|
||||
)
|
||||
cls.vatrate = models.VatRate.objects.create(start_at="2014-03-05", rate=0.20, comment="test1")
|
||||
cls.events = {
|
||||
1: models.Event.objects.create(name="TE E1", start_date=date.today()),
|
||||
2: models.Event.objects.create(name="TE E2", start_date=date.today())
|
||||
2: models.Event.objects.create(name="TE E2", start_date=date.today()),
|
||||
}
|
||||
|
||||
cls.invoices = {
|
||||
1: models.Invoice.objects.create(event=cls.events[1]),
|
||||
2: models.Invoice.objects.create(event=cls.events[2])
|
||||
2: models.Invoice.objects.create(event=cls.events[2]),
|
||||
}
|
||||
|
||||
cls.payments = {
|
||||
1: models.Payment.objects.create(invoice=cls.invoices[1], date=date.today(), amount=12.34,
|
||||
method=models.Payment.CASH)
|
||||
1: models.Payment.objects.create(
|
||||
invoice=cls.invoices[1], date=date.today(), amount=12.34, method=models.Payment.CASH
|
||||
)
|
||||
}
|
||||
|
||||
def setUp(self):
|
||||
self.profile.set_password('testuser')
|
||||
self.profile.set_password("testuser")
|
||||
self.profile.save()
|
||||
self.assertTrue(self.client.login(username=self.profile.username, password='testuser'))
|
||||
self.assertTrue(self.client.login(username=self.profile.username, password="testuser"))
|
||||
|
||||
def test_invoice_delete_allowed(self):
|
||||
request_url = reverse('invoice_delete', kwargs={'pk': self.invoices[2].pk})
|
||||
request_url = reverse("invoice_delete", kwargs={"pk": self.invoices[2].pk})
|
||||
|
||||
response = self.client.get(request_url, follow=True)
|
||||
self.assertContains(response, "Are you sure")
|
||||
@@ -210,7 +233,7 @@ class TestInvoiceDelete(TestCase):
|
||||
self.assertRaises(ObjectDoesNotExist, models.Invoice.objects.get, pk=self.invoices[2].pk)
|
||||
|
||||
def test_invoice_delete_not_allowed(self):
|
||||
request_url = reverse('invoice_delete', kwargs={'pk': self.invoices[1].pk})
|
||||
request_url = reverse("invoice_delete", kwargs={"pk": self.invoices[1].pk})
|
||||
|
||||
response = self.client.get(request_url, follow=True)
|
||||
self.assertContains(response, "To delete an invoice, delete the payments first.")
|
||||
@@ -228,11 +251,15 @@ class TestInvoiceDelete(TestCase):
|
||||
class TestPrintPaperwork(TestCase):
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
cls.profile = models.Profile.objects.create(username="testuser1", email="1@test.com", is_superuser=True,
|
||||
is_active=True, is_staff=True)
|
||||
cls.profile = models.Profile.objects.create(
|
||||
username="testuser1", email="1@test.com", is_superuser=True, is_active=True, is_staff=True
|
||||
)
|
||||
cls.events = {
|
||||
1: models.Event.objects.create(name="TE E1", start_date=date.today(),
|
||||
description="This is an event description\nthat for a very specific reason spans two lines."),
|
||||
1: models.Event.objects.create(
|
||||
name="TE E1",
|
||||
start_date=date.today(),
|
||||
description="This is an event description\nthat for a very specific reason spans two lines.",
|
||||
),
|
||||
}
|
||||
|
||||
cls.invoices = {
|
||||
@@ -240,25 +267,25 @@ class TestPrintPaperwork(TestCase):
|
||||
}
|
||||
|
||||
def setUp(self):
|
||||
self.profile.set_password('testuser')
|
||||
self.profile.set_password("testuser")
|
||||
self.profile.save()
|
||||
self.assertTrue(self.client.login(username=self.profile.username, password='testuser'))
|
||||
self.assertTrue(self.client.login(username=self.profile.username, password="testuser"))
|
||||
|
||||
def test_print_paperwork_success(self):
|
||||
request_url = reverse('event_print', kwargs={'pk': self.events[1].pk})
|
||||
request_url = reverse("event_print", kwargs={"pk": self.events[1].pk})
|
||||
|
||||
response = self.client.get(request_url, follow=True)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_print_invoice_success(self):
|
||||
request_url = reverse('invoice_print', kwargs={'pk': self.invoices[1].pk})
|
||||
request_url = reverse("invoice_print", kwargs={"pk": self.invoices[1].pk})
|
||||
|
||||
response = self.client.get(request_url, follow=True)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
|
||||
def test_login_redirect(client, django_user_model):
|
||||
request_url = reverse('event_embed', kwargs={'pk': 1})
|
||||
request_url = reverse("event_embed", kwargs={"pk": 1})
|
||||
expected_url = f"{reverse('login_embed')}?next={request_url}"
|
||||
|
||||
# Request the page and check it redirects
|
||||
@@ -274,14 +301,14 @@ def test_login_redirect(client, django_user_model):
|
||||
|
||||
|
||||
def test_login_cookie_warning(client):
|
||||
login_url = reverse('login_embed')
|
||||
login_url = reverse("login_embed")
|
||||
response = client.post(login_url, follow=True)
|
||||
assertContains(response, "Cookies do not seem to be enabled")
|
||||
|
||||
|
||||
def test_xframe_headers(admin_client, basic_event):
|
||||
event_url = reverse('event_embed', kwargs={'pk': basic_event.pk})
|
||||
login_url = reverse('login_embed')
|
||||
event_url = reverse("event_embed", kwargs={"pk": basic_event.pk})
|
||||
login_url = reverse("login_embed")
|
||||
|
||||
response = admin_client.get(event_url, follow=True)
|
||||
with pytest.raises(KeyError):
|
||||
@@ -293,12 +320,12 @@ def test_xframe_headers(admin_client, basic_event):
|
||||
|
||||
|
||||
def test_oembed(client, basic_event):
|
||||
event_url = reverse('event_detail', kwargs={'pk': basic_event.pk})
|
||||
event_embed_url = reverse('event_embed', kwargs={'pk': basic_event.pk})
|
||||
oembed_url = reverse('event_oembed', kwargs={'pk': basic_event.pk})
|
||||
event_url = reverse("event_detail", kwargs={"pk": basic_event.pk})
|
||||
event_embed_url = reverse("event_embed", kwargs={"pk": basic_event.pk})
|
||||
oembed_url = reverse("event_oembed", kwargs={"pk": basic_event.pk})
|
||||
|
||||
alt_oembed_url = reverse('event_oembed', kwargs={'pk': 999})
|
||||
alt_event_embed_url = reverse('event_embed', kwargs={'pk': 999})
|
||||
alt_oembed_url = reverse("event_oembed", kwargs={"pk": 999})
|
||||
alt_event_embed_url = reverse("event_embed", kwargs={"pk": 999})
|
||||
|
||||
assert_oembed(alt_event_embed_url, alt_oembed_url, client, event_embed_url, event_url, oembed_url)
|
||||
|
||||
@@ -308,8 +335,8 @@ def search(client, url, found, notfound, arguments):
|
||||
query = getattr(found, argument)
|
||||
request_url = "%s?q=%s" % (reverse_lazy(url), query)
|
||||
response = client.get(request_url, follow=True)
|
||||
assertContains(response, getattr(found, 'name'))
|
||||
assertNotContains(response, getattr(notfound, 'name'))
|
||||
assertContains(response, getattr(found, "name"))
|
||||
assertNotContains(response, getattr(notfound, "name"))
|
||||
|
||||
|
||||
def test_search(admin_client):
|
||||
@@ -326,47 +353,55 @@ def test_search(admin_client):
|
||||
2: models.Venue.objects.create(name="Wrong Venue", address="2 Check Way, TS2"),
|
||||
}
|
||||
events = {
|
||||
1: models.Event.objects.create(name="Right Event", start_date=date.today(), venue=venues[1], person=persons[1],
|
||||
organisation=organisations[1]),
|
||||
2: models.Event.objects.create(name="Wrong Event", start_date=date.today(), venue=venues[2], person=persons[2],
|
||||
organisation=organisations[2]),
|
||||
1: models.Event.objects.create(
|
||||
name="Right Event",
|
||||
start_date=date.today(),
|
||||
venue=venues[1],
|
||||
person=persons[1],
|
||||
organisation=organisations[1],
|
||||
),
|
||||
2: models.Event.objects.create(
|
||||
name="Wrong Event",
|
||||
start_date=date.today(),
|
||||
venue=venues[2],
|
||||
person=persons[2],
|
||||
organisation=organisations[2],
|
||||
),
|
||||
}
|
||||
search(admin_client, 'event_archive', events[1], events[2], ['name', 'id'])
|
||||
search(admin_client, 'person_list', persons[1], persons[2], ['name', 'id', 'phone'])
|
||||
search(admin_client, 'organisation_list', organisations[1], organisations[2],
|
||||
['name', 'id', 'email'])
|
||||
search(admin_client, 'venue_list', venues[1], venues[2],
|
||||
['name', 'id', 'address'])
|
||||
search(admin_client, "event_archive", events[1], events[2], ["name", "id"])
|
||||
search(admin_client, "person_list", persons[1], persons[2], ["name", "id", "phone"])
|
||||
search(admin_client, "organisation_list", organisations[1], organisations[2], ["name", "id", "email"])
|
||||
search(admin_client, "venue_list", venues[1], venues[2], ["name", "id", "address"])
|
||||
|
||||
|
||||
def test_hs_list(admin_client, basic_event):
|
||||
request_url = reverse('hs_list')
|
||||
request_url = reverse("hs_list")
|
||||
response = admin_client.get(request_url, follow=True)
|
||||
assertContains(response, basic_event.name)
|
||||
# assertContains(response, events[2].name)
|
||||
assertContains(response, 'Create')
|
||||
assertContains(response, "Create")
|
||||
|
||||
|
||||
def review(client, profile, obj, request_url):
|
||||
time = timezone.now()
|
||||
response = client.get(reverse(request_url, kwargs={'pk': obj.pk}), follow=True)
|
||||
response = client.get(reverse(request_url, kwargs={"pk": obj.pk}), follow=True)
|
||||
obj.refresh_from_db()
|
||||
assertContains(response, 'Reviewed by')
|
||||
assertContains(response, "Reviewed by")
|
||||
assertContains(response, profile.name)
|
||||
assert_times_almost_equal(time, obj.reviewed_at)
|
||||
|
||||
|
||||
def test_ra_review(admin_client, admin_user, ra):
|
||||
review(admin_client, admin_user, ra, 'ra_review')
|
||||
review(admin_client, admin_user, ra, "ra_review")
|
||||
|
||||
|
||||
def test_checklist_review(admin_client, admin_user, checklist):
|
||||
review(admin_client, admin_user, checklist, 'ec_review')
|
||||
review(admin_client, admin_user, checklist, "ec_review")
|
||||
|
||||
|
||||
def test_ra_redirect(admin_client, admin_user, ra):
|
||||
request_url = reverse('event_ra', kwargs={'pk': ra.event.pk})
|
||||
expected_url = reverse('ra_edit', kwargs={'pk': ra.pk})
|
||||
request_url = reverse("event_ra", kwargs={"pk": ra.event.pk})
|
||||
expected_url = reverse("ra_edit", kwargs={"pk": ra.pk})
|
||||
response = admin_client.get(request_url, follow=True)
|
||||
assertRedirects(response, expected_url, status_code=302, target_status_code=200)
|
||||
|
||||
@@ -380,19 +415,19 @@ class TestMarkdownTemplateTags(TestCase):
|
||||
self.assertIsInstance(html, SafeText)
|
||||
|
||||
def test_img_strip(self):
|
||||
rml = markdown_filter(self.markdown, 'rml')
|
||||
rml = markdown_filter(self.markdown, "rml")
|
||||
self.assertNotIn("<img", rml)
|
||||
|
||||
def test_code(self):
|
||||
rml = markdown_filter(self.markdown, 'rml')
|
||||
rml = markdown_filter(self.markdown, "rml")
|
||||
self.assertIn('<font face="Courier">monospace</font>', rml)
|
||||
|
||||
def test_blockquote(self):
|
||||
rml = markdown_filter(self.markdown, 'rml')
|
||||
rml = markdown_filter(self.markdown, "rml")
|
||||
self.assertIn("<pre>\nBlock quotes", rml)
|
||||
|
||||
def test_lists(self):
|
||||
rml = markdown_filter(self.markdown, 'rml')
|
||||
rml = markdown_filter(self.markdown, "rml")
|
||||
self.assertIn("<li><para>second item</para></li>", rml) # <ol>
|
||||
self.assertIn("<li><para>that one</para></li>", rml) # <ul>
|
||||
|
||||
@@ -400,19 +435,21 @@ class TestMarkdownTemplateTags(TestCase):
|
||||
event = models.Event.objects.create(
|
||||
name="MD Print Test",
|
||||
description=self.markdown,
|
||||
start_date='2016-01-01',
|
||||
start_date="2016-01-01",
|
||||
)
|
||||
models.EventItem.objects.create(
|
||||
event=event, name="TI I1", quantity=1, cost=1.00, order=1, description="* test \n * test \n * test"
|
||||
)
|
||||
event_item = models.EventItem.objects.create(event=event, name="TI I1", quantity=1, cost=1.00, order=1, description="* test \n * test \n * test")
|
||||
user = models.Profile.objects.create(
|
||||
username='RML test',
|
||||
username="RML test",
|
||||
is_superuser=True, # Don't care about permissions
|
||||
is_active=True,
|
||||
)
|
||||
user.set_password('rmltester')
|
||||
user.set_password("rmltester")
|
||||
user.save()
|
||||
|
||||
self.assertTrue(self.client.login(username=user.username, password='rmltester'))
|
||||
response = self.client.get(reverse('event_print', kwargs={'pk': event.pk}))
|
||||
self.assertTrue(self.client.login(username=user.username, password="rmltester"))
|
||||
response = self.client.get(reverse("event_print", kwargs={"pk": event.pk}))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
# By the time we have a PDF it should be larger than the original by some margin
|
||||
# RML hard fails if something doesn't work
|
||||
@@ -425,3 +462,24 @@ class TestMarkdownTemplateTags(TestCase):
|
||||
def test_linebreaks(self):
|
||||
html = markdown_filter(self.markdown)
|
||||
self.assertIn("Itemized lists<br/>\nlook like", html)
|
||||
|
||||
|
||||
def test_ra_big_power_without_power_mic_is_a_form_error(ra):
|
||||
data = model_to_dict(ra)
|
||||
data.update(big_power=True, power_mic=None, supervisor_consulted=True)
|
||||
form = forms.EventRiskAssessmentForm(data=data, instance=ra)
|
||||
assert not form.is_valid()
|
||||
assert form.errors["power_mic"].as_data()[0].code == "power_mic_required"
|
||||
|
||||
|
||||
def test_checkin_person_picker_only_for_event_mic(client, admin_user, basic_event, django_user_model):
|
||||
other = django_user_model.objects.create_user(username="other", password="other", is_approved=True)
|
||||
basic_event.mic = admin_user
|
||||
basic_event.save()
|
||||
url = reverse("event_checkin", kwargs={"pk": basic_event.pk})
|
||||
|
||||
client.force_login(admin_user)
|
||||
assertContains(client.get(url), "selectpicker")
|
||||
|
||||
client.force_login(other)
|
||||
assertNotContains(client.get(url), "selectpicker")
|
||||
|
||||
Reference in New Issue
Block a user