mirror of
https://github.com/ae-utbm/sith.git
synced 2024-11-24 18:14:22 +00:00
add tests
This commit is contained in:
parent
b9d19be183
commit
cb1aa8bef0
32
core/baker_recipes.py
Normal file
32
core/baker_recipes.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
from django.utils.timezone import now
|
||||||
|
from model_bakery import seq
|
||||||
|
from model_bakery.recipe import Recipe, related
|
||||||
|
|
||||||
|
from core.models import User
|
||||||
|
from subscription.models import Subscription
|
||||||
|
|
||||||
|
active_subscription = Recipe(
|
||||||
|
Subscription,
|
||||||
|
subscription_start=now() - timedelta(days=30),
|
||||||
|
subscription_end=now() + timedelta(days=30),
|
||||||
|
)
|
||||||
|
ended_subscription = Recipe(
|
||||||
|
Subscription,
|
||||||
|
subscription_start=now() - timedelta(days=60),
|
||||||
|
subscription_end=now() - timedelta(days=30),
|
||||||
|
)
|
||||||
|
|
||||||
|
subscriber_user = Recipe(
|
||||||
|
User,
|
||||||
|
first_name="subscriber",
|
||||||
|
last_name=seq("user "),
|
||||||
|
subscriptions=related(active_subscription),
|
||||||
|
)
|
||||||
|
old_subscriber_user = Recipe(
|
||||||
|
User,
|
||||||
|
first_name="old subscriber",
|
||||||
|
last_name=seq("user "),
|
||||||
|
subscriptions=related(ended_subscription),
|
||||||
|
)
|
@ -13,7 +13,7 @@ from pedagogy.schemas import SimpleUvSchema, UvFilterSchema, UvSchema
|
|||||||
from pedagogy.utbm_api import find_uv
|
from pedagogy.utbm_api import find_uv
|
||||||
|
|
||||||
|
|
||||||
@api_controller("/uv", permissions=[IsSubscriber])
|
@api_controller("/uv")
|
||||||
class UvController(ControllerBase):
|
class UvController(ControllerBase):
|
||||||
@route.get(
|
@route.get(
|
||||||
"/{year}/{code}",
|
"/{year}/{code}",
|
||||||
@ -31,7 +31,10 @@ class UvController(ControllerBase):
|
|||||||
return res
|
return res
|
||||||
|
|
||||||
@route.get(
|
@route.get(
|
||||||
"", response=PaginatedResponseSchema[SimpleUvSchema], url_name="fetch_uvs"
|
"",
|
||||||
|
response=PaginatedResponseSchema[SimpleUvSchema],
|
||||||
|
url_name="fetch_uvs",
|
||||||
|
permissions=[IsSubscriber | IsInGroup(settings.SITH_GROUP_PEDAGOGY_ADMIN_ID)],
|
||||||
)
|
)
|
||||||
@paginate(PageNumberPaginationExtra, page_size=100)
|
@paginate(PageNumberPaginationExtra, page_size=100)
|
||||||
def fetch_uv_list(self, search: Query[UvFilterSchema]):
|
def fetch_uv_list(self, search: Query[UvFilterSchema]):
|
||||||
|
@ -123,7 +123,7 @@ class UvFilterSchema(FilterSchema):
|
|||||||
def filter_semester(self, value: set[str] | None) -> Q:
|
def filter_semester(self, value: set[str] | None) -> Q:
|
||||||
"""Special filter for the semester.
|
"""Special filter for the semester.
|
||||||
|
|
||||||
If both "SPRING" and "AUTUMN" are given, UV that are available
|
If either "SPRING" or "AUTUMN" is given, UV that are available
|
||||||
during "AUTUMN_AND_SPRING" will be filtered.
|
during "AUTUMN_AND_SPRING" will be filtered.
|
||||||
"""
|
"""
|
||||||
if not value:
|
if not value:
|
||||||
|
@ -125,8 +125,6 @@
|
|||||||
|
|
||||||
function update_query_string(key, value) {
|
function update_query_string(key, value) {
|
||||||
const url = new URL(window.location.href);
|
const url = new URL(window.location.href);
|
||||||
console.log(value)
|
|
||||||
console.log(!!value)
|
|
||||||
if (!value) {
|
if (!value) {
|
||||||
url.searchParams.delete(key)
|
url.searchParams.delete(key)
|
||||||
} else if (Array.isArray(value)) {
|
} else if (Array.isArray(value)) {
|
||||||
|
0
pedagogy/tests/__init__.py
Normal file
0
pedagogy/tests/__init__.py
Normal file
165
pedagogy/tests/test_api.py
Normal file
165
pedagogy/tests/test_api.py
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.test import TestCase
|
||||||
|
from django.urls import reverse
|
||||||
|
from model_bakery import baker
|
||||||
|
from model_bakery.recipe import Recipe
|
||||||
|
|
||||||
|
from core.baker_recipes import subscriber_user
|
||||||
|
from core.models import RealGroup, User
|
||||||
|
from pedagogy.models import UV
|
||||||
|
|
||||||
|
|
||||||
|
class UVSearchTest(TestCase):
|
||||||
|
"""Test UV guide rights for view and API."""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpTestData(cls):
|
||||||
|
cls.root = User.objects.get(username="root")
|
||||||
|
cls.url = reverse("api:fetch_uvs")
|
||||||
|
uv_recipe = Recipe(UV, author=cls.root)
|
||||||
|
uvs = [
|
||||||
|
uv_recipe.prepare(
|
||||||
|
code="AP4A", credit_type="CS", semester="AUTUMN", department="GI"
|
||||||
|
),
|
||||||
|
uv_recipe.prepare(
|
||||||
|
code="MT01", credit_type="CS", semester="AUTUMN", department="TC"
|
||||||
|
),
|
||||||
|
uv_recipe.prepare(
|
||||||
|
code="PHYS11", credit_type="CS", semester="AUTUMN", department="TC"
|
||||||
|
),
|
||||||
|
uv_recipe.prepare(
|
||||||
|
code="TNEV", credit_type="TM", semester="SPRING", department="TC"
|
||||||
|
),
|
||||||
|
uv_recipe.prepare(
|
||||||
|
code="MT10", credit_type="TM", semester="AUTUMN", department="IMSI"
|
||||||
|
),
|
||||||
|
uv_recipe.prepare(
|
||||||
|
code="DA50",
|
||||||
|
credit_type="TM",
|
||||||
|
semester="AUTUMN_AND_SPRING",
|
||||||
|
department="GI",
|
||||||
|
),
|
||||||
|
]
|
||||||
|
UV.objects.bulk_create(uvs)
|
||||||
|
|
||||||
|
def test_permissions(self):
|
||||||
|
# Test with anonymous user
|
||||||
|
response = self.client.get(self.url)
|
||||||
|
assert response.status_code == 403
|
||||||
|
|
||||||
|
# Test with not subscribed user
|
||||||
|
self.client.force_login(baker.make(User))
|
||||||
|
response = self.client.get(self.url)
|
||||||
|
assert response.status_code == 403
|
||||||
|
|
||||||
|
for user in (
|
||||||
|
self.root,
|
||||||
|
subscriber_user.make(),
|
||||||
|
baker.make(
|
||||||
|
User,
|
||||||
|
groups=[
|
||||||
|
RealGroup.objects.get(pk=settings.SITH_GROUP_PEDAGOGY_ADMIN_ID)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
):
|
||||||
|
# users that have right
|
||||||
|
with self.subTest():
|
||||||
|
self.client.force_login(user)
|
||||||
|
response = self.client.get(self.url)
|
||||||
|
assert response.status_code == 200
|
||||||
|
|
||||||
|
def test_format(self):
|
||||||
|
"""Test that the return data format is correct"""
|
||||||
|
self.client.force_login(self.root)
|
||||||
|
res = self.client.get(self.url + "?search=PA00")
|
||||||
|
uv = UV.objects.get(code="PA00")
|
||||||
|
assert res.status_code == 200
|
||||||
|
assert json.loads(res.content) == {
|
||||||
|
"count": 1,
|
||||||
|
"next": None,
|
||||||
|
"previous": None,
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"id": uv.id,
|
||||||
|
"title": uv.title,
|
||||||
|
"code": uv.code,
|
||||||
|
"credit_type": uv.credit_type,
|
||||||
|
"semester": uv.semester,
|
||||||
|
"department": uv.department,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
def test_search_by_code(self):
|
||||||
|
self.client.force_login(self.root)
|
||||||
|
res = self.client.get(self.url + "?search=MT")
|
||||||
|
assert res.status_code == 200
|
||||||
|
assert {uv["code"] for uv in json.loads(res.content)["results"]} == {
|
||||||
|
"MT01",
|
||||||
|
"MT10",
|
||||||
|
}
|
||||||
|
|
||||||
|
def test_search_by_credit_type(self):
|
||||||
|
self.client.force_login(self.root)
|
||||||
|
res = self.client.get(self.url + "?credit_type=CS")
|
||||||
|
assert res.status_code == 200
|
||||||
|
codes = [uv["code"] for uv in json.loads(res.content)["results"]]
|
||||||
|
assert codes == ["AP4A", "MT01", "PHYS11"]
|
||||||
|
res = self.client.get(self.url + "?credit_type=CS&credit_type=OM")
|
||||||
|
assert res.status_code == 200
|
||||||
|
codes = {uv["code"] for uv in json.loads(res.content)["results"]}
|
||||||
|
assert codes == {"AP4A", "MT01", "PHYS11", "PA00"}
|
||||||
|
|
||||||
|
def test_search_by_semester(self):
|
||||||
|
self.client.force_login(self.root)
|
||||||
|
res = self.client.get(self.url + "?semester=SPRING")
|
||||||
|
assert res.status_code == 200
|
||||||
|
codes = {uv["code"] for uv in json.loads(res.content)["results"]}
|
||||||
|
assert codes == {"DA50", "TNEV", "PA00"}
|
||||||
|
|
||||||
|
def test_search_multiple_filters(self):
|
||||||
|
self.client.force_login(self.root)
|
||||||
|
res = self.client.get(
|
||||||
|
self.url + "?semester=AUTUMN&credit_type=CS&department=TC"
|
||||||
|
)
|
||||||
|
assert res.status_code == 200
|
||||||
|
codes = {uv["code"] for uv in json.loads(res.content)["results"]}
|
||||||
|
assert codes == {"MT01", "PHYS11"}
|
||||||
|
|
||||||
|
def test_search_fails(self):
|
||||||
|
self.client.force_login(self.root)
|
||||||
|
res = self.client.get(self.url + "?credit_type=CS&search=DA")
|
||||||
|
assert res.status_code == 200
|
||||||
|
assert json.loads(res.content)["results"] == []
|
||||||
|
|
||||||
|
def test_search_pa00_fail(self):
|
||||||
|
self.client.force_login(self.root)
|
||||||
|
# Search with UV code
|
||||||
|
response = self.client.get(reverse("pedagogy:guide"), {"search": "IFC"})
|
||||||
|
self.assertNotContains(response, text="PA00")
|
||||||
|
|
||||||
|
# Search with first letter of UV code
|
||||||
|
response = self.client.get(reverse("pedagogy:guide"), {"search": "I"})
|
||||||
|
self.assertNotContains(response, text="PA00")
|
||||||
|
|
||||||
|
# Search with UV manager
|
||||||
|
response = self.client.get(reverse("pedagogy:guide"), {"search": "GILLES"})
|
||||||
|
self.assertNotContains(response, text="PA00")
|
||||||
|
|
||||||
|
# Search with department
|
||||||
|
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")
|
@ -20,7 +20,6 @@
|
|||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
import json
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
@ -555,157 +554,6 @@ class UVCommentUpdateTest(TestCase):
|
|||||||
self.assertEqual(self.comment.author, self.krophil)
|
self.assertEqual(self.comment.author, self.krophil)
|
||||||
|
|
||||||
|
|
||||||
class UVSearchTest(TestCase):
|
|
||||||
"""Test UV guide rights for view and API."""
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def setUpTestData(cls):
|
|
||||||
cls.bibou = User.objects.get(username="root")
|
|
||||||
cls.tutu = User.objects.get(username="tutu")
|
|
||||||
cls.sli = User.objects.get(username="sli")
|
|
||||||
cls.guy = User.objects.get(username="guy")
|
|
||||||
cls.url = reverse("api:fetch_uvs")
|
|
||||||
uvs = [
|
|
||||||
UV(code="AP4A", credit_type="CS", semester="AUTUMN", department="GI"),
|
|
||||||
UV(code="MT01", credit_type="CS", semester="AUTUMN", department="TC"),
|
|
||||||
UV(code="PHYS11", credit_type="CS", semester="AUTUMN", department="TC"),
|
|
||||||
UV(code="TNEV", credit_type="TM", semester="SPRING", department="TC"),
|
|
||||||
UV(code="MT10", credit_type="TM", semester="AUTUMN", department="IMSI"),
|
|
||||||
UV(
|
|
||||||
code="DA50",
|
|
||||||
credit_type="TM",
|
|
||||||
semester="AUTUMN_AND_SPRING",
|
|
||||||
department="GI",
|
|
||||||
),
|
|
||||||
]
|
|
||||||
for uv in uvs:
|
|
||||||
uv.author = cls.bibou
|
|
||||||
uv.title = ""
|
|
||||||
uv.manager = ""
|
|
||||||
uv.language = "FR"
|
|
||||||
uv.objectives = ""
|
|
||||||
uv.program = ""
|
|
||||||
uv.skills = ""
|
|
||||||
uv.key_concepts = ""
|
|
||||||
uv.credits = 6
|
|
||||||
UV.objects.bulk_create(uvs)
|
|
||||||
|
|
||||||
def fetch_uvs(self, **kwargs):
|
|
||||||
params = "&".join(f"{key}={val}" for key, val in kwargs.items())
|
|
||||||
return json.loads(f"{self.url}?{params}")
|
|
||||||
|
|
||||||
def test_permissions(self):
|
|
||||||
# Test with anonymous user
|
|
||||||
response = self.client.get(self.url)
|
|
||||||
assert response.status_code == 403
|
|
||||||
|
|
||||||
# Test with not subscribed user
|
|
||||||
self.client.force_login(self.guy)
|
|
||||||
response = self.client.get(self.url)
|
|
||||||
assert response.status_code == 403
|
|
||||||
|
|
||||||
for user in self.bibou, self.tutu, self.sli:
|
|
||||||
# users that have right
|
|
||||||
with self.subTest():
|
|
||||||
self.client.force_login(user)
|
|
||||||
response = self.client.get(self.url)
|
|
||||||
assert response.status_code == 200
|
|
||||||
|
|
||||||
def test_format(self):
|
|
||||||
"""Test that the return data format is correct"""
|
|
||||||
self.client.force_login(self.bibou)
|
|
||||||
res = self.client.get(self.url + "?search=PA00")
|
|
||||||
uv = UV.objects.get(code="PA00")
|
|
||||||
assert res.status_code == 200
|
|
||||||
assert json.loads(res.content) == {
|
|
||||||
"count": 1,
|
|
||||||
"next": None,
|
|
||||||
"previous": None,
|
|
||||||
"results": [
|
|
||||||
{
|
|
||||||
"id": uv.id,
|
|
||||||
"title": uv.title,
|
|
||||||
"code": uv.code,
|
|
||||||
"credit_type": uv.credit_type,
|
|
||||||
"semester": uv.semester,
|
|
||||||
"department": uv.department,
|
|
||||||
}
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
def test_search_by_code(self):
|
|
||||||
self.client.force_login(self.bibou)
|
|
||||||
res = self.client.get(self.url + "?search=MT")
|
|
||||||
assert res.status_code == 200
|
|
||||||
assert {uv["code"] for uv in json.loads(res.content)["results"]} == {
|
|
||||||
"MT01",
|
|
||||||
"MT10",
|
|
||||||
}
|
|
||||||
|
|
||||||
def test_search_by_credit_type(self):
|
|
||||||
self.client.force_login(self.bibou)
|
|
||||||
res = self.client.get(self.url + "?credit_type=CS")
|
|
||||||
assert res.status_code == 200
|
|
||||||
codes = [uv["code"] for uv in json.loads(res.content)["results"]]
|
|
||||||
assert codes == ["AP4A", "MT01", "PHYS11"]
|
|
||||||
res = self.client.get(self.url + "?credit_type=CS&credit_type=OM")
|
|
||||||
assert res.status_code == 200
|
|
||||||
codes = {uv["code"] for uv in json.loads(res.content)["results"]}
|
|
||||||
assert codes == {"AP4A", "MT01", "PHYS11", "PA00"}
|
|
||||||
|
|
||||||
def test_search_by_semester(self):
|
|
||||||
self.client.force_login(self.bibou)
|
|
||||||
res = self.client.get(self.url + "?semester=SPRING")
|
|
||||||
assert res.status_code == 200
|
|
||||||
codes = {uv["code"] for uv in json.loads(res.content)["results"]}
|
|
||||||
assert codes == {"DA50", "TNEV", "PA00"}
|
|
||||||
|
|
||||||
def test_search_multiple_filters(self):
|
|
||||||
self.client.force_login(self.bibou)
|
|
||||||
res = self.client.get(
|
|
||||||
self.url + "?semester=AUTUMN&credit_type=CS&department=TC"
|
|
||||||
)
|
|
||||||
assert res.status_code == 200
|
|
||||||
codes = {uv["code"] for uv in json.loads(res.content)["results"]}
|
|
||||||
assert codes == {"MT01", "PHYS11"}
|
|
||||||
|
|
||||||
def test_search_fails(self):
|
|
||||||
self.client.force_login(self.bibou)
|
|
||||||
res = self.client.get(self.url + "?credit_type=CS&search=DA")
|
|
||||||
assert res.status_code == 200
|
|
||||||
assert json.loads(res.content)["results"] == []
|
|
||||||
|
|
||||||
def test_search_pa00_fail(self):
|
|
||||||
self.client.force_login(self.bibou)
|
|
||||||
# Search with UV code
|
|
||||||
response = self.client.get(reverse("pedagogy:guide"), {"search": "IFC"})
|
|
||||||
self.assertNotContains(response, text="PA00")
|
|
||||||
|
|
||||||
# Search with first letter of UV code
|
|
||||||
response = self.client.get(reverse("pedagogy:guide"), {"search": "I"})
|
|
||||||
self.assertNotContains(response, text="PA00")
|
|
||||||
|
|
||||||
# Search with UV manager
|
|
||||||
response = self.client.get(reverse("pedagogy:guide"), {"search": "GILLES"})
|
|
||||||
self.assertNotContains(response, text="PA00")
|
|
||||||
|
|
||||||
# Search with department
|
|
||||||
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")
|
|
||||||
|
|
||||||
|
|
||||||
class UVModerationFormTest(TestCase):
|
class UVModerationFormTest(TestCase):
|
||||||
"""Assert access rights and if the form works well."""
|
"""Assert access rights and if the form works well."""
|
||||||
|
|
20
poetry.lock
generated
20
poetry.lock
generated
@ -1225,6 +1225,24 @@ files = [
|
|||||||
griffe = ">=0.47"
|
griffe = ">=0.47"
|
||||||
mkdocstrings = ">=0.25"
|
mkdocstrings = ">=0.25"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "model-bakery"
|
||||||
|
version = "1.18.2"
|
||||||
|
description = "Smart object creation facility for Django."
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.8"
|
||||||
|
files = [
|
||||||
|
{file = "model_bakery-1.18.2-py3-none-any.whl", hash = "sha256:fd13a251d20db78b790d80f75350a73af5d199e5151227b5dd35cb76f2f08fe8"},
|
||||||
|
{file = "model_bakery-1.18.2.tar.gz", hash = "sha256:8f8ab4ba26a206ed848da9b1740b5006b5eeca8a67389efb28dbff37b362e802"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
django = ">=4.2"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
docs = ["myst-parser", "sphinx", "sphinx-rtd-theme"]
|
||||||
|
test = ["black", "coverage", "mypy", "pillow", "pytest", "pytest-django", "ruff"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nodeenv"
|
name = "nodeenv"
|
||||||
version = "1.9.1"
|
version = "1.9.1"
|
||||||
@ -2454,4 +2472,4 @@ filelock = ">=3.4"
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = "^3.10"
|
python-versions = "^3.10"
|
||||||
content-hash = "ee0b881719f6834880266d72272429708e781b3ccd34a0fbf3e8b4119dcb95fd"
|
content-hash = "f8e48947d004d61d63a345d36d7b42777030e1ac3687bb27f97b2c51318fcc8d"
|
||||||
|
@ -67,6 +67,7 @@ freezegun = "^1.2.2" # used to test time-dependent code
|
|||||||
pytest = "^8.2.2"
|
pytest = "^8.2.2"
|
||||||
pytest-cov = "^5.0.0"
|
pytest-cov = "^5.0.0"
|
||||||
pytest-django = "^4.8.0"
|
pytest-django = "^4.8.0"
|
||||||
|
model-bakery = "^1.18.2"
|
||||||
|
|
||||||
# deps used to work on the documentation
|
# deps used to work on the documentation
|
||||||
[tool.poetry.group.docs.dependencies]
|
[tool.poetry.group.docs.dependencies]
|
||||||
|
@ -33,8 +33,12 @@ class SasController(ControllerBase):
|
|||||||
# User can view any moderated picture if he/she is subscribed.
|
# User can view any moderated picture if he/she is subscribed.
|
||||||
# If not, he/she can view only the one he/she has been identified on
|
# If not, he/she can view only the one he/she has been identified on
|
||||||
raise PermissionDenied
|
raise PermissionDenied
|
||||||
pictures = filters.filter(
|
pictures = list(
|
||||||
Picture.objects.filter(is_moderated=True, asked_for_removal=False)
|
filters.filter(
|
||||||
|
Picture.objects.filter(is_moderated=True, asked_for_removal=False)
|
||||||
|
)
|
||||||
|
.distinct()
|
||||||
|
.order_by("-date")
|
||||||
)
|
)
|
||||||
for picture in pictures:
|
for picture in pictures:
|
||||||
picture.full_size_url = picture.get_download_url()
|
picture.full_size_url = picture.get_download_url()
|
||||||
|
0
sas/tests/__init__.py
Normal file
0
sas/tests/__init__.py
Normal file
103
sas/tests/test_api.py
Normal file
103
sas/tests/test_api.py
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
from django.test import TestCase
|
||||||
|
from django.urls import reverse
|
||||||
|
from model_bakery import baker
|
||||||
|
from model_bakery.recipe import Recipe
|
||||||
|
|
||||||
|
from core.baker_recipes import old_subscriber_user, subscriber_user
|
||||||
|
from core.models import User
|
||||||
|
from sas.models import Album, PeoplePictureRelation, Picture
|
||||||
|
|
||||||
|
|
||||||
|
class SasTest(TestCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpTestData(cls):
|
||||||
|
Picture.objects.all().delete()
|
||||||
|
owner = User.objects.get(username="root")
|
||||||
|
|
||||||
|
cls.user_a = old_subscriber_user.make()
|
||||||
|
cls.user_b, cls.user_c = subscriber_user.make(_quantity=2)
|
||||||
|
|
||||||
|
picture_recipe = Recipe(
|
||||||
|
Picture, is_in_sas=True, is_folder=False, owner=owner, is_moderated=True
|
||||||
|
)
|
||||||
|
cls.album_a = baker.make(Album, is_in_sas=True)
|
||||||
|
cls.album_b = baker.make(Album, is_in_sas=True)
|
||||||
|
for album in cls.album_a, cls.album_b:
|
||||||
|
pictures = picture_recipe.make(parent=album, _quantity=5, _bulk_create=True)
|
||||||
|
baker.make(PeoplePictureRelation, picture=pictures[1], user=cls.user_a)
|
||||||
|
baker.make(PeoplePictureRelation, picture=pictures[2], user=cls.user_a)
|
||||||
|
baker.make(PeoplePictureRelation, picture=pictures[2], user=cls.user_b)
|
||||||
|
baker.make(PeoplePictureRelation, picture=pictures[3], user=cls.user_b)
|
||||||
|
baker.make(PeoplePictureRelation, picture=pictures[4], user=cls.user_a)
|
||||||
|
baker.make(PeoplePictureRelation, picture=pictures[4], user=cls.user_b)
|
||||||
|
baker.make(PeoplePictureRelation, picture=pictures[4], user=cls.user_c)
|
||||||
|
|
||||||
|
def test_anonymous_user_forbidden(self):
|
||||||
|
res = self.client.get(reverse("api:pictures"))
|
||||||
|
assert res.status_code == 403
|
||||||
|
|
||||||
|
def test_filter_by_album(self):
|
||||||
|
self.client.force_login(self.user_b)
|
||||||
|
res = self.client.get(reverse("api:pictures") + f"?album_id={self.album_a.id}")
|
||||||
|
assert res.status_code == 200
|
||||||
|
expected = list(
|
||||||
|
self.album_a.children_pictures.order_by("-date").values_list(
|
||||||
|
"id", flat=True
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assert [i["id"] for i in res.json()] == expected
|
||||||
|
|
||||||
|
def test_filter_by_user(self):
|
||||||
|
self.client.force_login(self.user_b)
|
||||||
|
res = self.client.get(
|
||||||
|
reverse("api:pictures") + f"?users_identified={self.user_a.id}"
|
||||||
|
)
|
||||||
|
assert res.status_code == 200
|
||||||
|
expected = list(
|
||||||
|
self.user_a.pictures.order_by("-picture__date").values_list(
|
||||||
|
"picture_id", flat=True
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assert [i["id"] for i in res.json()] == expected
|
||||||
|
|
||||||
|
def test_filter_by_multiple_user(self):
|
||||||
|
self.client.force_login(self.user_b)
|
||||||
|
res = self.client.get(
|
||||||
|
reverse("api:pictures")
|
||||||
|
+ f"?users_identified={self.user_a.id}&users_identified={self.user_b.id}"
|
||||||
|
)
|
||||||
|
assert res.status_code == 200
|
||||||
|
expected = list(
|
||||||
|
self.user_a.pictures.union(self.user_b.pictures.all())
|
||||||
|
.order_by("-picture__date")
|
||||||
|
.values_list("picture_id", flat=True)
|
||||||
|
)
|
||||||
|
assert [i["id"] for i in res.json()] == expected
|
||||||
|
|
||||||
|
def test_not_subscribed_user(self):
|
||||||
|
"""Test that a user that is not subscribed can only its own pictures."""
|
||||||
|
self.client.force_login(self.user_a)
|
||||||
|
res = self.client.get(
|
||||||
|
reverse("api:pictures") + f"?users_identified={self.user_a.id}"
|
||||||
|
)
|
||||||
|
assert res.status_code == 200
|
||||||
|
expected = list(
|
||||||
|
self.user_a.pictures.order_by("-picture__date").values_list(
|
||||||
|
"picture_id", flat=True
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assert [i["id"] for i in res.json()] == expected
|
||||||
|
|
||||||
|
# trying to access the pictures of someone else
|
||||||
|
res = self.client.get(
|
||||||
|
reverse("api:pictures") + f"?users_identified={self.user_b.id}"
|
||||||
|
)
|
||||||
|
assert res.status_code == 403
|
||||||
|
|
||||||
|
# trying to access the pictures of someone else shouldn't success,
|
||||||
|
# even if mixed with owned pictures
|
||||||
|
res = self.client.get(
|
||||||
|
reverse("api:pictures")
|
||||||
|
+ f"?users_identified={self.user_a.id}&users_identified={self.user_b.id}"
|
||||||
|
)
|
||||||
|
assert res.status_code == 403
|
Loading…
Reference in New Issue
Block a user