From 45fcaac47d2fefd5ab764c1be88a896a2ac6be9a Mon Sep 17 00:00:00 2001 From: Philip Sargent Date: Sun, 12 Mar 2023 16:21:31 +0000 Subject: test revers() function --- core/TESTS/test_caves.py | 177 ++++++++++++++++++ core/TESTS/test_logins.py | 449 +++++++++++++++++++++++++++++++++++++++++++++ core/TESTS/test_urls.py | 149 +++++++++++++++ core/TESTS/tests.py | 17 -- core/TESTS/tests_caves.py | 177 ------------------ core/TESTS/tests_logins.py | 449 --------------------------------------------- 6 files changed, 775 insertions(+), 643 deletions(-) create mode 100644 core/TESTS/test_caves.py create mode 100644 core/TESTS/test_logins.py create mode 100644 core/TESTS/test_urls.py delete mode 100644 core/TESTS/tests_caves.py delete mode 100644 core/TESTS/tests_logins.py (limited to 'core') diff --git a/core/TESTS/test_caves.py b/core/TESTS/test_caves.py new file mode 100644 index 0000000..baa4ffa --- /dev/null +++ b/core/TESTS/test_caves.py @@ -0,0 +1,177 @@ +""" +Modified for Expo April 2021. +""" + +import re +from http import HTTPStatus + +from django.test import Client, TestCase + +from troggle.core.models.caves import Area, Cave +from troggle.core.models.troggle import Person, PersonExpedition + + +class FixtureTests(TestCase): + """These just hit the database. + They do not exercise the GET and url functions + """ + + fixtures = ["auth_users", "expo_areas", "expo_caves", "expo_exped"] + ph = r"and leads in 800m of tortuous going to" + + def setUp(self): + pass + + def tearDown(self): + pass + + def test_fix_person_loaded(self): + p = Person.objects.get(fullname="Michael Sargent") + self.assertEqual(str(p.first_name), "Michael") + + def test_fix_person_loaded(self): + pe = PersonExpedition.objects.get(pk="681") + self.assertEqual(str(pe.person.fullname), "Michael Sargent") + self.assertEqual(str(pe.expedition.year), "2019") + + def test_fix_area_loaded(self): + a = Area.objects.get(short_name="1623") + self.assertEqual(str(a.short_name), "1623") + + def test_fix_cave_loaded115(self): + c = Cave.objects.get(kataster_number="115") + self.assertEqual(str(c.description_file), "1623/115.htm") + self.assertEqual(str(c.url), "1623/115.url") # intentional + self.assertEqual(str(c.filename), "1623-115.html") + + # c.area is a 'ManyRelatedManager' object and not iterable + # self.assertEqual(str(c.[0].short_name), "1623") + + ph = self.ph + phmatch = re.search(ph, c.underground_description) + self.assertIsNotNone(phmatch, "In fixture-loaded cave, failed to find expected text: '" + ph + "'") + + def test_fix_cave_loaded284(self): + c = Cave.objects.get(kataster_number="284") + self.assertEqual(str(c.description_file), "") + self.assertEqual(str(c.url), "1623/284/284.html") + self.assertEqual(str(c.filename), "1623-284.html") + + ph = r"at a depth of 72m, there are large round blocks" + phmatch = re.search(ph, c.notes) + self.assertIsNotNone(phmatch, "In fixture-loaded cave, failed to find expected text: '" + ph + "'") + + def test_page_personexpedition(self): + response = self.client.get("/personexpedition/MichaelSargent/2019") + content = response.content.decode() + # with open('testresponse.html','w') as tr: + # tr.writelines(content) + self.assertEqual(response.status_code, HTTPStatus.OK) + for ph in [r"Michael Sargent", r"Table of all trips and surveys aligned by date"]: + phmatch = re.search(ph, content) + self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") + # Need to add a fixture so that this actually has a logbook entry and a trip/svx in it. + + +class FixturePageTests(TestCase): + """Currently nothing that runs troggle works - all do 404. Must be something in a template rendering crash? + ordinary pages are OK, and expopages and expofiles are OK, even though they come through troggle. + """ + + # The fixtures have a password hash which is compatible with plain-text password 'secretword' + fixtures = ["auth_users", "expo_areas", "expo_caves", "expo_exped"] + ph = r"and leads in 800m of tortuous going to" + + @classmethod + def setUpTestData(cls): + pass + + def setUp(self): + from django.contrib.auth.models import User + + self.user = User.objects.get(username="expotest") + + # Every test needs a client. + self.client = Client() + + def tearDown(self): + pass + + def test_fix_expedition(self): + response = self.client.get("/expedition/2019") + self.assertEqual(response.status_code, HTTPStatus.OK) + + ph = r"Michael Sargent" + + content = response.content.decode() + phmatch = re.search(ph, content) + # with open('exped-op.html', 'w') as f: + # f.write(content) + self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") + + def test_fix_personexped(self): + response = self.client.get("/personexpedition/MichaelSargent/2019") + self.assertEqual(response.status_code, HTTPStatus.OK) + + ph = r"Table of all trips and surveys aligned by date" + + content = response.content.decode() + phmatch = re.search(ph, content) + # with open('persexped-op.html', 'w') as f: + # f.write(content) + self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") + + def test_fix_person(self): + response = self.client.get("/person/MichaelSargent") + self.assertEqual(response.status_code, HTTPStatus.OK) + + ph = r"second-generation expo caver " + + content = response.content.decode() + phmatch = re.search(ph, content) + # with open('person-op.html', 'w') as f: + # f.write(content) + self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") + + def test_fix_cave_url115(self): + ph = self.ph + response = self.client.get("/1623/115.url") # yes this is intentional, see the inserted data above & fixture + self.assertEqual(response.status_code, HTTPStatus.OK) + + content = response.content.decode() + phmatch = re.search(ph, content) + self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") + + def test_fix_cave_url284(self): + response = self.client.get("/1623/284/284.html") + self.assertEqual(response.status_code, HTTPStatus.OK) + + ph = r"at a depth of 72m, there are large round blocks" + + content = response.content.decode() + phmatch = re.search(ph, content) + # with open('cave-op.html', 'w') as f: + # f.write(content) + self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") + + def test_fix_cave_bare_url115(self): + """Expect to get Page Not Found and status 404""" + ph = self.ph + ph = "Probably a mistake." + response = self.client.get("/1623/115") + self.assertEqual(response.status_code, HTTPStatus.NOT_FOUND) + + content = response.content.decode() + phmatch = re.search(ph, content) + self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") # 200 & Page Not Found + + def test_fix_cave_slug115(self): + """Expect to get Page Not Found and status 404""" + ph = self.ph + ph = "Probably a mistake." + response = self.client.get("/1623-115") + self.assertEqual(response.status_code, HTTPStatus.NOT_FOUND) + + content = response.content.decode() + phmatch = re.search(ph, content) + self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") # 200 & Page Not Found diff --git a/core/TESTS/test_logins.py b/core/TESTS/test_logins.py new file mode 100644 index 0000000..f50e292 --- /dev/null +++ b/core/TESTS/test_logins.py @@ -0,0 +1,449 @@ +""" +Originally written for CUYC +Philip Sargent (Feb.2021) + +Modified for Expo April 2021. +""" + +import pathlib +import re +from http import HTTPStatus + +from django.test import Client, TestCase + +import troggle.settings as settings +from troggle.core.models.wallets import Wallet +from troggle.core.models.troggle import Expedition + + +class DataTests(TestCase): + """These check that the NULL and NON-UNIQUE constraints are working in the database""" + + @classmethod + def setUpTestData(cls): + pass + + def setUp(self): + from django.contrib.auth.models import User + + u = User() + u.pk = 9000 + u.user_id = 8000 + u.username, u.password = "stinker", "secretword" + u.email = "philip.sargent+SP@gmail.com" + u.first_name, u.last_name = "Stinker", "Pinker" + u.save() + self.user = u + + def tearDown(self): + # self.member.delete() # must delete member before user + # self.user.delete() # horrible crash, why? + pass + + +class FixturePageTests(TestCase): + # The fixtures have a password hash which is compatible with plain-text password 'secretword' + fixtures = ["auth_users"] + + def setUp(self): + from django.contrib.auth.models import User + + self.user = User.objects.get(username="expotest") + + def tearDown(self): + pass + + def test_fix_admin_login_fail(self): + c = self.client + from django.contrib.auth.models import User + + u = User.objects.get(username="expotest") + + self.assertTrue(u.is_active, "User '" + u.username + "' is INACTIVE") + + logged_in = c.login(username=u.username, password="secretword") # fails to work if password=u.password ! + self.assertTrue(logged_in, "FAILED to login as '" + u.username + "'") + + response = c.get("/admin/") + content = response.content.decode() + # with open('admin-op.html', 'w') as f: + # f.write(content) + t = re.search(r"Troggle administration", content) + self.assertIsNone(t, "Logged in as '" + u.username + "' (not staff) but still managed to get the Admin page") + + +class PostTests(TestCase): + """Tests walletedit form""" + + fixtures = ["auth_users"] + + @classmethod + def setUpTestData(cls): + pass + + def setUp(self): + from django.contrib.auth.models import User + + self.user = User.objects.get(username="expotest") + self.client = Client() + + testyear = "2022" + wname = f"{testyear}:00" + self.testyear = testyear + w = Wallet() + w.pk = 9100 + w.fpath = str(pathlib.Path(settings.SCANS_ROOT, wname)) + w.walletname = wname + w.save() + self.wallet = w + + e = Expedition() + e.year = testyear + e.save() + self.expedition = e + + def test_file_permissions(self): + """Expect to be allowed to write to expofiles + Need to login first. + """ + c = self.client + from django.contrib.auth.models import User + + u = User.objects.get(username="expotest") + testyear = self.testyear + + self.assertTrue(u.is_active, "User '" + u.username + "' is INACTIVE") + c.login(username=u.username, password="secretword") + + for p in [settings.SCANS_ROOT, + settings.DRAWINGS_DATA / "walletjson", + settings.EXPOWEB / "documents", + settings.SURVEX_DATA / "docs" + ]: + + _test_file_path = pathlib.Path(p, "_created_by_test_suite.txt") + self.assertEqual(_test_file_path.is_file(), False) + + with open(_test_file_path, "w") as f: + f.write("test string: can we write to this directory?") + self.assertEqual(_test_file_path.is_file(), True) + _test_file_path.unlink() + + def test_scan_upload(self): + """Expect scan upload to wallet to work on any file + Need to login first. + + This upload form looks for the Cave and the Wallet, so the test fails if the database is not loaded with the cave + identified in the wallet + """ + c = self.client + from django.contrib.auth.models import User + + u = User.objects.get(username="expotest") + testyear = self.testyear + + self.assertTrue(u.is_active, "User '" + u.username + "' is INACTIVE") + c.login(username=u.username, password="secretword") + + with open("core/fixtures/test_upload_file.txt", "r") as testf: + response = self.client.post( + f"/walletedit/{testyear}:00", data={"name": "test_upload_file.txt", "uploadfiles": testf} + ) + content = response.content.decode() + self.assertEqual(response.status_code, HTTPStatus.OK) + self.assertEqual(response.status_code, HTTPStatus.OK) + with open("_test_response.html", "w") as f: + f.write(content) + for ph in [ + r"test_upload_", + rf"← {testyear}#00 →", + r"description written", + r"Plan not required", + r"edit settings or upload a file", + ]: + phmatch = re.search(ph, content) + self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") + + # # Does not use the filename Django actually uses, assumes it is unchanged. Potential bug. + # remove_file = pathlib.Path(settings.SCANS_ROOT) / f'{testyear}' / f'{testyear}#00'/ 'test_upload_file.txt' + # remove_file.unlink() + # # Undo the auto create and commit of a new wallet + # cwd = settings.DRAWINGS_DATA + # sp = subprocess.run([settings.GIT, "reset", "--hard", "master^"], cwd=cwd, capture_output=True, text=True) + # print(f'git output: {cwd}:\n # {sp.stderr=}\n # {sp.stdout=} \n # return code: {str(sp.returncode)}') + # if sp.returncode != 0: + # print(f'git output: {cwd}:\n # {sp.stderr=}\n # {sp.stdout=} \n # return code: {str(sp.returncode)}') + + def test_photo_upload(self): + """Expect photo upload to work on any file (contrary to msg on screen) + Upload into current default year. settings.PHOTOS_YEAR + Deletes file afterwards + Need to login first. + """ + c = self.client + from django.contrib.auth.models import User + + u = User.objects.get(username="expotest") + + self.assertTrue(u.is_active, "User '" + u.username + "' is INACTIVE") + c.login(username=u.username, password="secretword") + + with open("core/fixtures/test_upload_file.txt", "r") as testf: + response = self.client.post( + "/photoupload/", data={"name": "test_upload_file.txt", "renameto": "", "uploadfiles": testf} + ) + content = response.content.decode() + self.assertEqual(response.status_code, HTTPStatus.OK) + self.assertEqual(response.status_code, HTTPStatus.OK) + # with open('_test_response.html', 'w') as f: + # f.write(content) + for ph in [ + r"test_upload_", + r"Upload photos into /photos/" + str(settings.PHOTOS_YEAR), + r" you can create a new folder in your name", + r"Create new Photographer folder", + r"only photo image files are accepted", + ]: + phmatch = re.search(ph, content) + self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") + + # Does not use the filename Django actually uses, assumes it is unchanged. Potential bug. + remove_file = pathlib.Path(settings.PHOTOS_ROOT, settings.PHOTOS_YEAR) / "test_upload_file.txt" + remove_file.unlink() + + def test_photo_upload_rename(self): + """Expect photo upload to work on any file (contrary to msg on screen) + Upload into current default year. settings.PHOTOS_YEAR + Deletes file afterwards + Need to login first. + """ + c = self.client + from django.contrib.auth.models import User + + u = User.objects.get(username="expotest") + + self.assertTrue(u.is_active, "User '" + u.username + "' is INACTIVE") + c.login(username=u.username, password="secretword") + + rename = "RENAMED-FILE.JPG" + with open("core/fixtures/test_upload_file.txt", "r") as testf: + response = self.client.post( + "/photoupload/", data={"name": "test_upload_file.txt", "renameto": rename, "uploadfiles": testf} + ) + content = response.content.decode() + self.assertEqual(response.status_code, HTTPStatus.OK) + self.assertEqual(response.status_code, HTTPStatus.OK) + # with open('_test_response.html', 'w') as f: + # f.write(content) + for ph in [rename]: + phmatch = re.search(ph, content) + self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") + + # Does not use the filename Django actually uses, assumes it is unchanged. Potential bug. + remove_file = pathlib.Path(settings.PHOTOS_ROOT, settings.PHOTOS_YEAR) / rename + remove_file.unlink() + + def test_photo_folder_create(self): + """Create folder for new user + Create in current default year. settings.PHOTOS_YEAR + Deletes folder afterwards + Need to login first. + """ + c = self.client + from django.contrib.auth.models import User + + u = User.objects.get(username="expotest") + + self.assertTrue(u.is_active, "User '" + u.username + "' is INACTIVE") + c.login(username=u.username, password="secretword") + + response = self.client.post("/photoupload/", data={"photographer": "GussieFinkNottle"}) + content = response.content.decode() + self.assertEqual(response.status_code, HTTPStatus.OK) + self.assertEqual(response.status_code, HTTPStatus.OK) + # with open('_test_response.html', 'w') as f: + # f.write(content) + for ph in [r"/GussieFinkNottle/", r"Create new Photographer folder"]: + phmatch = re.search(ph, content) + self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") + + # Does not use the filename Django actually uses, assumes it is unchanged. Potential bug. + remove_dir = pathlib.Path(settings.PHOTOS_ROOT, settings.PHOTOS_YEAR) / "GussieFinkNottle" + remove_dir.rmdir() + + def test_dwg_upload_txt(self): + """Expect .pdf file to be refused upload + Need to login first. + """ + c = self.client + from django.contrib.auth.models import User + + u = User.objects.get(username="expotest") + + self.assertTrue(u.is_active, "User '" + u.username + "' is INACTIVE") + c.login(username=u.username, password="secretword") + + with open("core/fixtures/test_upload_file.pdf", "r") as testf: + response = self.client.post( + "/dwgupload/uploads", data={"name": "test_upload_file.txt", "uploadfiles": testf} + ) + content = response.content.decode() + self.assertEqual(response.status_code, HTTPStatus.OK) + t = re.search("Files refused:", content) + self.assertIsNotNone(t, 'Logged in but failed to see "Files refused:"') + + def test_dwg_upload_drawing(self): + """Expect no-suffix file to upload + Note that this skips the git commit process. That would need a new test. + Need to login first. + """ + c = self.client + from django.contrib.auth.models import User + + u = User.objects.get(username="expotest") + + self.assertTrue(u.is_active, "User '" + u.username + "' is INACTIVE") + c.login(username=u.username, password="secretword") + + with open("core/fixtures/test_upload_nosuffix", "r") as testf: + response = self.client.post( + "/dwguploadnogit/uploads", data={"name": "test_upload_nosuffix", "uploadfiles": testf} + ) + content = response.content.decode() + # with open('_test_response.html', 'w') as f: + # f.write(content) + self.assertEqual(response.status_code, HTTPStatus.OK) + for ph in [ + r"test_upload_nosuffix", + r"You cannot create folders here", + r"Creating a folder is done by a nerd", + ]: + phmatch = re.search(ph, content) + self.assertIsNotNone( + phmatch, "Expect no-suffix file to upload OK. Failed to find expected text: '" + ph + "'" + ) + + # Does not use the filename Django actually uses, assumes it is unchanged. Bug: accumulates one file with random name added each time it is run. + remove_file = pathlib.Path(settings.DRAWINGS_DATA) / "uploads" / "test_upload_nosuffix" + remove_file.unlink() + + +class ComplexLoginTests(TestCase): + """These test the login and capabilities of logged-in users, they do not use fixtures""" + + def setUp(self): + """setUp runs once for each test in this class""" + from django.contrib.auth.models import User + + u = User() + u.pk = 9000 + u.user_id = 8000 + u.username, u.password = "expotest", "secretword" + u.email = "philip.sargent+ET@gmail.com" + u.first_name, u.last_name = "ExpoTest", "Caver" + u.is_staff = True + u.is_superuser = True + + u.set_password(u.password) # This creates a new salt and thus a new key for EACH test + u.save() # vital that we save all this before attempting login + # print ('\n',u.password) + self.user = u + + def tearDown(self): + self.client.logout() # not needed as each test creates a new self.client + # self.member.delete() + ##self.user.delete() # id attribute set to None ! + pass + + # def test_login_redirect_for_non_logged_on_user(self): # need to fix this in real system + # c = self.client + # # Need to login first. Tests that we are redirected to login page if not logged in + # response = c.get('noinfo/cave-number-index') + # self.assertRedirects(response, "/login/?next=/committee/appointments/") + + def test_ordinary_login(self): + c = self.client + u = self.user + + self.assertTrue(u.is_active, "User '" + u.username + "' is INACTIVE") + + logged_in = c.login(username=u.username, password="secretword") # fails to work if password=u.password ! + self.assertTrue(logged_in, "FAILED to login as '" + u.username + "'") + + response = c.get("/accounts/login/") # defined by auth system + content = response.content.decode() + t = re.search(r"You are now logged in", content) + self.assertIsNotNone(t, "Logged in as '" + u.username + "' but failed to get 'Now you can' greeting") + + def test_authentication_login(self): + c = self.client + u = self.user + + self.assertTrue(u.is_active, "User '" + u.username + "' is INACTIVE") + + # This is weird. I thought that the user had to login before she was in the authenticated state + self.assertTrue(u.is_authenticated, "User '" + u.username + "' is NOT AUTHENTICATED before login") + + logged_in = c.login(username=u.username, password="secretword") # fails to work if password=u.password ! + self.assertTrue(logged_in, "FAILED to login as '" + u.username + "'") + + self.assertTrue(u.is_authenticated, "User '" + u.username + "' is NOT AUTHENTICATED after login") + + # c.logout() # This next test always means user is still authenticated after logout. Surely not? + # self.assertFalse(u.is_authenticated, 'User \'' + u.username + '\' is STILL AUTHENTICATED after logout') + + def test_admin_login(self): + c = self.client + u = self.user + + logged_in = c.login(username=u.username, password="secretword") # fails to work if password=u.password ! + self.assertTrue(logged_in, "FAILED to login as '" + u.username + "'") + + response = c.get("/admin/") + content = response.content.decode() + # with open('admin-op.html', 'w') as f: + # f.write(content) + t = re.search(r"Troggle database administration", content) + self.assertIsNotNone(t, "Logged in as '" + u.username + "' but failed to get the Troggle Admin page") + + def test_noinfo_login(self): + + c = self.client # inherited from TestCase + u = self.user + + logged_in = c.login(username=u.username, password="secretword") # fails if password=u.password ! + self.assertTrue(logged_in, "FAILED to login as '" + u.username + "'") + response = c.get("/stats") # a page with the Troggle menus + content = response.content.decode() + t = re.search(r"User\:expotest", content) + self.assertIsNotNone(t, "Logged in as '" + u.username + "' but failed to get 'User:expotest' heading") + + response = c.get("/noinfo/cave-number-index") + content = response.content.decode() + t = re.search(r"2001-07 Hoffnungschacht", content) + self.assertIsNotNone(t, "Logged in as '" + u.username + "' but failed to get /noinfo/ content") + + def test_user_force(self): + + c = self.client + u = self.user + + try: + c.force_login(u) + except: + self.assertIsNotNone( + None, + "Unexpected exception trying to force_login as '" + + u.username + + "' but failed (Bad Django documentation?)", + ) + + response = c.get("/stats") # a page with the Troggle menus + content = response.content.decode() + t = re.search(r"Log out", content) + self.assertIsNotNone(t, "Forced logged in as '" + u.username + "' but failed to get Log out heading") + + response = c.get("/accounts/login/") + content = response.content.decode() + t = re.search(r"You are now logged in", content) + self.assertIsNotNone(t, "Forced logged in as '" + u.username + "' but failed to get /accounts/profile/ content") diff --git a/core/TESTS/test_urls.py b/core/TESTS/test_urls.py new file mode 100644 index 0000000..df34ee6 --- /dev/null +++ b/core/TESTS/test_urls.py @@ -0,0 +1,149 @@ +""" +We are using unittest for troggle. + +Note that the database has not been parsed from the source files when these tests are run, +so any path that relies on data being in the database will fail. + +https://docs.djangoproject.com/en/dev/topics/testing/tools/ + +The code {% url THING %} or {% url THING PARAMETER %} appears a hundred times or more in the troggle/templates/ HTML template files. +This is the template synstax for +reverse('THING') +or +reverse('THING', args=[PARAMETER]) + +It is the URLS which take parameters which need understanding and testing. The reverse() which take no +parameters should be fine as this is fundamental Django stuff which will have been tested to death. + +But the reverse() function is purely syntactical, the PARAMETER is just a string which is applied to +the url. So this is not testing anything important really. See the test_url_threed() below. + +1. No tests: No parameters + +{% url "caveindex" %} +{% url "controlpanel" %} +{% url "dataissues" %} +{% url "dwgallfiles" %} +{% url "dwgupload" %} +{% url "eastings" %} +{% url "exportlogbook" %} +{% url "newcave" %} +{% url "notablepersons" %} +{% url "photoupload" %} +{% url "walletedit" %} + +Tests exist: +{% url "stats" %} +{% url "allscans" %} +{% url "survexcaveslist" %} + +2. With parameter + +{% url "caveQMs" "1623-290" %} +{% url "cavewallets" cave_id %} +{% url "dwgfilesingle" drawing.dwgpath %} +{% url "edit_cave" cave.url_parent cave.slug %} +{% url "editentrance" cave.slug ent.entrance.slug %} +{% url "editexpopage" path %} +{% url "err" title %} +{% url "expedition" 2022 %} +{% url "newentrance" cave.slug %} +{% url "survexcavessingle" cavedir %} +{% url "survexcavessingle" cavefiles.0.1 %} +{% url "svx" cavepath %} +{% url "svx" survexfile.path %} +{% url "svxlog" title %} +{% url 'caveQMs' '1623-161' %} +{% url 'image_selector' path %} +{% url 'new_image_form' path %} + +Tests exist: +{% url "threed" title %} +""" + + +todo = """These just do {% url THING %} with no parameter, we also need tests which take a parameter + +- Read all this https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Testing + +- Read all this https://realpython.com/testing-in-django-part-1-best-practices-and-examples/ + +- add 'coverage' to all tests + +- statistics also needs test when we have put data into the database + +""" + +import re +from http import HTTPStatus + +from django.test import Client, TestCase +from django.urls import reverse, path + +# class SimplePageTest(unittest.TestCase): +class URLTests(TestCase): + """These tests may appear to be redundant, but in fact they exercise different bits of code. The urls.py + dispatcher is sending these URLs view via different 'view' handlers, and they all need verifying. + """ + + @classmethod + def setUpTestData(cls): + # Set up data for the whole TestCase + # cls.foo = Foo.objects.create(bar="Test") + # Some test using self.foo in tests below.. + # read in some SQL ? + pass + + def setUp(self): + # Every test needs a client. + self.client = Client() + + def test_statistics(self): + response = self.client.get("/statistics") + self.assertEqual(response.status_code, HTTPStatus.OK) + content = response.content.decode() + ph = r"0 expeditions: 0 people, 0 caves and 0 logbook entries." + phmatch = re.search(ph, content) + self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") + + def test_stats(self): + # Needs another test with test data + response = self.client.get("/stats") + self.assertEqual(response.status_code, HTTPStatus.OK) + content = response.content.decode() + # with open('_test_response.html', 'w') as f: + # f.write(content) + ph = r"Total length: 0.0 km adding up the total for each year." + phmatch = re.search(ph, content) + self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") + + def test_url_stats(self): + """Test the {% url "stats" %} reverse resolution + path('statistics', statistics.stats, name="stats"), + path('stats', statistics.stats, name="stats"), + """ + reversed_url = reverse('stats') # NB _ must be written as - if present in name + self.assertEqual(reversed_url, "/stats") + + def test_url_allscans(self): + """Test the {% url "allscans" %} reverse resolution + path('survey_scans/', allscans, name="allscans"), # all the scans in all wallets + """ + reversed_url = reverse('allscans') # NB _ must be written as - if present in name + self.assertEqual(reversed_url, "/survey_scans/") + + def test_url_survexcaveslist(self): + """Test the {% url "allscans" %} reverse resolution + path('survexfile/caves', survex.survexcaveslist, name="survexcaveslist"), + path('survexfile/caves/', survex.survexcaveslist, name="survexcaveslist"), # auto slash not working + """ + reversed_url = reverse('survexcaveslist') # NB _ must be written as - if present in name + self.assertEqual(reversed_url, "/survexfile/caves/") + + def test_url_threed(self): + """Test the {% url "threed" %} reverse resolution + path('survexfile/.3d', survex.threed, name="threed"), + """ + reversed_url = reverse('threed', args=['zilch']) # NB _ must be written as - if present in name + self.assertEqual(reversed_url, "/survexfile/zilch.3d") + diff --git a/core/TESTS/tests.py b/core/TESTS/tests.py index fc6f12b..e5c4349 100644 --- a/core/TESTS/tests.py +++ b/core/TESTS/tests.py @@ -476,23 +476,6 @@ class PageTests(TestCase): self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") - def test_statistics(self): - response = self.client.get("/statistics") - self.assertEqual(response.status_code, HTTPStatus.OK) - content = response.content.decode() - ph = r"0 expeditions: 0 people, 0 caves and 0 logbook entries." - phmatch = re.search(ph, content) - self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") - - def test_stats(self): - # Needs another test with test data - response = self.client.get("/stats") - self.assertEqual(response.status_code, HTTPStatus.OK) - content = response.content.decode() - ph = r"Total length: 0.0 km adding up the total for each year." - phmatch = re.search(ph, content) - self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") - def test_dataissues(self): # Needs another test with test data response = self.client.get("/dataissues") diff --git a/core/TESTS/tests_caves.py b/core/TESTS/tests_caves.py deleted file mode 100644 index baa4ffa..0000000 --- a/core/TESTS/tests_caves.py +++ /dev/null @@ -1,177 +0,0 @@ -""" -Modified for Expo April 2021. -""" - -import re -from http import HTTPStatus - -from django.test import Client, TestCase - -from troggle.core.models.caves import Area, Cave -from troggle.core.models.troggle import Person, PersonExpedition - - -class FixtureTests(TestCase): - """These just hit the database. - They do not exercise the GET and url functions - """ - - fixtures = ["auth_users", "expo_areas", "expo_caves", "expo_exped"] - ph = r"and leads in 800m of tortuous going to" - - def setUp(self): - pass - - def tearDown(self): - pass - - def test_fix_person_loaded(self): - p = Person.objects.get(fullname="Michael Sargent") - self.assertEqual(str(p.first_name), "Michael") - - def test_fix_person_loaded(self): - pe = PersonExpedition.objects.get(pk="681") - self.assertEqual(str(pe.person.fullname), "Michael Sargent") - self.assertEqual(str(pe.expedition.year), "2019") - - def test_fix_area_loaded(self): - a = Area.objects.get(short_name="1623") - self.assertEqual(str(a.short_name), "1623") - - def test_fix_cave_loaded115(self): - c = Cave.objects.get(kataster_number="115") - self.assertEqual(str(c.description_file), "1623/115.htm") - self.assertEqual(str(c.url), "1623/115.url") # intentional - self.assertEqual(str(c.filename), "1623-115.html") - - # c.area is a 'ManyRelatedManager' object and not iterable - # self.assertEqual(str(c.[0].short_name), "1623") - - ph = self.ph - phmatch = re.search(ph, c.underground_description) - self.assertIsNotNone(phmatch, "In fixture-loaded cave, failed to find expected text: '" + ph + "'") - - def test_fix_cave_loaded284(self): - c = Cave.objects.get(kataster_number="284") - self.assertEqual(str(c.description_file), "") - self.assertEqual(str(c.url), "1623/284/284.html") - self.assertEqual(str(c.filename), "1623-284.html") - - ph = r"at a depth of 72m, there are large round blocks" - phmatch = re.search(ph, c.notes) - self.assertIsNotNone(phmatch, "In fixture-loaded cave, failed to find expected text: '" + ph + "'") - - def test_page_personexpedition(self): - response = self.client.get("/personexpedition/MichaelSargent/2019") - content = response.content.decode() - # with open('testresponse.html','w') as tr: - # tr.writelines(content) - self.assertEqual(response.status_code, HTTPStatus.OK) - for ph in [r"Michael Sargent", r"Table of all trips and surveys aligned by date"]: - phmatch = re.search(ph, content) - self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") - # Need to add a fixture so that this actually has a logbook entry and a trip/svx in it. - - -class FixturePageTests(TestCase): - """Currently nothing that runs troggle works - all do 404. Must be something in a template rendering crash? - ordinary pages are OK, and expopages and expofiles are OK, even though they come through troggle. - """ - - # The fixtures have a password hash which is compatible with plain-text password 'secretword' - fixtures = ["auth_users", "expo_areas", "expo_caves", "expo_exped"] - ph = r"and leads in 800m of tortuous going to" - - @classmethod - def setUpTestData(cls): - pass - - def setUp(self): - from django.contrib.auth.models import User - - self.user = User.objects.get(username="expotest") - - # Every test needs a client. - self.client = Client() - - def tearDown(self): - pass - - def test_fix_expedition(self): - response = self.client.get("/expedition/2019") - self.assertEqual(response.status_code, HTTPStatus.OK) - - ph = r"Michael Sargent" - - content = response.content.decode() - phmatch = re.search(ph, content) - # with open('exped-op.html', 'w') as f: - # f.write(content) - self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") - - def test_fix_personexped(self): - response = self.client.get("/personexpedition/MichaelSargent/2019") - self.assertEqual(response.status_code, HTTPStatus.OK) - - ph = r"Table of all trips and surveys aligned by date" - - content = response.content.decode() - phmatch = re.search(ph, content) - # with open('persexped-op.html', 'w') as f: - # f.write(content) - self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") - - def test_fix_person(self): - response = self.client.get("/person/MichaelSargent") - self.assertEqual(response.status_code, HTTPStatus.OK) - - ph = r"second-generation expo caver " - - content = response.content.decode() - phmatch = re.search(ph, content) - # with open('person-op.html', 'w') as f: - # f.write(content) - self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") - - def test_fix_cave_url115(self): - ph = self.ph - response = self.client.get("/1623/115.url") # yes this is intentional, see the inserted data above & fixture - self.assertEqual(response.status_code, HTTPStatus.OK) - - content = response.content.decode() - phmatch = re.search(ph, content) - self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") - - def test_fix_cave_url284(self): - response = self.client.get("/1623/284/284.html") - self.assertEqual(response.status_code, HTTPStatus.OK) - - ph = r"at a depth of 72m, there are large round blocks" - - content = response.content.decode() - phmatch = re.search(ph, content) - # with open('cave-op.html', 'w') as f: - # f.write(content) - self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") - - def test_fix_cave_bare_url115(self): - """Expect to get Page Not Found and status 404""" - ph = self.ph - ph = "Probably a mistake." - response = self.client.get("/1623/115") - self.assertEqual(response.status_code, HTTPStatus.NOT_FOUND) - - content = response.content.decode() - phmatch = re.search(ph, content) - self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") # 200 & Page Not Found - - def test_fix_cave_slug115(self): - """Expect to get Page Not Found and status 404""" - ph = self.ph - ph = "Probably a mistake." - response = self.client.get("/1623-115") - self.assertEqual(response.status_code, HTTPStatus.NOT_FOUND) - - content = response.content.decode() - phmatch = re.search(ph, content) - self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") # 200 & Page Not Found diff --git a/core/TESTS/tests_logins.py b/core/TESTS/tests_logins.py deleted file mode 100644 index f50e292..0000000 --- a/core/TESTS/tests_logins.py +++ /dev/null @@ -1,449 +0,0 @@ -""" -Originally written for CUYC -Philip Sargent (Feb.2021) - -Modified for Expo April 2021. -""" - -import pathlib -import re -from http import HTTPStatus - -from django.test import Client, TestCase - -import troggle.settings as settings -from troggle.core.models.wallets import Wallet -from troggle.core.models.troggle import Expedition - - -class DataTests(TestCase): - """These check that the NULL and NON-UNIQUE constraints are working in the database""" - - @classmethod - def setUpTestData(cls): - pass - - def setUp(self): - from django.contrib.auth.models import User - - u = User() - u.pk = 9000 - u.user_id = 8000 - u.username, u.password = "stinker", "secretword" - u.email = "philip.sargent+SP@gmail.com" - u.first_name, u.last_name = "Stinker", "Pinker" - u.save() - self.user = u - - def tearDown(self): - # self.member.delete() # must delete member before user - # self.user.delete() # horrible crash, why? - pass - - -class FixturePageTests(TestCase): - # The fixtures have a password hash which is compatible with plain-text password 'secretword' - fixtures = ["auth_users"] - - def setUp(self): - from django.contrib.auth.models import User - - self.user = User.objects.get(username="expotest") - - def tearDown(self): - pass - - def test_fix_admin_login_fail(self): - c = self.client - from django.contrib.auth.models import User - - u = User.objects.get(username="expotest") - - self.assertTrue(u.is_active, "User '" + u.username + "' is INACTIVE") - - logged_in = c.login(username=u.username, password="secretword") # fails to work if password=u.password ! - self.assertTrue(logged_in, "FAILED to login as '" + u.username + "'") - - response = c.get("/admin/") - content = response.content.decode() - # with open('admin-op.html', 'w') as f: - # f.write(content) - t = re.search(r"Troggle administration", content) - self.assertIsNone(t, "Logged in as '" + u.username + "' (not staff) but still managed to get the Admin page") - - -class PostTests(TestCase): - """Tests walletedit form""" - - fixtures = ["auth_users"] - - @classmethod - def setUpTestData(cls): - pass - - def setUp(self): - from django.contrib.auth.models import User - - self.user = User.objects.get(username="expotest") - self.client = Client() - - testyear = "2022" - wname = f"{testyear}:00" - self.testyear = testyear - w = Wallet() - w.pk = 9100 - w.fpath = str(pathlib.Path(settings.SCANS_ROOT, wname)) - w.walletname = wname - w.save() - self.wallet = w - - e = Expedition() - e.year = testyear - e.save() - self.expedition = e - - def test_file_permissions(self): - """Expect to be allowed to write to expofiles - Need to login first. - """ - c = self.client - from django.contrib.auth.models import User - - u = User.objects.get(username="expotest") - testyear = self.testyear - - self.assertTrue(u.is_active, "User '" + u.username + "' is INACTIVE") - c.login(username=u.username, password="secretword") - - for p in [settings.SCANS_ROOT, - settings.DRAWINGS_DATA / "walletjson", - settings.EXPOWEB / "documents", - settings.SURVEX_DATA / "docs" - ]: - - _test_file_path = pathlib.Path(p, "_created_by_test_suite.txt") - self.assertEqual(_test_file_path.is_file(), False) - - with open(_test_file_path, "w") as f: - f.write("test string: can we write to this directory?") - self.assertEqual(_test_file_path.is_file(), True) - _test_file_path.unlink() - - def test_scan_upload(self): - """Expect scan upload to wallet to work on any file - Need to login first. - - This upload form looks for the Cave and the Wallet, so the test fails if the database is not loaded with the cave - identified in the wallet - """ - c = self.client - from django.contrib.auth.models import User - - u = User.objects.get(username="expotest") - testyear = self.testyear - - self.assertTrue(u.is_active, "User '" + u.username + "' is INACTIVE") - c.login(username=u.username, password="secretword") - - with open("core/fixtures/test_upload_file.txt", "r") as testf: - response = self.client.post( - f"/walletedit/{testyear}:00", data={"name": "test_upload_file.txt", "uploadfiles": testf} - ) - content = response.content.decode() - self.assertEqual(response.status_code, HTTPStatus.OK) - self.assertEqual(response.status_code, HTTPStatus.OK) - with open("_test_response.html", "w") as f: - f.write(content) - for ph in [ - r"test_upload_", - rf"← {testyear}#00 →", - r"description written", - r"Plan not required", - r"edit settings or upload a file", - ]: - phmatch = re.search(ph, content) - self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") - - # # Does not use the filename Django actually uses, assumes it is unchanged. Potential bug. - # remove_file = pathlib.Path(settings.SCANS_ROOT) / f'{testyear}' / f'{testyear}#00'/ 'test_upload_file.txt' - # remove_file.unlink() - # # Undo the auto create and commit of a new wallet - # cwd = settings.DRAWINGS_DATA - # sp = subprocess.run([settings.GIT, "reset", "--hard", "master^"], cwd=cwd, capture_output=True, text=True) - # print(f'git output: {cwd}:\n # {sp.stderr=}\n # {sp.stdout=} \n # return code: {str(sp.returncode)}') - # if sp.returncode != 0: - # print(f'git output: {cwd}:\n # {sp.stderr=}\n # {sp.stdout=} \n # return code: {str(sp.returncode)}') - - def test_photo_upload(self): - """Expect photo upload to work on any file (contrary to msg on screen) - Upload into current default year. settings.PHOTOS_YEAR - Deletes file afterwards - Need to login first. - """ - c = self.client - from django.contrib.auth.models import User - - u = User.objects.get(username="expotest") - - self.assertTrue(u.is_active, "User '" + u.username + "' is INACTIVE") - c.login(username=u.username, password="secretword") - - with open("core/fixtures/test_upload_file.txt", "r") as testf: - response = self.client.post( - "/photoupload/", data={"name": "test_upload_file.txt", "renameto": "", "uploadfiles": testf} - ) - content = response.content.decode() - self.assertEqual(response.status_code, HTTPStatus.OK) - self.assertEqual(response.status_code, HTTPStatus.OK) - # with open('_test_response.html', 'w') as f: - # f.write(content) - for ph in [ - r"test_upload_", - r"Upload photos into /photos/" + str(settings.PHOTOS_YEAR), - r" you can create a new folder in your name", - r"Create new Photographer folder", - r"only photo image files are accepted", - ]: - phmatch = re.search(ph, content) - self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") - - # Does not use the filename Django actually uses, assumes it is unchanged. Potential bug. - remove_file = pathlib.Path(settings.PHOTOS_ROOT, settings.PHOTOS_YEAR) / "test_upload_file.txt" - remove_file.unlink() - - def test_photo_upload_rename(self): - """Expect photo upload to work on any file (contrary to msg on screen) - Upload into current default year. settings.PHOTOS_YEAR - Deletes file afterwards - Need to login first. - """ - c = self.client - from django.contrib.auth.models import User - - u = User.objects.get(username="expotest") - - self.assertTrue(u.is_active, "User '" + u.username + "' is INACTIVE") - c.login(username=u.username, password="secretword") - - rename = "RENAMED-FILE.JPG" - with open("core/fixtures/test_upload_file.txt", "r") as testf: - response = self.client.post( - "/photoupload/", data={"name": "test_upload_file.txt", "renameto": rename, "uploadfiles": testf} - ) - content = response.content.decode() - self.assertEqual(response.status_code, HTTPStatus.OK) - self.assertEqual(response.status_code, HTTPStatus.OK) - # with open('_test_response.html', 'w') as f: - # f.write(content) - for ph in [rename]: - phmatch = re.search(ph, content) - self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") - - # Does not use the filename Django actually uses, assumes it is unchanged. Potential bug. - remove_file = pathlib.Path(settings.PHOTOS_ROOT, settings.PHOTOS_YEAR) / rename - remove_file.unlink() - - def test_photo_folder_create(self): - """Create folder for new user - Create in current default year. settings.PHOTOS_YEAR - Deletes folder afterwards - Need to login first. - """ - c = self.client - from django.contrib.auth.models import User - - u = User.objects.get(username="expotest") - - self.assertTrue(u.is_active, "User '" + u.username + "' is INACTIVE") - c.login(username=u.username, password="secretword") - - response = self.client.post("/photoupload/", data={"photographer": "GussieFinkNottle"}) - content = response.content.decode() - self.assertEqual(response.status_code, HTTPStatus.OK) - self.assertEqual(response.status_code, HTTPStatus.OK) - # with open('_test_response.html', 'w') as f: - # f.write(content) - for ph in [r"/GussieFinkNottle/", r"Create new Photographer folder"]: - phmatch = re.search(ph, content) - self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'") - - # Does not use the filename Django actually uses, assumes it is unchanged. Potential bug. - remove_dir = pathlib.Path(settings.PHOTOS_ROOT, settings.PHOTOS_YEAR) / "GussieFinkNottle" - remove_dir.rmdir() - - def test_dwg_upload_txt(self): - """Expect .pdf file to be refused upload - Need to login first. - """ - c = self.client - from django.contrib.auth.models import User - - u = User.objects.get(username="expotest") - - self.assertTrue(u.is_active, "User '" + u.username + "' is INACTIVE") - c.login(username=u.username, password="secretword") - - with open("core/fixtures/test_upload_file.pdf", "r") as testf: - response = self.client.post( - "/dwgupload/uploads", data={"name": "test_upload_file.txt", "uploadfiles": testf} - ) - content = response.content.decode() - self.assertEqual(response.status_code, HTTPStatus.OK) - t = re.search("Files refused:", content) - self.assertIsNotNone(t, 'Logged in but failed to see "Files refused:"') - - def test_dwg_upload_drawing(self): - """Expect no-suffix file to upload - Note that this skips the git commit process. That would need a new test. - Need to login first. - """ - c = self.client - from django.contrib.auth.models import User - - u = User.objects.get(username="expotest") - - self.assertTrue(u.is_active, "User '" + u.username + "' is INACTIVE") - c.login(username=u.username, password="secretword") - - with open("core/fixtures/test_upload_nosuffix", "r") as testf: - response = self.client.post( - "/dwguploadnogit/uploads", data={"name": "test_upload_nosuffix", "uploadfiles": testf} - ) - content = response.content.decode() - # with open('_test_response.html', 'w') as f: - # f.write(content) - self.assertEqual(response.status_code, HTTPStatus.OK) - for ph in [ - r"test_upload_nosuffix", - r"You cannot create folders here", - r"Creating a folder is done by a nerd", - ]: - phmatch = re.search(ph, content) - self.assertIsNotNone( - phmatch, "Expect no-suffix file to upload OK. Failed to find expected text: '" + ph + "'" - ) - - # Does not use the filename Django actually uses, assumes it is unchanged. Bug: accumulates one file with random name added each time it is run. - remove_file = pathlib.Path(settings.DRAWINGS_DATA) / "uploads" / "test_upload_nosuffix" - remove_file.unlink() - - -class ComplexLoginTests(TestCase): - """These test the login and capabilities of logged-in users, they do not use fixtures""" - - def setUp(self): - """setUp runs once for each test in this class""" - from django.contrib.auth.models import User - - u = User() - u.pk = 9000 - u.user_id = 8000 - u.username, u.password = "expotest", "secretword" - u.email = "philip.sargent+ET@gmail.com" - u.first_name, u.last_name = "ExpoTest", "Caver" - u.is_staff = True - u.is_superuser = True - - u.set_password(u.password) # This creates a new salt and thus a new key for EACH test - u.save() # vital that we save all this before attempting login - # print ('\n',u.password) - self.user = u - - def tearDown(self): - self.client.logout() # not needed as each test creates a new self.client - # self.member.delete() - ##self.user.delete() # id attribute set to None ! - pass - - # def test_login_redirect_for_non_logged_on_user(self): # need to fix this in real system - # c = self.client - # # Need to login first. Tests that we are redirected to login page if not logged in - # response = c.get('noinfo/cave-number-index') - # self.assertRedirects(response, "/login/?next=/committee/appointments/") - - def test_ordinary_login(self): - c = self.client - u = self.user - - self.assertTrue(u.is_active, "User '" + u.username + "' is INACTIVE") - - logged_in = c.login(username=u.username, password="secretword") # fails to work if password=u.password ! - self.assertTrue(logged_in, "FAILED to login as '" + u.username + "'") - - response = c.get("/accounts/login/") # defined by auth system - content = response.content.decode() - t = re.search(r"You are now logged in", content) - self.assertIsNotNone(t, "Logged in as '" + u.username + "' but failed to get 'Now you can' greeting") - - def test_authentication_login(self): - c = self.client - u = self.user - - self.assertTrue(u.is_active, "User '" + u.username + "' is INACTIVE") - - # This is weird. I thought that the user had to login before she was in the authenticated state - self.assertTrue(u.is_authenticated, "User '" + u.username + "' is NOT AUTHENTICATED before login") - - logged_in = c.login(username=u.username, password="secretword") # fails to work if password=u.password ! - self.assertTrue(logged_in, "FAILED to login as '" + u.username + "'") - - self.assertTrue(u.is_authenticated, "User '" + u.username + "' is NOT AUTHENTICATED after login") - - # c.logout() # This next test always means user is still authenticated after logout. Surely not? - # self.assertFalse(u.is_authenticated, 'User \'' + u.username + '\' is STILL AUTHENTICATED after logout') - - def test_admin_login(self): - c = self.client - u = self.user - - logged_in = c.login(username=u.username, password="secretword") # fails to work if password=u.password ! - self.assertTrue(logged_in, "FAILED to login as '" + u.username + "'") - - response = c.get("/admin/") - content = response.content.decode() - # with open('admin-op.html', 'w') as f: - # f.write(content) - t = re.search(r"Troggle database administration", content) - self.assertIsNotNone(t, "Logged in as '" + u.username + "' but failed to get the Troggle Admin page") - - def test_noinfo_login(self): - - c = self.client # inherited from TestCase - u = self.user - - logged_in = c.login(username=u.username, password="secretword") # fails if password=u.password ! - self.assertTrue(logged_in, "FAILED to login as '" + u.username + "'") - response = c.get("/stats") # a page with the Troggle menus - content = response.content.decode() - t = re.search(r"User\:expotest", content) - self.assertIsNotNone(t, "Logged in as '" + u.username + "' but failed to get 'User:expotest' heading") - - response = c.get("/noinfo/cave-number-index") - content = response.content.decode() - t = re.search(r"2001-07 Hoffnungschacht", content) - self.assertIsNotNone(t, "Logged in as '" + u.username + "' but failed to get /noinfo/ content") - - def test_user_force(self): - - c = self.client - u = self.user - - try: - c.force_login(u) - except: - self.assertIsNotNone( - None, - "Unexpected exception trying to force_login as '" - + u.username - + "' but failed (Bad Django documentation?)", - ) - - response = c.get("/stats") # a page with the Troggle menus - content = response.content.decode() - t = re.search(r"Log out", content) - self.assertIsNotNone(t, "Forced logged in as '" + u.username + "' but failed to get Log out heading") - - response = c.get("/accounts/login/") - content = response.content.decode() - t = re.search(r"You are now logged in", content) - self.assertIsNotNone(t, "Forced logged in as '" + u.username + "' but failed to get /accounts/profile/ content") -- cgit v1.2.3