From 0bafcacdad912a598cdf4e031cab5059efb30b18 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Sun, 23 Sep 2018 16:40:14 +0200 Subject: tests: ajout de tests pour le parseur UPS2018 Le parseur est une des parties les plus importantes de celcatsanitizer, mais ni le parseur 2017, ni le parseur 2018 n’ont eu de test unitaires à proprement parler. Jusqu’ici, pour tester ce composant, on ajoutait une source dans la base, on la récupérait, et on regardait si tout correspondait plus ou moins. Cette technique a plusieurs inconvénients : c’était une tâche rébarbative et pas systématiquement effectuée, ce qui a posé quelques problèmes par le passé, certains cas pouvaient ne pas se trouver dans la source au moment de la récupération, et ce n’était pas reproductible proprement. Rajouter des tests permettra donc de tester efficacement le parseur, avec tous les cas de figure, rapidement et en utilisant seulement des ressources locales. Pour éviter d’utiliser le réseau, le module requests est mocké lorsqu’on teste des fonctions qui l’utilisent. L’initialisation du parseur et ses fonctions __get_event(), get_events(), get_source() et get_update_date() (ainsi que la fonction find_events_list() de manière indirecte) sont testées. Signed-off-by: Alban Gruin --- tests.py | 227 +++++++++++++++++++++++++++++++++++++++++ tests/data/2018/october.html | 50 +++++++++ tests/data/2018/september.html | 51 +++++++++ 3 files changed, 328 insertions(+) create mode 100644 tests/data/2018/october.html create mode 100644 tests/data/2018/september.html diff --git a/tests.py b/tests.py index 2568688..a6c84d7 100644 --- a/tests.py +++ b/tests.py @@ -13,13 +13,42 @@ # You should have received a copy of the GNU Affero General Public License # along with celcatsanitizer. If not, see . +from unittest import mock + from django.test import TestCase from django.utils import timezone +from .management.parsers.ups2018 import Parser as UPS2018Parser from .models import Course, Group, Room, Source, Timetable, Year from .utils import tz_now import datetime +import os + + +def mock_requests_get(*args, **kwargs): + class MockedResponse: + def __init__(self, content=""): + self.encoding = "utf-8" + self.content = content + self.status = 200 + + def raise_for_status(self): + return + + def mocked_response_from_file(filename): + module_dir = os.path.dirname(__file__) + filepath = os.path.join(module_dir, filename) + with open(filepath, "r") as response: + return MockedResponse(response.read()) + + if args[0] == "https://example.org/2018": + if not kwargs["params"]: + return mocked_response_from_file("tests/data/2018/september.html") + elif kwargs["params"].get("Date") == "20181001": + return mocked_response_from_file("tests/data/2018/october.html") + else: + return MockedResponse("") class CourseTestCase(TestCase): @@ -345,3 +374,201 @@ class RoomTestCase(TestCase): self.assertNotIn(self.rooms[4], rooms) self.assertIn(self.rooms[5], rooms) self.assertIn(self.rooms[6], rooms) + + +class UPS2018ParserTestCase(TestCase): + @mock.patch("requests.get", side_effect=mock_requests_get) + def setUp(self, *args, **kwargs): + source = Source.objects.create(url="https://example.org/2018") + self.room = Room.objects.create(name="Salle quelconque") + self.room2 = Room.objects.create(name="Salle quelconque 2") + + self.group = Group(celcat_name="L3 Info s1 CMA") + self.group.source = source + self.group.save() + + self.parser = UPS2018Parser(source) + + def test_get_event(self): + get_event = self.parser._Parser__get_event + + event = get_event( + {"start": "2018-09-21T10:00:00", "end": "2018-09-21T12:00:00", + "text": "(10:00-12:00)
COURS/TD
Cours quelconque;AAA" + "
L3 Info s1 CMA;L3 Info s1 TDA2
" + "Salle quelconque;Salle quelconque 2
Commentaire"}, + timezone.make_aware(datetime.datetime(2018, 9, 21)), + timezone.make_aware(datetime.datetime(2018, 9, 1)), + timezone.make_aware(datetime.datetime(2018, 10, 1)), + 2018, 38) + + ngroup = Group.objects.filter(name="L3 Info s1 TDA2").first() + self.assertIsNotNone(ngroup) + + self.assertEqual(event.name, "Cours quelconque, AAA") + self.assertEqual(event.type, "COURS/TD") + self.assertIn(self.group, event.groups.all()) + self.assertIn(ngroup, event.groups.all()) + self.assertEqual(event.groups.count(), 2) + self.assertIn(self.room, event.rooms.all()) + self.assertIn(self.room2, event.rooms.all()) + self.assertEqual(event.rooms.count(), 2) + self.assertEqual(event.notes, "Commentaire") + self.assertEqual(event.begin, timezone.make_aware( + datetime.datetime(2018, 9, 21, 10, 0, 0))) + self.assertEqual(event.end, timezone.make_aware( + datetime.datetime(2018, 9, 21, 12, 0, 0))) + + events = [ + { + "text": "(10:00-12:00)
COURS/TD
Cours quelconque" + "
L3 Info s1 CMA
Salle quelconque", + "name": "Cours quelconque", "type": "COURS/TD", + "group": self.group, + "room": self.room, + }, + { + "text": "(10:00-12:00)
COURS/TD
Cours quelconque" + "
L3 Info s1 TDA2
Salle quelconque 3", + "name": "Cours quelconque", + "type": "COURS/TD", + "group": ngroup, + "notes": "Salle quelconque 3" + }, + { + "text": "(10:00-12:00)
COURS/TD
Cours quelconque" + "
L3 Info s1 CMA
Salle quelconque 3
Commentaire", + "name": "Cours quelconque", + "type": "COURS/TD", + "group": self.group, + "notes": "Salle quelconque 3\nCommentaire", + }, + { + "text": "(10:00-12:00)
COURS/TD" + "
L3 Info s1 CMA
Salle quelconque 3", + "name": "COURS/TD", + "group": self.group, + "notes": "Salle quelconque 3" + }, + { + "text": "COURS/TD
L3 Info s1 CMA
Salle quelconque 3", + "name": "COURS/TD", + "group": self.group, + "notes": "Salle quelconque 3" + }, + { + "text": "L3 Info s1 CMA
Salle quelconque", + "name": "Sans nom", + "group": self.group, + "room": self.room + }, + { + "text": "L3 Info s1 CMA
Salle quelconque 3", + "name": "Sans nom", + "group": self.group, + "notes": "Salle quelconque 3" + }, + { + "text": "(10:00-12:00)
L3 Info s1 CMA
Salle quelconque", + "name": "Sans nom", + "group": self.group, + "room": self.room + } + ] + + for e in events: + event = get_event( + {"start": "2018-09-21T10:00:00", "end": "2018-09-21T12:00:00", + "text": e["text"]}, + timezone.make_aware(datetime.datetime(2018, 9, 21)), + timezone.make_aware(datetime.datetime(2018, 9, 1)), + timezone.make_aware(datetime.datetime(2018, 10, 1)), + 2018, 38) + + self.assertEqual(event.name, e["name"]) + self.assertIn(e["group"], event.groups.all()) + self.assertEqual(event.groups.count(), 1) + + if "type" in e: + self.assertEqual(event.type, e["type"]) + else: + self.assertIsNone(event.type) + + if "room" in e: + self.assertIn(e["room"], event.rooms.all()) + self.assertEqual(event.rooms.count(), 1) + else: + self.assertEqual(event.rooms.count(), 0) + + if "notes" in e: + self.assertEqual(event.notes, e["notes"]) + else: + self.assertIsNone(event.notes) + + event = get_event( + {"start": "2018-09-21T10:00:00", "end": "2018-09-21T12:00:00", + "text": "Global Event"}, + timezone.make_aware(datetime.datetime(2018, 9, 21)), + timezone.make_aware(datetime.datetime(2018, 9, 1)), + timezone.make_aware(datetime.datetime(2018, 10, 1)), + 2018, 38) + self.assertIsNone(event) + + event = get_event( + {"start": "2018-09-21T10:00:00", "end": "2018-09-21T12:00:00", + "text": "L3 Info s1 CMA
Salle quelconque 2"}, + timezone.make_aware(datetime.datetime(2018, 9, 21)), + timezone.make_aware(datetime.datetime(2018, 9, 1)), + timezone.make_aware(datetime.datetime(2018, 10, 1)), + 2018, 39) + self.assertIsNone(event) + + @mock.patch("requests.get", side_effect=mock_requests_get) + def test_get_events(self, *args, **kwargs): + self.parser.get_source() + courses = [ + {"begin": + timezone.make_aware(datetime.datetime(2018, 9, 21, 10, 00, 00)), + "end": + timezone.make_aware(datetime.datetime(2018, 9, 21, 12, 00, 00))}, + {"begin": + timezone.make_aware(datetime.datetime(2018, 10, 22, 10, 00, 00)), + "end": + timezone.make_aware(datetime.datetime(2018, 10, 22, 12, 00, 00))} + ] + + for i, course in enumerate(self.parser.get_events( + timezone.make_aware(datetime.datetime(2018, 9, 21)))): + self.assertEqual(course.name, "Cours quelconque") + self.assertEqual(course.type, "COURS/TD") + self.assertIn(self.group, course.groups.all()) + self.assertEqual(course.groups.count(), 1) + self.assertIn(self.room, course.rooms.all()) + self.assertEqual(course.rooms.count(), 1) + self.assertIsNone(course.notes) + self.assertEqual(course.begin, courses[i]["begin"]) + self.assertEqual(course.end, courses[i]["end"]) + + self.assertEqual(i, len(courses) - 1) + + @mock.patch("requests.get", side_effect=mock_requests_get) + def test_get_source(self, *args, **kwargs): + events = self.parser.get_source() + self.assertEquals(events, [ + [{ + "start": "2018-09-21T10:00:00", "end": "2018-09-21T12:00:00", + "text": "(10:00-12:00)
COURS/TD
Cours quelconque" + "
L3 Info s1 CMA
Salle quelconque" + }], [{ + "start": "2018-09-21T10:00:00", "end": "2018-09-21T12:00:00", + "text": "(10:00-12:00)
COURS/TD
Cours quelconque" + "
L3 Info s1 CMA
Salle quelconque" + }, { + "start": "2018-10-22T10:00:00", "end": "2018-10-22T12:00:00", + "text": "(10:00-12:00)
COURS/TD
Cours quelconque" + "
L3 Info s1 CMA
Salle quelconque" + }], [], [], [], [], [], [], [], [], []]) + + def test_get_update_date(self): + # Pas de date de mise à jour dans ce format + self.assertIsNone(self.parser.get_update_date()) diff --git a/tests/data/2018/october.html b/tests/data/2018/october.html new file mode 100644 index 0000000..6f326f9 --- /dev/null +++ b/tests/data/2018/october.html @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/data/2018/september.html b/tests/data/2018/september.html new file mode 100644 index 0000000..3db6cbc --- /dev/null +++ b/tests/data/2018/september.html @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.1