mirror of
https://github.com/ae-utbm/sith.git
synced 2026-09-14 16:29:12 +00:00
add tests
This commit is contained in:
+2
-5
@@ -29,14 +29,11 @@ class UeController(ControllerBase):
|
|||||||
response=UeSchema,
|
response=UeSchema,
|
||||||
)
|
)
|
||||||
def fetch_from_utbm_api(
|
def fetch_from_utbm_api(
|
||||||
self,
|
self, code: str, year: Query[Annotated[int, Ge(2010)] | None] = None
|
||||||
code: str,
|
|
||||||
lang: Query[str] = "fr",
|
|
||||||
year: Query[Annotated[int, Ge(2010)] | None] = None,
|
|
||||||
):
|
):
|
||||||
"""Fetch UE data from the UTBM API and returns it after some parsing."""
|
"""Fetch UE data from the UTBM API and returns it after some parsing."""
|
||||||
with UtbmApiClient() as client:
|
with UtbmApiClient() as client:
|
||||||
res = client.find_ue(lang, code, year)
|
res = client.find_ue(code, year)
|
||||||
if res is None:
|
if res is None:
|
||||||
raise NotFound
|
raise NotFound
|
||||||
return res
|
return res
|
||||||
|
|||||||
@@ -190,6 +190,7 @@ class UeFilterSchema(FilterSchema):
|
|||||||
return Q(semester__in=value)
|
return Q(semester__in=value)
|
||||||
|
|
||||||
def filter_is_open(self, value: bool | None) -> Q: # noqa: FBT001
|
def filter_is_open(self, value: bool | None) -> Q: # noqa: FBT001
|
||||||
|
"""Filter by open/closed status."""
|
||||||
if value is None:
|
if value is None:
|
||||||
return Q()
|
return Q()
|
||||||
if not value:
|
if not value:
|
||||||
|
|||||||
+42
-46
@@ -1,8 +1,6 @@
|
|||||||
import json
|
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.core.management import call_command
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.test.testcases import call_command
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from model_bakery import baker
|
from model_bakery import baker
|
||||||
from model_bakery.recipe import Recipe
|
from model_bakery.recipe import Recipe
|
||||||
@@ -17,7 +15,7 @@ class TestUESearch(TestCase):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpTestData(cls):
|
def setUpTestData(cls):
|
||||||
cls.root = User.objects.get(username="root")
|
cls.root = baker.make(User, is_superuser=True)
|
||||||
cls.url = reverse("api:fetch_ues")
|
cls.url = reverse("api:fetch_ues")
|
||||||
ue_recipe = Recipe(UE, author=cls.root)
|
ue_recipe = Recipe(UE, author=cls.root)
|
||||||
ues = [
|
ues = [
|
||||||
@@ -92,10 +90,10 @@ class TestUESearch(TestCase):
|
|||||||
def test_format(self):
|
def test_format(self):
|
||||||
"""Test that the return data format is correct"""
|
"""Test that the return data format is correct"""
|
||||||
self.client.force_login(self.root)
|
self.client.force_login(self.root)
|
||||||
res = self.client.get(self.url + "?search=PA00")
|
res = self.client.get(self.url, query_params={"search": "PA00"})
|
||||||
ue = UE.objects.get(code="PA00")
|
ue = UE.objects.get(code="PA00")
|
||||||
assert res.status_code == 200
|
assert res.status_code == 200
|
||||||
assert json.loads(res.content) == {
|
assert res.json() == {
|
||||||
"count": 1,
|
"count": 1,
|
||||||
"next": None,
|
"next": None,
|
||||||
"previous": None,
|
"previous": None,
|
||||||
@@ -121,79 +119,77 @@ class TestUESearch(TestCase):
|
|||||||
def test_search_by_text(self):
|
def test_search_by_text(self):
|
||||||
self.client.force_login(self.root)
|
self.client.force_login(self.root)
|
||||||
for query, expected in (
|
for query, expected in (
|
||||||
# UE code search case insensitive
|
# UE code search case-insensitive
|
||||||
("m", {"MT01", "MT10"}),
|
("m", {"MT01", "MT10"}),
|
||||||
("M", {"MT01", "MT10"}),
|
("M", {"MT01", "MT10"}),
|
||||||
("mt", {"MT01", "MT10"}),
|
("mt", {"MT01", "MT10"}),
|
||||||
("MT", {"MT01", "MT10"}),
|
("MT", {"MT01", "MT10"}),
|
||||||
("algèbre", {"MT01"}), # Title search case insensitive
|
("algèbre", {"MT01"}), # Title search case-insensitive
|
||||||
# Manager search
|
# Manager search
|
||||||
("moss", {"TNEV"}),
|
("moss", {"TNEV"}),
|
||||||
("francky", {"DA50", "AP4A"}),
|
("francky", {"DA50", "AP4A"}),
|
||||||
):
|
):
|
||||||
res = self.client.get(self.url + f"?search={query}")
|
res = self.client.get(self.url, query_params={"search": query})
|
||||||
assert res.status_code == 200
|
assert res.status_code == 200
|
||||||
assert {ue["code"] for ue in json.loads(res.content)["results"]} == expected
|
assert {ue["code"] for ue in res.json()["results"]} == expected
|
||||||
|
|
||||||
def test_search_by_credit_type(self):
|
def test_search_by_credit_type(self):
|
||||||
self.client.force_login(self.root)
|
self.client.force_login(self.root)
|
||||||
res = self.client.get(self.url + "?credit_type=CS")
|
res = self.client.get(self.url, query_params={"credit_type": "CS"})
|
||||||
assert res.status_code == 200
|
assert res.status_code == 200
|
||||||
codes = [ue["code"] for ue in json.loads(res.content)["results"]]
|
codes = [ue["code"] for ue in res.json()["results"]]
|
||||||
assert codes == ["AP4A", "MT01", "PHYS11"]
|
assert codes == ["AP4A", "MT01", "PHYS11"]
|
||||||
res = self.client.get(self.url + "?credit_type=CS&credit_type=OM")
|
res = self.client.get(self.url, query_params={"credit_type": ["CS", "OM"]})
|
||||||
assert res.status_code == 200
|
assert res.status_code == 200
|
||||||
codes = {ue["code"] for ue in json.loads(res.content)["results"]}
|
codes = {ue["code"] for ue in res.json()["results"]}
|
||||||
assert codes == {"AP4A", "MT01", "PHYS11", "PA00"}
|
assert codes == {"AP4A", "MT01", "PHYS11", "PA00"}
|
||||||
|
|
||||||
def test_search_by_semester(self):
|
def test_search_by_semester(self):
|
||||||
self.client.force_login(self.root)
|
self.client.force_login(self.root)
|
||||||
res = self.client.get(self.url + "?semester=SPRING")
|
res = self.client.get(self.url, query_params={"semester": "SPRING"})
|
||||||
assert res.status_code == 200
|
assert res.status_code == 200
|
||||||
codes = {ue["code"] for ue in json.loads(res.content)["results"]}
|
codes = {ue["code"] for ue in res.json()["results"]}
|
||||||
assert codes == {"DA50", "TNEV", "PA00"}
|
assert codes == {"DA50", "TNEV", "PA00"}
|
||||||
|
|
||||||
def test_search_multiple_filters(self):
|
def test_search_multiple_filters(self):
|
||||||
self.client.force_login(self.root)
|
self.client.force_login(self.root)
|
||||||
res = self.client.get(
|
res = self.client.get(
|
||||||
self.url + "?semester=AUTUMN&credit_type=CS&department=TC"
|
self.url,
|
||||||
|
query_params={
|
||||||
|
"semester": "AUTUMN",
|
||||||
|
"credit_type": "CS",
|
||||||
|
"department": "TC",
|
||||||
|
},
|
||||||
)
|
)
|
||||||
assert res.status_code == 200
|
assert res.status_code == 200
|
||||||
codes = {ue["code"] for ue in json.loads(res.content)["results"]}
|
codes = {ue["code"] for ue in res.json()["results"]}
|
||||||
assert codes == {"MT01", "PHYS11"}
|
assert codes == {"MT01", "PHYS11"}
|
||||||
|
|
||||||
def test_search_fails(self):
|
def test_search_fails(self):
|
||||||
self.client.force_login(self.root)
|
self.client.force_login(self.root)
|
||||||
res = self.client.get(self.url + "?credit_type=CS&search=DA")
|
res = self.client.get(
|
||||||
|
self.url, query_params={"search": "DA", "credit_type": "CS"}
|
||||||
|
)
|
||||||
assert res.status_code == 200
|
assert res.status_code == 200
|
||||||
assert json.loads(res.content)["results"] == []
|
assert res.json()["results"] == []
|
||||||
|
|
||||||
|
def test_search_closed_status(self):
|
||||||
|
# Simple heuristic : take a UE, and mark everything before it as closed
|
||||||
|
closed_ue = UE.objects.order_by("id")[2]
|
||||||
|
UE.objects.filter(id__lte=closed_ue.id).update(semester="CLOSED")
|
||||||
|
|
||||||
def test_search_pa00_fail(self):
|
|
||||||
self.client.force_login(self.root)
|
self.client.force_login(self.root)
|
||||||
# Search with UE code
|
|
||||||
response = self.client.get(reverse("pedagogy:guide"), {"search": "IFC"})
|
|
||||||
self.assertNotContains(response, text="PA00")
|
|
||||||
|
|
||||||
# Search with first letter of UE code
|
res = self.client.get(self.url, query_params={"is_open": False})
|
||||||
response = self.client.get(reverse("pedagogy:guide"), {"search": "I"})
|
assert res.status_code == 200
|
||||||
self.assertNotContains(response, text="PA00")
|
ids = {ue["id"] for ue in res.json()["results"]}
|
||||||
|
assert ids == set(
|
||||||
|
UE.objects.filter(semester="CLOSED").values_list("id", flat=True)
|
||||||
|
)
|
||||||
|
|
||||||
# Search with UE manager
|
res = self.client.get(self.url, query_params={"is_open": True})
|
||||||
response = self.client.get(reverse("pedagogy:guide"), {"search": "GILLES"})
|
assert res.status_code == 200
|
||||||
self.assertNotContains(response, text="PA00")
|
ids = {ue["id"] for ue in res.json()["results"]}
|
||||||
|
assert ids == set(
|
||||||
# Search with department
|
UE.objects.exclude(semester="CLOSED").values_list("id", flat=True)
|
||||||
response = self.client.get(reverse("pedagogy:guide"), {"department": "TC"})
|
)
|
||||||
self.assertNotContains(response, text="PA00")
|
|
||||||
|
|
||||||
# Search with semester
|
|
||||||
response = self.client.get(reverse("pedagogy:guide"), {"semester": "CLOSED"})
|
|
||||||
self.assertNotContains(response, text="PA00")
|
|
||||||
|
|
||||||
# Search with language
|
|
||||||
response = self.client.get(reverse("pedagogy:guide"), {"language": "EN"})
|
|
||||||
self.assertNotContains(response, text="PA00")
|
|
||||||
|
|
||||||
# Search with credit type
|
|
||||||
response = self.client.get(reverse("pedagogy:guide"), {"credit_type": "TM"})
|
|
||||||
self.assertNotContains(response, text="PA00")
|
|
||||||
|
|||||||
Reference in New Issue
Block a user