2023-02-24 22:55:18 +00:00
|
|
|
"""
|
|
|
|
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.
|
|
|
|
|
|
|
|
The simple redirections to files which exist, e.g. in
|
|
|
|
/expoweb/
|
2023-05-02 13:28:28 +01:00
|
|
|
/photos/
|
2023-02-24 22:55:18 +00:00
|
|
|
etc. will test fine.
|
|
|
|
|
|
|
|
But paths like this:
|
|
|
|
/survey_scans/
|
|
|
|
/caves/
|
|
|
|
which rely on database resolution will fail unless a fixture has been set up for
|
|
|
|
them.
|
|
|
|
|
|
|
|
https://docs.djangoproject.com/en/dev/topics/testing/tools/
|
|
|
|
"""
|
|
|
|
import re
|
|
|
|
import subprocess
|
|
|
|
import unittest
|
2023-03-03 15:15:17 +00:00
|
|
|
from http import HTTPStatus
|
2023-02-24 22:55:18 +00:00
|
|
|
|
|
|
|
from django.test import Client, SimpleTestCase, TestCase
|
|
|
|
|
2023-09-03 22:25:35 +01:00
|
|
|
from troggle.core.models.logbooks import LogbookEntry
|
2023-02-24 22:55:18 +00:00
|
|
|
from troggle.core.models.troggle import Expedition, DataIssue, Person, PersonExpedition
|
|
|
|
import troggle.parsers.logbooks as lbp
|
|
|
|
|
|
|
|
TEST_YEAR = "1986"
|
|
|
|
lbp.ENTRIES[TEST_YEAR] = 4 # number of entries in the test logbook
|
|
|
|
|
|
|
|
class ImportTest(TestCase):
|
2023-09-03 21:28:36 +01:00
|
|
|
# see test_logins.py for the tests to check that logged-in users work
|
|
|
|
fixtures = ["auth_users"] # contains user 'expotest' with a hash => password = 'secretword'
|
2023-02-24 22:55:18 +00:00
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def setUpTestData(cls):
|
2023-10-05 13:33:01 +01:00
|
|
|
def make_person(firstname, lastname, nickname=False, vfho=False):
|
2023-02-24 22:55:18 +00:00
|
|
|
fullname = f"{firstname} {lastname}"
|
2023-10-05 13:33:01 +01:00
|
|
|
slug=f"{firstname.lower()}-{lastname.lower()}"
|
|
|
|
coUniqueAttribs = {"first_name": firstname, "last_name": (lastname or ""), "slug": slug,}
|
2023-10-01 10:42:47 +01:00
|
|
|
otherAttribs = {"is_vfho": vfho, "fullname": fullname, "nickname": nickname}
|
|
|
|
person = Person.objects.create(**otherAttribs, **coUniqueAttribs)
|
2023-02-24 22:55:18 +00:00
|
|
|
|
2023-10-01 10:42:47 +01:00
|
|
|
coUniqueAttribs = {"person": person, "expedition": cls.test_expo}
|
2023-10-05 13:33:01 +01:00
|
|
|
otherAttribs = {}
|
2023-10-01 10:42:47 +01:00
|
|
|
pe = PersonExpedition.objects.create(**otherAttribs, **coUniqueAttribs)
|
2023-02-24 22:55:18 +00:00
|
|
|
|
|
|
|
return person
|
|
|
|
|
|
|
|
import troggle.settings as settings
|
|
|
|
|
|
|
|
LOGBOOKS_PATH = settings.EXPOWEB / lbp.LOGBOOKS_DIR
|
|
|
|
|
|
|
|
cls.test_logbook = LOGBOOKS_PATH / TEST_YEAR / lbp.DEFAULT_LOGBOOK_FILE
|
|
|
|
frontmatter_file = LOGBOOKS_PATH / TEST_YEAR / "frontmatter.html"
|
|
|
|
if frontmatter_file.is_file():
|
|
|
|
frontmatter_file.unlink() # delete if it exists
|
|
|
|
|
2023-10-01 10:42:47 +01:00
|
|
|
coUniqueAttribs = {"year": TEST_YEAR}
|
|
|
|
otherAttribs = {"name": f"CUCC expo-test {TEST_YEAR}"}
|
|
|
|
cls.test_expo = Expedition.objects.create(**otherAttribs, **coUniqueAttribs)
|
2023-02-24 22:55:18 +00:00
|
|
|
|
|
|
|
fred = make_person("Fred", "Smartarse", nickname="freddy")
|
|
|
|
phil = make_person("Phil", "Tosser", nickname="tosspot")
|
|
|
|
dave = make_person("David", "Smartarse", "")
|
|
|
|
mike = make_person("Michael", "Wideboy", "WB", vfho=True)
|
2023-02-24 23:12:44 +00:00
|
|
|
# NOT created Kurt, as the whole point is that he is a guest.
|
2023-09-03 21:28:36 +01:00
|
|
|
|
|
|
|
def setUp(self):
|
|
|
|
from django.contrib.auth.models import User
|
|
|
|
|
|
|
|
self.user = User.objects.get(username="expotest") # has password 'secretword' from fixture
|
|
|
|
self.client = Client()
|
|
|
|
|
2023-02-24 22:55:18 +00:00
|
|
|
|
|
|
|
def tearDown(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def test_logbook_exists(self):
|
|
|
|
self.assertTrue(self.test_logbook.is_file())
|
|
|
|
|
2023-09-03 22:25:35 +01:00
|
|
|
def test_logbook_parse_issues(self):
|
2023-09-03 21:28:36 +01:00
|
|
|
"""This is just testing the db not the web page
|
|
|
|
"""
|
|
|
|
lbp.LoadLogbook(self.test_expo) # i.e. load the 1986 logbook
|
2023-02-24 22:55:18 +00:00
|
|
|
|
|
|
|
issues = DataIssue.objects.all()
|
|
|
|
messages = []
|
|
|
|
for i in issues:
|
|
|
|
if i.parser=="logbooks":
|
|
|
|
# f"{self.parser} - {self.message}"
|
|
|
|
messages.append(i.message)
|
|
|
|
print(f"'{i.message}'")
|
|
|
|
|
|
|
|
expected = [
|
2023-09-01 19:35:26 +01:00
|
|
|
"! - 1986 No name match for: 'Kurt Keinnamen' in entry",
|
2023-02-24 22:55:18 +00:00
|
|
|
]
|
|
|
|
|
|
|
|
not_expected = [
|
2023-09-01 19:14:19 +01:00
|
|
|
" ! - 1986 EXCEPTION:: 'Dave Smartarse' (Dave Smartarse) in entry tid='1986-07-27a' for this year.",
|
|
|
|
" ! - 1986 Warning: logentry: surface - stupour - no expo member author for entry '1986-07-31a'",
|
|
|
|
" ! - 1986 Warning: logentry: 123 - wave 2 - no expo member author for entry '1986-08-01a'",
|
2023-02-24 22:55:18 +00:00
|
|
|
]
|
2023-09-03 22:25:35 +01:00
|
|
|
# with open('_test_response.txt', 'w') as f:
|
|
|
|
# for m in messages:
|
|
|
|
# f.write(m)
|
2023-09-03 21:28:36 +01:00
|
|
|
messages_text = ", ".join(messages)
|
2023-02-24 22:55:18 +00:00
|
|
|
for e in expected:
|
2023-09-03 21:28:36 +01:00
|
|
|
phmatch = re.search(e, messages_text)
|
|
|
|
self.assertIsNotNone(phmatch, f"Failed to find expected text: '{e}' in\n{messages_text}")
|
2023-02-24 23:12:44 +00:00
|
|
|
for e in not_expected:
|
2023-09-03 21:28:36 +01:00
|
|
|
phmatch = re.search(e, messages_text)
|
|
|
|
self.assertIsNone(phmatch, f"Found unexpected text: '{e}' in\n{messages_text}")
|
2023-03-03 15:15:17 +00:00
|
|
|
|
2023-09-01 19:35:26 +01:00
|
|
|
def test_lbe(self):
|
2023-09-03 21:28:36 +01:00
|
|
|
lbp.LoadLogbook(self.test_expo) # i.e. load the 1986 logbook, which has this logbook entry
|
2023-09-01 19:35:26 +01:00
|
|
|
|
2023-09-03 21:28:36 +01:00
|
|
|
response = self.client.get(f"/logbookentry/1986-07-27/1986-07-27a")
|
2023-09-01 19:35:26 +01:00
|
|
|
self.assertEqual(response.status_code, HTTPStatus.OK)
|
|
|
|
content = response.content.decode()
|
2023-09-03 22:25:35 +01:00
|
|
|
# with open('_test_response_1986-07-27a.html', 'w') as f:
|
2023-09-03 21:28:36 +01:00
|
|
|
# f.write(content)
|
2023-09-01 19:50:03 +01:00
|
|
|
expected = [
|
2023-09-03 21:28:36 +01:00
|
|
|
"<title>Logbook CUCC expo-test 1986 123 - 123 Wave 1</title>",
|
2023-09-01 19:50:03 +01:00
|
|
|
"Smartarse rig first section of new pitches. Second wave arrives and takes over rigging.",
|
|
|
|
]
|
|
|
|
for ph in expected:
|
|
|
|
phmatch = re.search(ph, content)
|
|
|
|
self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'")
|
2023-09-03 21:28:36 +01:00
|
|
|
|
|
|
|
def test_lbe_new(self):
|
|
|
|
"""This page requires the user to be logged in first, hence the extra shenanigans
|
|
|
|
"""
|
|
|
|
c = self.client
|
|
|
|
u = self.user
|
|
|
|
c.login(username=u.username, password="secretword")
|
|
|
|
|
|
|
|
response = self.client.get(f"/logbookedit/")
|
|
|
|
self.assertEqual(response.status_code, HTTPStatus.OK)
|
|
|
|
content = response.content.decode()
|
2023-09-03 22:25:35 +01:00
|
|
|
# with open('_test_response.html', 'w') as f:
|
|
|
|
# f.write(content)
|
2023-09-03 21:28:36 +01:00
|
|
|
expected = [
|
|
|
|
"New Logbook Entry in ",
|
2023-09-03 22:25:35 +01:00
|
|
|
"Everyone else involved",
|
2023-09-03 21:28:36 +01:00
|
|
|
"Place: cave name, or 'plateau', 'topcamp' etc.",
|
|
|
|
]
|
|
|
|
for ph in expected:
|
|
|
|
phmatch = re.search(ph, content)
|
|
|
|
self.assertIsNotNone(phmatch, f"({response.status_code}) Failed to find expected text: '" + ph + "'")
|
|
|
|
|
|
|
|
|
|
|
|
def test_lbe_edit(self):
|
2023-09-03 22:25:35 +01:00
|
|
|
"""This page requires the user to be logged in first, hence the extra shenanigans
|
|
|
|
"""
|
2023-09-03 21:28:36 +01:00
|
|
|
c = self.client
|
|
|
|
u = self.user
|
|
|
|
c.login(username=u.username, password="secretword")
|
2023-09-03 22:25:35 +01:00
|
|
|
|
|
|
|
lbp.LoadLogbook(self.test_expo) # i.e. load the 1986 logbook, which has this logbook entry
|
|
|
|
# muliple loads are overwriting the lbes and incrementing the a, b, c etc, so get one that works
|
|
|
|
lbe = LogbookEntry.objects.get(date="1986-07-31") # only one on this date in fixture
|
|
|
|
|
|
|
|
response = self.client.get(f"/logbookedit/{lbe.slug}")
|
2023-09-03 21:28:36 +01:00
|
|
|
self.assertEqual(response.status_code, HTTPStatus.OK)
|
|
|
|
content = response.content.decode()
|
2023-09-03 22:25:35 +01:00
|
|
|
# with open('_test_response_edit.html', 'w') as f:
|
|
|
|
# f.write(content)
|
2023-09-03 21:28:36 +01:00
|
|
|
expected = [
|
2023-09-03 22:25:35 +01:00
|
|
|
"Edit Logbook Entry on 1986-07-31",
|
2023-11-23 18:46:44 +00:00
|
|
|
r"Other names \(comma separated\)", # regex match so slashes need to be espcaped
|
2023-09-03 21:28:36 +01:00
|
|
|
"Place: cave name, or 'plateau', 'topcamp' etc.",
|
|
|
|
]
|
|
|
|
for ph in expected:
|
|
|
|
phmatch = re.search(ph, content)
|
|
|
|
self.assertIsNotNone(phmatch, f"({response.status_code}) Failed to find expected text: '" + ph + "'")
|
|
|
|
|
2023-03-03 15:15:17 +00:00
|
|
|
def test_aliases(self):
|
2023-09-03 21:28:36 +01:00
|
|
|
# FIX THIS
|
2023-04-05 12:46:10 +01:00
|
|
|
# Problem: '' empty string appears as valid alias for David Smartarse
|
2023-03-03 15:15:17 +00:00
|
|
|
response = self.client.get(f"/aliases/{TEST_YEAR}")
|
|
|
|
self.assertEqual(response.status_code, HTTPStatus.OK)
|
|
|
|
content = response.content.decode()
|
2023-04-05 12:46:10 +01:00
|
|
|
# with open('_test_response.html', 'w') as f:
|
|
|
|
# f.write(content)
|
2023-03-03 15:15:17 +00:00
|
|
|
ph = f"'fsmartarse'"
|
|
|
|
phmatch = re.search(ph, content)
|
|
|
|
self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'")
|
2023-03-05 23:17:11 +00:00
|
|
|
|
|
|
|
def test_survexfiles(self):
|
|
|
|
# Needs another test with test data
|
|
|
|
response = self.client.get("/survexfile/caves/")
|
|
|
|
self.assertEqual(response.status_code, HTTPStatus.OK)
|
|
|
|
content = response.content.decode()
|
2023-04-06 00:51:04 +01:00
|
|
|
# with open('_test_response.html', 'w') as f:
|
|
|
|
# f.write(content)
|
2023-03-05 23:17:11 +00:00
|
|
|
ph = f"Caves with subdirectories"
|
|
|
|
phmatch = re.search(ph, content)
|
|
|
|
self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'")
|
2023-03-03 15:15:17 +00:00
|
|
|
|
|
|
|
def test_people(self):
|
|
|
|
# Needs another test with test data
|
|
|
|
response = self.client.get("/people")
|
|
|
|
self.assertEqual(response.status_code, HTTPStatus.OK)
|
|
|
|
content = response.content.decode()
|
2023-04-06 00:51:04 +01:00
|
|
|
# with open('_test_response.html', 'w') as f:
|
|
|
|
# f.write(content)
|
2023-10-05 13:36:04 +01:00
|
|
|
ph = f"<td><a href=\"/personexpedition/fred-smartarse/{TEST_YEAR}\">{TEST_YEAR}</a></td>"
|
2023-03-03 15:15:17 +00:00
|
|
|
phmatch = re.search(ph, content)
|
|
|
|
self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph + "'")
|
|
|
|
|