mamweb/galerie/tests.py
LEdoian 1f499a00a1 Veliké přejmenovávání [WIP]
Neříkám, že to funguje, ale říkám, že mi běží netriviální testy :-)
Chybí:
- migrace
- přejmenovat templates
2025-12-19 07:06:34 +00:00

140 lines
5.7 KiB
Python

from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.test import TestCase, Client, override_settings
from django.urls import reverse
from galerie.models import Galerie, Soubor
from soustredeni.models import Soustredeni
import django.contrib.auth.models as auth
import personalni.models as pers
import tvorba.models as tv
from contextlib import ExitStack
from pathlib import Path
import shutil
import tempfile
# NOTE: Existují metody, jak si pořídit kontext: https://docs.python.org/3/library/unittest.html#unittest.TestCase.enterClassContext
# Nepoužíváme je, protože jsem nepřišlo na to, jak je pak použít v `@override_settings(MEDIA_ROOT=media_dir)`
# Ref: https://stackoverflow.com/a/2269295
tempdir = tempfile.TemporaryDirectory(prefix='mamweb_test')
media_dir = Path(tempdir.name) / 'media'
class GalerieTests(TestCase):
@classmethod
def setUpTestData(cls):
org_perm = auth.Permission.objects.get(content_type=ContentType.objects.get_for_model(auth.User), codename='org')
resitel_perm = auth.Permission.objects.get(content_type=ContentType.objects.get_for_model(auth.User), codename='resitel')
r = tv.Rocnik.objects.create(rocnik=42, prvni_rok=1970)
cls.sous_a = Soustredeni.objects.create(rocnik=r)
cls.sous_b = Soustredeni.objects.create(rocnik=r)
cls.neucastnik = pers.Resitel.objects.create(osoba=pers.Osoba.objects.create(user=auth.User.objects.create_user(username='ne')))
cls.neucastnik.osoba.user.user_permissions.add(resitel_perm)
cls.ucastnik_a = pers.Resitel.objects.create(osoba=pers.Osoba.objects.create(user=auth.User.objects.create_user(username='ua')))
cls.ucastnik_a.osoba.user.user_permissions.add(resitel_perm)
cls.sous_a.ucastnici.add(cls.ucastnik_a)
cls.ucastnik_b = pers.Resitel.objects.create(osoba=pers.Osoba.objects.create(user=auth.User.objects.create_user(username='ub')))
cls.ucastnik_b.osoba.user.user_permissions.add(resitel_perm)
cls.sous_b.ucastnici.add(cls.ucastnik_b)
cls.org = pers.Organizator.objects.create(osoba=pers.Osoba.objects.create(user=auth.User.objects.create_user(username='o', is_staff=True)))
cls.org.osoba.user.user_permissions.add(org_perm)
def setUp(self):
media_dir.mkdir()
def tearDown(self):
shutil.rmtree(media_dir)
@classmethod
def tearDownClass(cls):
super().tearDownClass()
tempdir.cleanup()
# TODO: tohle není moc unit test. Správnější by bylo mít polopřipravené
# věci (sous s galerií, sous bez galerie, sous se špatně uspořádanými
# galeriemi ap.) a dedikované testy na jednotlivé úkony. Ale teď jsem to
# začalo psát takhle a chci to nejdřív dopsat a commitnout, takže pokud to
# zapomenu rozstřelit na menší, tak to takhle zůstane…
@override_settings(MEDIA_ROOT=media_dir)
def test_vyrobeni_galerii_k_sousu(self):
"""Vyrobí strukturu galerií odpovídající sousové běžné struktuře pomocí příslušných views"""
org_client = Client()
org_client.force_login(self.org.osoba.user)
resp = org_client.get(reverse('galerie_nova', kwargs={'soustredeni': self.sous_a.id, 'galerie': 0}))
self.assertEqual(resp.status_code, 200)
tf = Path(settings.BASE_DIR) / 'galerie' / 'testfiles'
filenames_pa = [
tf / 'kod_emoji.jpg',
tf / 'metal.jpg',
tf / 'ohno_small.jpg',
]
filenames_so = [
tf / 'pf2020_small.jpg',
]
resp = org_client.post(
reverse('galerie_nova', kwargs={'soustredeni': self.sous_a.id, 'galerie': 0}),
data={'nazev': 'Top galerie k sousu A'},
follow=True,
)
self.assertEqual(resp.status_code, 200)
# Teď je kind-of těžké kliknout na „přidat novou podgalerii“, protože ten odkaz je někde v HTML vyrenderovaný templatem.
# Ale můžeme vytáhnout pk galerie z kontextu
top_gal = resp.context['galerie']
self.assertIsInstance(top_gal, Galerie)
# Záměrně vyrobíme nejdřív sobotní a pak páteční galerii, ať je pak můžeme prohodit
with ExitStack() as stack:
files = [stack.enter_context(open(fn, 'rb')) for fn in filenames_so]
resp = org_client.post(
reverse('galerie_nova', kwargs={'soustredeni': self.sous_a.id, 'galerie': top_gal.pk}),
data={'nazev': 'Sobota', 'obr': files},
follow=True,
)
self.assertEqual(resp.status_code, 200)
so_gal = resp.context['galerie']
self.assertIsInstance(so_gal, Galerie)
with ExitStack() as stack:
files = [stack.enter_context(open(fn, 'rb')) for fn in filenames_pa]
resp = org_client.post(
reverse('galerie_nova', kwargs={'soustredeni': self.sous_a.id, 'galerie': top_gal.pk}),
data={'nazev': 'Pátek', 'obr': files},
follow=True,
)
self.assertEqual(resp.status_code, 200)
pa_gal = resp.context['galerie']
self.assertIsInstance(pa_gal, Galerie)
self.assertGreater(pa_gal.poradi, so_gal.poradi)
# Dokonce i tušíme, jaká ta pořadí jsou
# NOTE: pokud tohle začne failovat, tak je asi safe to smazat.
self.assertEqual(pa_gal.poradi, 2)
self.assertEqual(so_gal.poradi, 1)
# Teď je prohodíme:
# NOTE: použití metody PATCH by tady prošlo, protože nekontrolujeme,
# jaká metoda se používá. Ale dokud simulujeme orga na webu s odkazy
# (`<a>`), tak použijeme GET.
resp = org_client.get(
reverse('galerie_doleva', kwargs={'soustredeni': self.sous_a.id, 'galerie': top_gal.pk, 'subgalerie': pa_gal.pk}),
follow=True,
)
self.assertEqual(resp.status_code, 200)
resp = org_client.get(
reverse('galerie_doprava', kwargs={'soustredeni': self.sous_a.id, 'galerie': top_gal.pk, 'subgalerie': so_gal.pk}),
follow=True,
)
self.assertEqual(resp.status_code, 200)
# Změnil se stav
pa_gal.refresh_from_db()
so_gal.refresh_from_db()
self.assertLess(pa_gal.poradi, so_gal.poradi)
self.assertEqual(pa_gal.poradi, 1)
self.assertEqual(so_gal.poradi, 2)