diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 74f18dd6..5e3f8cd9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,12 +25,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - uses: ./.github/actions/setup_project - uses: ./.github/actions/setup_xapian - uses: ./.github/actions/compile_messages - name: Run tests - run: poetry run coverage run ./manage.py test + run: poetry run coverage run -m pytest - name: Generate coverage report run: | poetry run coverage report diff --git a/accounting/tests.py b/accounting/tests.py index 28c7a420..0ea7a29e 100644 --- a/accounting/tests.py +++ b/accounting/tests.py @@ -30,71 +30,66 @@ from core.models import User class RefoundAccountTest(TestCase): - def setUp(self): - self.skia = User.objects.filter(username="skia").first() + @classmethod + def setUpTestData(cls): + cls.skia = User.objects.get(username="skia") # reffil skia's account - self.skia.customer.amount = 800 - self.skia.customer.save() + cls.skia.customer.amount = 800 + cls.skia.customer.save() + cls.refound_account_url = reverse("accounting:refound_account") def test_permission_denied(self): - self.client.login(username="guy", password="plop") + self.client.force_login(User.objects.get(username="guy")) response_post = self.client.post( - reverse("accounting:refound_account"), {"user": self.skia.id} + self.refound_account_url, {"user": self.skia.id} ) - response_get = self.client.get(reverse("accounting:refound_account")) - self.assertTrue(response_get.status_code == 403) - self.assertTrue(response_post.status_code == 403) + response_get = self.client.get(self.refound_account_url) + assert response_get.status_code == 403 + assert response_post.status_code == 403 def test_root_granteed(self): - self.client.login(username="root", password="plop") - response_post = self.client.post( - reverse("accounting:refound_account"), {"user": self.skia.id} - ) - self.skia = User.objects.filter(username="skia").first() - response_get = self.client.get(reverse("accounting:refound_account")) - self.assertFalse(response_get.status_code == 403) - self.assertTrue('
' in str(response_get.content)) - self.assertFalse(response_post.status_code == 403) - self.assertTrue(self.skia.customer.amount == 0) + self.client.force_login(User.objects.get(username="root")) + response = self.client.post(self.refound_account_url, {"user": self.skia.id}) + self.assertRedirects(response, self.refound_account_url) + self.skia.refresh_from_db() + response = self.client.get(self.refound_account_url) + assert response.status_code == 200 + assert '' in str(response.content) + assert self.skia.customer.amount == 0 def test_comptable_granteed(self): - self.client.login(username="comptable", password="plop") - response_post = self.client.post( - reverse("accounting:refound_account"), {"user": self.skia.id} - ) - self.skia = User.objects.filter(username="skia").first() - response_get = self.client.get(reverse("accounting:refound_account")) - self.assertFalse(response_get.status_code == 403) - self.assertTrue('' in str(response_get.content)) - self.assertFalse(response_post.status_code == 403) - self.assertTrue(self.skia.customer.amount == 0) + self.client.force_login(User.objects.get(username="comptable")) + response = self.client.post(self.refound_account_url, {"user": self.skia.id}) + self.assertRedirects(response, self.refound_account_url) + self.skia.refresh_from_db() + response = self.client.get(self.refound_account_url) + assert response.status_code == 200 + assert '' in str(response.content) + assert self.skia.customer.amount == 0 class JournalTest(TestCase): - def setUp(self): - self.journal = GeneralJournal.objects.filter(id=1).first() + @classmethod + def setUpTestData(cls): + cls.journal = GeneralJournal.objects.get(id=1) def test_permission_granted(self): - self.client.login(username="comptable", password="plop") + self.client.force_login(User.objects.get(username="comptable")) response_get = self.client.get( reverse("accounting:journal_details", args=[self.journal.id]) ) - self.assertTrue(response_get.status_code == 200) - self.assertTrue( - "M\\xc3\\xa9thode de paiement" in str(response_get.content) - ) + assert response_get.status_code == 200 + assert "M\\xc3\\xa9thode de paiement" in str(response_get.content) def test_permission_not_granted(self): - self.client.login(username="skia", password="plop") + self.client.force_login(User.objects.get(username="skia")) response_get = self.client.get( reverse("accounting:journal_details", args=[self.journal.id]) ) - self.assertTrue(response_get.status_code == 403) - self.assertFalse( - "M\xc3\xa9thode de paiement" in str(response_get.content) - ) + assert response_get.status_code == 403 + assert "M\xc3\xa9thode de paiement" not in str(response_get.content) class OperationTest(TestCase): @@ -108,9 +103,8 @@ class OperationTest(TestCase): code="443", label="Ce code n'existe pas", movement_type="CREDIT" ) at.save() - l = Label(club_account=self.journal.club_account, name="bob") - l.save() - self.client.login(username="comptable", password="plop") + l = Label.objects.create(club_account=self.journal.club_account, name="bob") + self.client.force_login(User.objects.get(username="comptable")) self.op1 = Operation( journal=self.journal, date=date.today(), @@ -139,8 +133,7 @@ class OperationTest(TestCase): self.op2.save() def test_new_operation(self): - self.client.login(username="comptable", password="plop") - at = AccountingType.objects.filter(code="604").first() + at = AccountingType.objects.get(code="604") response = self.client.post( reverse("accounting:op_new", args=[self.journal.id]), { @@ -172,8 +165,7 @@ class OperationTest(TestCase): self.assertTrue("Le fantome de la nuit" in str(response_get.content)) def test_bad_new_operation(self): - self.client.login(username="comptable", password="plop") - AccountingType.objects.filter(code="604").first() + AccountingType.objects.get(code="604") response = self.client.post( reverse("accounting:op_new", args=[self.journal.id]), { @@ -199,7 +191,7 @@ class OperationTest(TestCase): ) def test_new_operation_not_authorized(self): - self.client.login(username="skia", password="plop") + self.client.force_login(self.skia) at = AccountingType.objects.filter(code="604").first() response = self.client.post( reverse("accounting:op_new", args=[self.journal.id]), @@ -226,7 +218,6 @@ class OperationTest(TestCase): ) def test__operation_simple_accounting(self): - self.client.login(username="comptable", password="plop") sat = SimplifiedAccountingType.objects.all().first() response = self.client.post( reverse("accounting:op_new", args=[self.journal.id]), @@ -263,14 +254,12 @@ class OperationTest(TestCase): ) def test_nature_statement(self): - self.client.login(username="comptable", password="plop") response = self.client.get( reverse("accounting:journal_nature_statement", args=[self.journal.id]) ) self.assertContains(response, "bob (Troll Penché) : 3.00", status_code=200) def test_person_statement(self): - self.client.login(username="comptable", password="plop") response = self.client.get( reverse("accounting:journal_person_statement", args=[self.journal.id]) ) @@ -292,7 +281,6 @@ class OperationTest(TestCase): ) def test_accounting_statement(self): - self.client.login(username="comptable", password="plop") response = self.client.get( reverse("accounting:journal_accounting_statement", args=[self.journal.id]) ) diff --git a/club/tests.py b/club/tests.py index 73480979..21285ade 100644 --- a/club/tests.py +++ b/club/tests.py @@ -19,7 +19,7 @@ from django.conf import settings from django.core.cache import cache from django.test import TestCase from django.urls import reverse -from django.utils import html, timezone +from django.utils import timezone from django.utils.timezone import localtime, now from django.utils.translation import gettext as _ @@ -49,6 +49,7 @@ class ClubTest(TestCase): cls.richard = User.objects.get(username="rbatsbak") cls.comptable = User.objects.get(username="comptable") cls.sli = User.objects.get(username="sli") + cls.root = User.objects.get(username="root") # subscribed users - not initial members cls.krophil = User.objects.get(username="krophil") @@ -102,45 +103,42 @@ class MembershipQuerySetTest(ClubTest): Test that the ongoing queryset method returns the memberships that are not ended. """ - current_members = self.club.members.ongoing() + current_members = list(self.club.members.ongoing().order_by("id")) expected = [ self.skia.memberships.get(club=self.club), self.comptable.memberships.get(club=self.club), self.richard.memberships.get(club=self.club), ] - self.assertEqual(len(current_members), len(expected)) - for member in current_members: - self.assertIn(member, expected) + expected.sort(key=lambda i: i.id) + assert current_members == expected def test_board(self): """ Test that the board queryset method returns the memberships of user in the club board """ - board_members = list(self.club.members.board()) + board_members = list(self.club.members.board().order_by("id")) expected = [ self.skia.memberships.get(club=self.club), self.comptable.memberships.get(club=self.club), # sli is no more member, but he was in the board self.sli.memberships.get(club=self.club), ] - self.assertEqual(len(board_members), len(expected)) - for member in board_members: - self.assertIn(member, expected) + expected.sort(key=lambda i: i.id) + assert board_members == expected def test_ongoing_board(self): """ Test that combining ongoing and board returns users who are currently board members of the club """ - members = list(self.club.members.ongoing().board()) + members = list(self.club.members.ongoing().board().order_by("id")) expected = [ self.skia.memberships.get(club=self.club), self.comptable.memberships.get(club=self.club), ] - self.assertEqual(len(members), len(expected)) - for member in members: - self.assertIn(member, expected) + expected.sort(key=lambda i: i.id) + assert members == expected def test_update_invalidate_cache(self): """ @@ -149,8 +147,9 @@ class MembershipQuerySetTest(ClubTest): mem_skia = self.skia.memberships.get(club=self.club) cache.set(f"membership_{mem_skia.club_id}_{mem_skia.user_id}", mem_skia) self.skia.memberships.update(end_date=localtime(now()).date()) - self.assertEqual( - cache.get(f"membership_{mem_skia.club_id}_{mem_skia.user_id}"), "not_member" + assert ( + cache.get(f"membership_{mem_skia.club_id}_{mem_skia.user_id}") + == "not_member" ) mem_richard = self.richard.memberships.get(club=self.club) @@ -159,8 +158,8 @@ class MembershipQuerySetTest(ClubTest): ) self.richard.memberships.update(role=5) new_mem = self.richard.memberships.get(club=self.club) - self.assertNotEqual(new_mem, "not_member") - self.assertEqual(new_mem.role, 5) + assert new_mem != "not_member" + assert new_mem.role == 5 def test_delete_invalidate_cache(self): """ @@ -177,40 +176,39 @@ class MembershipQuerySetTest(ClubTest): # should delete the subscriptions of skia and comptable self.club.members.ongoing().board().delete() - self.assertEqual( - cache.get(f"membership_{mem_skia.club_id}_{mem_skia.user_id}"), "not_member" + assert ( + cache.get(f"membership_{mem_skia.club_id}_{mem_skia.user_id}") + == "not_member" ) - self.assertEqual( - cache.get(f"membership_{mem_comptable.club_id}_{mem_comptable.user_id}"), - "not_member", + assert ( + cache.get(f"membership_{mem_comptable.club_id}_{mem_comptable.user_id}") + == "not_member", ) class ClubModelTest(ClubTest): - def assert_membership_just_started(self, user: User, role: int): + def assert_membership_started_today(self, user: User, role: int): """ Assert that the given membership is active and started today """ membership = user.memberships.ongoing().filter(club=self.club).first() - self.assertIsNotNone(membership) - self.assertEqual(localtime(now()).date(), membership.start_date) - self.assertIsNone(membership.end_date) - self.assertEqual(membership.role, role) - self.assertEqual(membership.club.get_membership_for(user), membership) + assert membership is not None + assert localtime(now()).date() == membership.start_date + assert membership.end_date is None + assert membership.role == role + assert membership.club.get_membership_for(user) == membership member_group = self.club.unix_name + settings.SITH_MEMBER_SUFFIX board_group = self.club.unix_name + settings.SITH_BOARD_SUFFIX - self.assertTrue(user.is_in_group(name=member_group)) - self.assertTrue(user.is_in_group(name=board_group)) + assert user.is_in_group(name=member_group) + assert user.is_in_group(name=board_group) - def assert_membership_just_ended(self, user: User): + def assert_membership_ended_today(self, user: User): """ Assert that the given user have a membership which ended today """ today = localtime(now()).date() - self.assertIsNotNone( - user.memberships.filter(club=self.club, end_date=today).first() - ) - self.assertIsNone(self.club.get_membership_for(user)) + assert user.memberships.filter(club=self.club, end_date=today).exists() + assert self.club.get_membership_for(user) is None def test_access_unauthorized(self): """ @@ -218,20 +216,20 @@ class ClubModelTest(ClubTest): cannot see the page """ response = self.client.post(self.members_url) - self.assertEqual(response.status_code, 403) + assert response.status_code == 403 - self.client.login(username="public", password="plop") + self.client.force_login(self.public) response = self.client.post(self.members_url) - self.assertEqual(response.status_code, 403) + assert response.status_code == 403 def test_display(self): """ Test that a GET request return a page where the requested information are displayed. """ - self.client.login(username=self.skia.username, password="plop") + self.client.force_login(self.skia) response = self.client.get(self.members_url) - self.assertEqual(response.status_code, 200) + assert response.status_code == 200 expected_html = ( "" "" @@ -264,20 +262,20 @@ class ClubModelTest(ClubTest): """ Test that root users can add members to clubs, one at a time """ - self.client.login(username="root", password="plop") + self.client.force_login(self.root) response = self.client.post( self.members_url, {"users": self.subscriber.id, "role": 3}, ) self.assertRedirects(response, self.members_url) self.subscriber.refresh_from_db() - self.assert_membership_just_started(self.subscriber, role=3) + self.assert_membership_started_today(self.subscriber, role=3) def test_root_add_multiple_club_member(self): """ Test that root users can add multiple members at once to clubs """ - self.client.login(username="root", password="plop") + self.client.force_login(self.root) response = self.client.post( self.members_url, { @@ -287,36 +285,36 @@ class ClubModelTest(ClubTest): ) self.assertRedirects(response, self.members_url) self.subscriber.refresh_from_db() - self.assert_membership_just_started(self.subscriber, role=3) - self.assert_membership_just_started(self.krophil, role=3) + self.assert_membership_started_today(self.subscriber, role=3) + self.assert_membership_started_today(self.krophil, role=3) def test_add_unauthorized_members(self): """ Test that users who are not currently subscribed cannot be members of clubs. """ - self.client.login(username="root", password="plop") + self.client.force_login(self.root) response = self.client.post( self.members_url, {"users": self.public.id, "role": 1}, ) - self.assertIsNone(self.public.memberships.filter(club=self.club).first()) - self.assertTrue('", response.content.decode(), @@ -127,42 +124,37 @@ class EbouticTest(TestCase): "", response.content.decode(), ) - self.assertIn("basket_id", self.client.session) + assert "basket_id" in self.client.session basket = Basket.objects.get(id=self.client.session["basket_id"]) - self.assertEqual(basket.items.count(), 2) + assert basket.items.count() == 2 barbar = basket.items.filter(product_name="Barbar").first() - self.assertIsNotNone(barbar) - self.assertEqual(barbar.quantity, 3) + assert barbar is not None + assert barbar.quantity == 3 cotis = basket.items.filter(product_name="Cotis 2 semestres").first() - self.assertIsNotNone(cotis) - self.assertEqual(cotis.quantity, 1) - self.assertEqual(basket.get_total(), 3 * 1.7 + 28) + assert cotis is not None + assert cotis.quantity == 1 + assert basket.get_total() == 3 * 1.7 + 28 def test_submit_empty_basket(self): - self.client.login(username="subscriber", password="plop") + self.client.force_login(self.subscriber) self.client.cookies["basket_items"] = "[]" response = self.client.get(reverse("eboutic:command")) self.assertRedirects(response, "/eboutic/") def test_submit_invalid_basket(self): - self.client.login(username="subscriber", password="plop") + self.client.force_login(self.subscriber) max_id = Product.objects.aggregate(res=Max("id"))["res"] self.client.cookies["basket_items"] = f"""[ {{"id": {max_id + 1}, "name": "", "quantity": 1, "unit_price": 28}} ]""" response = self.client.get(reverse("eboutic:command")) - self.assertIn( - 'basket_items=""', - self.client.cookies["basket_items"].OutputString(), - ) - self.assertIn( - "Path=/eboutic", - self.client.cookies["basket_items"].OutputString(), - ) + cookie = self.client.cookies["basket_items"].OutputString() + assert 'basket_items=""' in cookie + assert "Path=/eboutic" in cookie self.assertRedirects(response, "/eboutic/") def test_submit_basket_illegal_quantity(self): - self.client.login(username="subscriber", password="plop") + self.client.force_login(self.subscriber) self.client.cookies["basket_items"] = """[ {"id": 4, "name": "Barbar", "quantity": -1, "unit_price": 1.7} ]""" @@ -170,11 +162,11 @@ class EbouticTest(TestCase): self.assertRedirects(response, "/eboutic/") def test_buy_subscribe_product_with_credit_card(self): - self.client.login(username="old_subscriber", password="plop") + self.client.force_login(self.old_subscriber) response = self.client.get( reverse("core:user_profile", kwargs={"user_id": self.old_subscriber.id}) ) - self.assertTrue("Non cotisant" in str(response.content)) + assert "Non cotisant" in str(response.content) self.client.cookies["basket_items"] = """[ {"id": 2, "name": "Cotis 2 semestres", "quantity": 1, "unit_price": 28} ]""" @@ -184,21 +176,21 @@ class EbouticTest(TestCase): response.content.decode(), ) basket = Basket.objects.get(id=self.client.session["basket_id"]) - self.assertEqual(basket.items.count(), 1) + assert basket.items.count() == 1 response = self.client.get(self.generate_bank_valid_answer()) - self.assertTrue(response.status_code == 200) - self.assertTrue(response.content.decode("utf-8") == "Payment successful") + assert response.status_code == 200 + assert response.content.decode("utf-8") == "Payment successful" subscriber = User.objects.get(id=self.old_subscriber.id) - self.assertEqual(subscriber.subscriptions.count(), 2) + assert subscriber.subscriptions.count() == 2 sub = subscriber.subscriptions.order_by("-subscription_end").first() - self.assertTrue(sub.is_valid_now()) - self.assertEqual(sub.member, subscriber) - self.assertEqual(sub.subscription_type, "deux-semestres") - self.assertEqual(sub.location, "EBOUTIC") + assert sub.is_valid_now() + assert sub.member == subscriber + assert sub.subscription_type == "deux-semestres" + assert sub.location == "EBOUTIC" def test_buy_refill_product_with_credit_card(self): - self.client.login(username="subscriber", password="plop") + self.client.force_login(self.subscriber) # basket contains 1 refill item worth 15€ self.client.cookies["basket_items"] = json.dumps( [{"id": 3, "name": "Rechargement 15 €", "quantity": 1, "unit_price": 15}] @@ -208,13 +200,13 @@ class EbouticTest(TestCase): url = self.generate_bank_valid_answer() response = self.client.get(url) - self.assertTrue(response.status_code == 200) - self.assertTrue(response.content.decode() == "Payment successful") + assert response.status_code == 200 + assert response.content.decode() == "Payment successful" new_balance = Customer.objects.get(user=self.subscriber).amount - self.assertEqual(new_balance, initial_balance + 15) + assert new_balance == initial_balance + 15 def test_alter_basket_after_submission(self): - self.client.login(username="subscriber", password="plop") + self.client.force_login(self.subscriber) self.client.cookies["basket_items"] = json.dumps( [{"id": 4, "name": "Barbar", "quantity": 1, "unit_price": 1.7}] ) @@ -227,30 +219,30 @@ class EbouticTest(TestCase): ) self.client.get(reverse("eboutic:command")) response = self.client.get(et_answer_url) - self.assertEqual(response.status_code, 500) - self.assertIn( - "Basket processing failed with error: SuspiciousOperation('Basket total and amount do not match'", - response.content.decode("utf-8"), + assert response.status_code == 500 + assert ( + "Basket processing failed with error: SuspiciousOperation('Basket total and amount do not match'" + in response.content.decode("utf-8"), ) def test_buy_simple_product_with_credit_card(self): - self.client.login(username="subscriber", password="plop") + self.client.force_login(self.subscriber) self.client.cookies["basket_items"] = json.dumps( [{"id": 4, "name": "Barbar", "quantity": 1, "unit_price": 1.7}] ) self.client.get(reverse("eboutic:command")) et_answer_url = self.generate_bank_valid_answer() response = self.client.get(et_answer_url) - self.assertTrue(response.status_code == 200) - self.assertTrue(response.content.decode("utf-8") == "Payment successful") + assert response.status_code == 200 + assert response.content.decode("utf-8") == "Payment successful" selling = ( Selling.objects.filter(customer=self.subscriber.customer) .order_by("-date") .first() ) - self.assertEqual(selling.payment_method, "CARD") - self.assertEqual(selling.quantity, 1) - self.assertEqual(selling.unit_price, self.barbar.selling_price) - self.assertEqual(selling.counter.type, "EBOUTIC") - self.assertEqual(selling.product, self.barbar) + assert selling.payment_method == "CARD" + assert selling.quantity == 1 + assert selling.unit_price == self.barbar.selling_price + assert selling.counter.type == "EBOUTIC" + assert selling.product == self.barbar diff --git a/election/tests.py b/election/tests.py index 3a3de97a..9ea534b8 100644 --- a/election/tests.py +++ b/election/tests.py @@ -6,56 +6,44 @@ from core.models import Group, User from election.models import Election -class MainElection(TestCase): - def setUp(self): - self.election = Election.objects.all().first() - self.public_group = Group.objects.get(id=settings.SITH_GROUP_PUBLIC_ID) - self.subscriber_group = Group.objects.get(name=settings.SITH_MAIN_MEMBERS_GROUP) - self.ae_board_group = Group.objects.get(name=settings.SITH_MAIN_BOARD_GROUP) - self.sli = User.objects.get(username="sli") - self.subscriber = User.objects.get(username="subscriber") - self.public = User.objects.get(username="public") +class ElectionTest(TestCase): + @classmethod + def setUpTestData(cls): + cls.election = Election.objects.first() + cls.public_group = Group.objects.get(id=settings.SITH_GROUP_PUBLIC_ID) + cls.subscriber_group = Group.objects.get(name=settings.SITH_MAIN_MEMBERS_GROUP) + cls.ae_board_group = Group.objects.get(name=settings.SITH_MAIN_BOARD_GROUP) + cls.sli = User.objects.get(username="sli") + cls.subscriber = User.objects.get(username="subscriber") + cls.public = User.objects.get(username="public") -class ElectionDetailTest(MainElection): +class ElectionDetailTest(ElectionTest): def test_permission_denied(self): self.election.view_groups.remove(self.public_group) - self.election.view_groups.add(self.subscriber_group) - self.election.save() - self.client.login(username=self.public.username, password="plop") - response_get = self.client.get( + self.client.force_login(self.public) + response = self.client.get( reverse("election:detail", args=str(self.election.id)) ) - response_post = self.client.get( - reverse("election:detail", args=str(self.election.id)) - ) - self.assertTrue(response_get.status_code == 403) - self.assertTrue(response_post.status_code == 403) - self.election.view_groups.remove(self.subscriber_group) - self.election.view_groups.add(self.public_group) - self.election.save() + assert response.status_code == 403 def test_permisson_granted(self): - self.client.login(username=self.public.username, password="plop") - response_get = self.client.get( + self.client.force_login(self.public) + response = self.client.get( reverse("election:detail", args=str(self.election.id)) ) - response_post = self.client.post( - reverse("election:detail", args=str(self.election.id)) - ) - self.assertFalse(response_get.status_code == 403) - self.assertFalse(response_post.status_code == 403) - self.assertTrue("La roue tourne" in str(response_get.content)) + assert response.status_code == 200 + assert "La roue tourne" in str(response.content) -class ElectionUpdateView(MainElection): +class ElectionUpdateView(ElectionTest): def test_permission_denied(self): - self.client.login(username=self.subscriber.username, password="plop") - response_get = self.client.get( + self.client.force_login(self.subscriber) + response = self.client.get( reverse("election:update", args=str(self.election.id)) ) - response_post = self.client.post( + assert response.status_code == 403 + response = self.client.post( reverse("election:update", args=str(self.election.id)) ) - self.assertTrue(response_get.status_code == 403) - self.assertTrue(response_post.status_code == 403) + assert response.status_code == 403 diff --git a/galaxy/tests.py b/galaxy/tests.py index 2a523af3..f1a3f092 100644 --- a/galaxy/tests.py +++ b/galaxy/tests.py @@ -34,29 +34,30 @@ from galaxy.models import Galaxy class GalaxyTestModel(TestCase): - def setUp(self): - self.root = User.objects.get(username="root") - self.skia = User.objects.get(username="skia") - self.sli = User.objects.get(username="sli") - self.krophil = User.objects.get(username="krophil") - self.richard = User.objects.get(username="rbatsbak") - self.subscriber = User.objects.get(username="subscriber") - self.public = User.objects.get(username="public") - self.com = User.objects.get(username="comunity") + @classmethod + def setUpTestData(cls): + cls.root = User.objects.get(username="root") + cls.skia = User.objects.get(username="skia") + cls.sli = User.objects.get(username="sli") + cls.krophil = User.objects.get(username="krophil") + cls.richard = User.objects.get(username="rbatsbak") + cls.subscriber = User.objects.get(username="subscriber") + cls.public = User.objects.get(username="public") + cls.com = User.objects.get(username="comunity") def test_user_self_score(self): """ Test that individual user scores are correct """ with self.assertNumQueries(8): - self.assertEqual(Galaxy.compute_user_score(self.root), 9) - self.assertEqual(Galaxy.compute_user_score(self.skia), 10) - self.assertEqual(Galaxy.compute_user_score(self.sli), 8) - self.assertEqual(Galaxy.compute_user_score(self.krophil), 2) - self.assertEqual(Galaxy.compute_user_score(self.richard), 10) - self.assertEqual(Galaxy.compute_user_score(self.subscriber), 8) - self.assertEqual(Galaxy.compute_user_score(self.public), 8) - self.assertEqual(Galaxy.compute_user_score(self.com), 1) + assert Galaxy.compute_user_score(self.root) == 9 + assert Galaxy.compute_user_score(self.skia) == 10 + assert Galaxy.compute_user_score(self.sli) == 8 + assert Galaxy.compute_user_score(self.krophil) == 2 + assert Galaxy.compute_user_score(self.richard) == 10 + assert Galaxy.compute_user_score(self.subscriber) == 8 + assert Galaxy.compute_user_score(self.public) == 8 + assert Galaxy.compute_user_score(self.com) == 1 def test_users_score(self): """ @@ -155,12 +156,13 @@ class GalaxyTestView(TestCase): call_command("generate_galaxy_test_data", "-v", "0") galaxy = Galaxy.objects.create() galaxy.rule(26) # We want a fast test + cls.root = User.objects.get(username="root") def test_page_is_citizen(self): """ Test that users can access the galaxy page of users who are citizens """ - self.client.login(username="root", password="plop") + self.client.force_login(self.root) user = User.objects.get(last_name="n°500") response = self.client.get(reverse("galaxy:user", args=[user.id])) self.assertContains( @@ -174,10 +176,10 @@ class GalaxyTestView(TestCase): Test that trying to access the galaxy page of a user who is not citizens return a 404 """ - self.client.login(username="root", password="plop") + self.client.force_login(self.root) user = User.objects.get(last_name="n°1") response = self.client.get(reverse("galaxy:user", args=[user.id])) - self.assertEquals(response.status_code, 404) + assert response.status_code == 404 def test_full_galaxy_state(self): """ @@ -185,7 +187,7 @@ class GalaxyTestView(TestCase): command that the relation scores are correct, and that the view exposes the right data. """ - self.client.login(username="root", password="plop") + self.client.force_login(self.root) response = self.client.get(reverse("galaxy:data")) state = response.json() @@ -194,7 +196,6 @@ class GalaxyTestView(TestCase): # Dump computed state, either for easier debugging, or to copy as new reference if changes are legit (galaxy_dir / "test_galaxy_state.json").write_text(json.dumps(state)) - self.assertEqual( - state, - json.loads((galaxy_dir / "ref_galaxy_state.json").read_text()), + assert ( + state == json.loads((galaxy_dir / "ref_galaxy_state.json").read_text()), ) diff --git a/pedagogy/tests.py b/pedagogy/tests.py index c52ee2ae..2c61facf 100644 --- a/pedagogy/tests.py +++ b/pedagogy/tests.py @@ -32,10 +32,12 @@ from core.models import Notification, User from pedagogy.models import UV, UVComment, UVCommentReport -def create_uv_template(user_id, code="IFC1", exclude_list=[]): +def create_uv_template(user_id, code="IFC1", exclude_list=None): """ Factory to help UV creation/update in post requests """ + if exclude_list is None: + exclude_list = [] uv = { "code": code, "author": user_id, @@ -83,235 +85,218 @@ class UVCreation(TestCase): """ @classmethod - def setUp(cls): + 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.create_uv_url = reverse("pedagogy:uv_create") + + def test_create_uv_admin_success(self): + self.client.force_login(self.bibou) + response = self.client.post( + self.create_uv_url, create_uv_template(self.bibou.id) + ) + assert response.status_code == 302 + assert UV.objects.filter(code="IFC1").exists() + + def test_create_uv_pedagogy_admin_success(self): + self.client.force_login(self.tutu) + response = self.client.post( + self.create_uv_url, create_uv_template(self.tutu.id) + ) + assert response.status_code == 302 + assert UV.objects.filter(code="IFC1").exists() + + def test_create_uv_unauthorized_fail(self): + # Test with anonymous user + response = self.client.post(self.create_uv_url, create_uv_template(0)) + assert response.status_code == 403 + + # Test with subscribed user + self.client.force_login(self.sli) + response = self.client.post(self.create_uv_url, create_uv_template(self.sli.id)) + assert response.status_code == 403 + + # Test with non subscribed user + self.client.force_login(self.guy) + response = self.client.post(self.create_uv_url, create_uv_template(self.guy.id)) + assert response.status_code == 403 + + # Check that the UV has never been created + assert not UV.objects.filter(code="IFC1").exists() + + def test_create_uv_bad_request_fail(self): + self.client.force_login(self.tutu) + + # Test with wrong user id (if someone cheats on the hidden input) + response = self.client.post( + self.create_uv_url, create_uv_template(self.bibou.id) + ) + assert response.status_code == 200 + + # Remove a required field + response = self.client.post( + self.create_uv_url, + create_uv_template(self.tutu.id, exclude_list=["title"]), + ) + assert response.status_code == 200 + + # Check that the UV hase never been created + assert not UV.objects.filter(code="IFC1").exists() + + +class UVListTest(TestCase): + """Test guide display rights.""" + + @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") - def test_create_uv_admin_success(self): - self.client.login(username="root", password="plop") - response = self.client.post( - reverse("pedagogy:uv_create"), create_uv_template(self.bibou.id) - ) - self.assertEqual(response.status_code, 302) - self.assertTrue(UV.objects.filter(code="IFC1").exists()) - - def test_create_uv_pedagogy_admin_success(self): - self.client.login(username="tutu", password="plop") - response = self.client.post( - reverse("pedagogy:uv_create"), create_uv_template(self.tutu.id) - ) - self.assertEqual(response.status_code, 302) - self.assertTrue(UV.objects.filter(code="IFC1").exists()) - - def test_create_uv_unauthorized_fail(self): - # Test with anonymous user - response = self.client.post( - reverse("pedagogy:uv_create"), create_uv_template(0) - ) - self.assertEqual(response.status_code, 403) - - # Test with subscribed user - self.client.login(username="sli", password="plop") - response = self.client.post( - reverse("pedagogy:uv_create"), create_uv_template(self.sli.id) - ) - self.assertEqual(response.status_code, 403) - - # Test with non subscribed user - self.client.login(username="guy", password="plop") - response = self.client.post( - reverse("pedagogy:uv_create"), create_uv_template(self.guy.id) - ) - self.assertEqual(response.status_code, 403) - - # Check that the UV has never been created - self.assertFalse(UV.objects.filter(code="IFC1").exists()) - - def test_create_uv_bad_request_fail(self): - self.client.login(username="tutu", password="plop") - - # Test with wrong user id (if someone cheats on the hidden input) - response = self.client.post( - reverse("pedagogy:uv_create"), create_uv_template(self.bibou.id) - ) - self.assertNotEqual(response.status_code, 302) - self.assertEqual(response.status_code, 200) - - # Remove a required field - response = self.client.post( - reverse("pedagogy:uv_create"), - create_uv_template(self.tutu.id, exclude_list=["title"]), - ) - self.assertNotEqual(response.status_code, 302) - self.assertEqual(response.status_code, 200) - - # Check that the UV hase never been created - self.assertFalse(UV.objects.filter(code="IFC1").exists()) - - -class UVListTest(TestCase): - """ - Test guide display rights - """ - def test_uv_list_display_success(self): # Display for root - self.client.login(username="root", password="plop") + self.client.force_login(self.bibou) response = self.client.get(reverse("pedagogy:guide")) self.assertContains(response, text="PA00") # Display for pedagogy admin - self.client.login(username="tutu", password="plop") + self.client.force_login(self.tutu) response = self.client.get(reverse("pedagogy:guide")) self.assertContains(response, text="PA00") # Display for simple subscriber - self.client.login(username="sli", password="plop") + self.client.force_login(self.sli) response = self.client.get(reverse("pedagogy:guide")) self.assertContains(response, text="PA00") def test_uv_list_display_fail(self): # Don't display for anonymous user response = self.client.get(reverse("pedagogy:guide")) - self.assertEqual(response.status_code, 403) + assert response.status_code == 403 # Don't display for none subscribed users - self.client.login(username="guy", password="plop") + self.client.force_login(self.guy) response = self.client.get(reverse("pedagogy:guide")) - self.assertEqual(response.status_code, 403) + assert response.status_code == 403 class UVDeleteTest(TestCase): - """ - Test UV deletion rights - """ + """Test UV deletion rights.""" + + @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.uv = UV.objects.get(code="PA00") + cls.delete_uv_url = reverse("pedagogy:uv_delete", kwargs={"uv_id": cls.uv.id}) def test_uv_delete_root_success(self): - self.client.login(username="root", password="plop") - self.client.post( - reverse( - "pedagogy:uv_delete", kwargs={"uv_id": UV.objects.get(code="PA00").id} - ) - ) - self.assertFalse(UV.objects.filter(code="PA00").exists()) + self.client.force_login(self.bibou) + self.client.post(self.delete_uv_url) + assert not UV.objects.filter(pk=self.uv.pk).exists() def test_uv_delete_pedagogy_admin_success(self): - self.client.login(username="tutu", password="plop") - self.client.post( - reverse( - "pedagogy:uv_delete", kwargs={"uv_id": UV.objects.get(code="PA00").id} - ) - ) - self.assertFalse(UV.objects.filter(code="PA00").exists()) + self.client.force_login(self.tutu) + self.client.post(self.delete_uv_url) + assert not UV.objects.filter(pk=self.uv.pk).exists() def test_uv_delete_pedagogy_unauthorized_fail(self): # Anonymous user - response = self.client.post( - reverse( - "pedagogy:uv_delete", kwargs={"uv_id": UV.objects.get(code="PA00").id} - ) - ) - self.assertEqual(response.status_code, 403) + response = self.client.post(self.delete_uv_url) + assert response.status_code == 403 + assert UV.objects.filter(pk=self.uv.pk).exists() # Not subscribed user - self.client.login(username="guy", password="plop") - response = self.client.post( - reverse( - "pedagogy:uv_delete", kwargs={"uv_id": UV.objects.get(code="PA00").id} - ) - ) - self.assertEqual(response.status_code, 403) + self.client.force_login(self.guy) + response = self.client.post(self.delete_uv_url) + assert response.status_code == 403 + assert UV.objects.filter(pk=self.uv.pk).exists() # Simply subscribed user - self.client.login(username="sli", password="plop") - response = self.client.post( - reverse( - "pedagogy:uv_delete", kwargs={"uv_id": UV.objects.get(code="PA00").id} - ) - ) - self.assertEqual(response.status_code, 403) - - # Check that the UV still exists - self.assertTrue(UV.objects.filter(code="PA00").exists()) + self.client.force_login(self.sli) + response = self.client.post(self.delete_uv_url) + assert response.status_code == 403 + assert UV.objects.filter(pk=self.uv.pk).exists() class UVUpdateTest(TestCase): - """ - Test UV update rights - """ + """Test UV update rights.""" - def setUp(self): - self.bibou = User.objects.filter(username="root").first() - self.tutu = User.objects.filter(username="tutu").first() - self.uv = UV.objects.get(code="PA00") + @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.uv = UV.objects.get(code="PA00") + cls.update_uv_url = reverse("pedagogy:uv_update", kwargs={"uv_id": cls.uv.id}) def test_uv_update_root_success(self): - self.client.login(username="root", password="plop") + self.client.force_login(self.bibou) self.client.post( - reverse("pedagogy:uv_update", kwargs={"uv_id": self.uv.id}), - create_uv_template(self.bibou.id, code="PA00"), + self.update_uv_url, create_uv_template(self.bibou.id, code="PA00") ) self.uv.refresh_from_db() - self.assertEqual(self.uv.credit_type, "TM") + assert self.uv.credit_type == "TM" def test_uv_update_pedagogy_admin_success(self): - self.client.login(username="tutu", password="plop") + self.client.force_login(self.tutu) self.client.post( - reverse("pedagogy:uv_update", kwargs={"uv_id": self.uv.id}), - create_uv_template(self.bibou.id, code="PA00"), + self.update_uv_url, create_uv_template(self.bibou.id, code="PA00") ) self.uv.refresh_from_db() - self.assertEqual(self.uv.credit_type, "TM") + assert self.uv.credit_type == "TM" def test_uv_update_original_author_does_not_change(self): - self.client.login(username="tutu", password="plop") + self.client.force_login(self.tutu) response = self.client.post( - reverse("pedagogy:uv_update", kwargs={"uv_id": self.uv.id}), + self.update_uv_url, create_uv_template(self.tutu.id, code="PA00"), ) - + assert response.status_code == 200 self.uv.refresh_from_db() - self.assertEqual(response.status_code, 200) - self.assertEqual(self.uv.author, self.bibou) + assert self.uv.author == self.bibou def test_uv_update_pedagogy_unauthorized_fail(self): # Anonymous user response = self.client.post( - reverse("pedagogy:uv_update", kwargs={"uv_id": self.uv.id}), - create_uv_template(self.bibou.id, code="PA00"), + self.update_uv_url, create_uv_template(self.bibou.id, code="PA00") ) - self.assertEqual(response.status_code, 403) + assert response.status_code == 403 # Not subscribed user - self.client.login(username="guy", password="plop") + self.client.force_login(self.guy) response = self.client.post( - reverse("pedagogy:uv_update", kwargs={"uv_id": self.uv.id}), - create_uv_template(self.bibou.id, code="PA00"), + self.update_uv_url, create_uv_template(self.bibou.id, code="PA00") ) - self.assertEqual(response.status_code, 403) + assert response.status_code == 403 # Simply subscribed user - self.client.login(username="sli", password="plop") + self.client.force_login(self.sli) response = self.client.post( - reverse("pedagogy:uv_update", kwargs={"uv_id": self.uv.id}), - create_uv_template(self.bibou.id, code="PA00"), + self.update_uv_url, create_uv_template(self.bibou.id, code="PA00") ) - self.assertEqual(response.status_code, 403) + assert response.status_code == 403 # Check that the UV has not changed self.uv.refresh_from_db() - self.assertEqual(self.uv.credit_type, "OM") + assert self.uv.credit_type == "OM" # UVComment class tests -def create_uv_comment_template(user_id, uv_code="PA00", exclude_list=[]): +def create_uv_comment_template(user_id, uv_code="PA00", exclude_list=None): """ Factory to help UVComment creation/update in post requests """ + if exclude_list is None: + exclude_list = [] comment = { "author": user_id, "uv": UV.objects.get(code=uv_code).id, @@ -340,105 +325,80 @@ class UVCommentCreationAndDisplay(TestCase): cls.sli = User.objects.get(username="sli") cls.guy = User.objects.get(username="guy") cls.uv = UV.objects.get(code="PA00") + cls.uv_url = reverse("pedagogy:uv_detail", kwargs={"uv_id": cls.uv.id}) def test_create_uv_comment_admin_success(self): - self.client.login(username="root", password="plop") + self.client.force_login(self.bibou) response = self.client.post( - reverse("pedagogy:uv_detail", kwargs={"uv_id": self.uv.id}), - create_uv_comment_template(self.bibou.id), - ) - self.assertEqual(response.status_code, 302) - response = self.client.get( - reverse("pedagogy:uv_detail", kwargs={"uv_id": self.uv.id}) + self.uv_url, create_uv_comment_template(self.bibou.id) ) + self.assertRedirects(response, self.uv_url) + response = self.client.get(self.uv_url) self.assertContains(response, text="Superbe UV") def test_create_uv_comment_pedagogy_admin_success(self): - self.client.login(username="tutu", password="plop") + self.client.force_login(self.tutu) response = self.client.post( - reverse("pedagogy:uv_detail", kwargs={"uv_id": self.uv.id}), - create_uv_comment_template(self.tutu.id), - ) - self.assertEqual(response.status_code, 302) - response = self.client.get( - reverse("pedagogy:uv_detail", kwargs={"uv_id": self.uv.id}) + self.uv_url, create_uv_comment_template(self.tutu.id) ) + self.assertRedirects(response, self.uv_url) + response = self.client.get(self.uv_url) self.assertContains(response, text="Superbe UV") def test_create_uv_comment_subscriber_success(self): - self.client.login(username="sli", password="plop") + self.client.force_login(self.sli) response = self.client.post( - reverse("pedagogy:uv_detail", kwargs={"uv_id": self.uv.id}), - create_uv_comment_template(self.sli.id), - ) - self.assertEqual(response.status_code, 302) - response = self.client.get( - reverse("pedagogy:uv_detail", kwargs={"uv_id": self.uv.id}) + self.uv_url, create_uv_comment_template(self.sli.id) ) + self.assertRedirects(response, self.uv_url) + response = self.client.get(self.uv_url) self.assertContains(response, text="Superbe UV") def test_create_uv_comment_unauthorized_fail(self): + nb_comments = self.uv.comments.count() # Test with anonymous user - response = self.client.post( - reverse("pedagogy:uv_detail", kwargs={"uv_id": self.uv.id}), - create_uv_comment_template(0), - ) - self.assertEqual(response.status_code, 403) + response = self.client.post(self.uv_url, create_uv_comment_template(0)) + assert response.status_code == 403 # Test with non subscribed user - self.client.login(username="guy", password="plop") + self.client.force_login(self.guy) response = self.client.post( - reverse("pedagogy:uv_detail", kwargs={"uv_id": self.uv.id}), - create_uv_comment_template(self.guy.id), + self.uv_url, create_uv_comment_template(self.guy.id) ) - self.assertEqual(response.status_code, 403) + assert response.status_code == 403 - # Check that the comment has never been created - self.client.login(username="root", password="plop") - response = self.client.get( - reverse("pedagogy:uv_detail", kwargs={"uv_id": self.uv.id}) - ) - self.assertNotContains(response, text="Superbe UV") + # Check that no comment has been created + assert self.uv.comments.count() == nb_comments def test_create_uv_comment_bad_form_fail(self): - self.client.login(username="root", password="plop") + nb_comments = self.uv.comments.count() + self.client.force_login(self.bibou) response = self.client.post( - reverse("pedagogy:uv_detail", kwargs={"uv_id": self.uv.id}), + self.uv_url, create_uv_comment_template(self.bibou.id, exclude_list=["grade_global"]), ) - self.assertEqual(response.status_code, 200) - - response = self.client.get( - reverse("pedagogy:uv_detail", kwargs={"uv_id": self.uv.id}) - ) - self.assertNotContains(response, text="Superbe UV") + assert response.status_code == 200 + assert self.uv.comments.count() == nb_comments def test_create_uv_comment_twice_fail(self): # Checks that the has_user_already_commented method works proprely - self.assertFalse(self.uv.has_user_already_commented(self.bibou)) + assert not self.uv.has_user_already_commented(self.bibou) # Create a first comment - self.client.login(username="root", password="plop") - self.client.post( - reverse("pedagogy:uv_detail", kwargs={"uv_id": self.uv.id}), - create_uv_comment_template(self.bibou.id), - ) + self.client.force_login(self.bibou) + self.client.post(self.uv_url, create_uv_comment_template(self.bibou.id)) # Checks that the has_user_already_commented method works proprely - self.assertTrue(self.uv.has_user_already_commented(self.bibou)) + assert self.uv.has_user_already_commented(self.bibou) # Create the second comment comment = create_uv_comment_template(self.bibou.id) comment["comment"] = "Twice" - response = self.client.post( - reverse("pedagogy:uv_detail", kwargs={"uv_id": self.uv.id}), comment - ) - self.assertEqual(response.status_code, 200) - self.assertTrue( - UVComment.objects.filter(comment__contains="Superbe UV").exists() - ) - self.assertFalse(UVComment.objects.filter(comment__contains="Twice").exists()) + response = self.client.post(self.uv_url, comment) + assert response.status_code == 200 + assert UVComment.objects.filter(comment__contains="Superbe UV").exists() + assert not UVComment.objects.filter(comment__contains="Twice").exists() self.assertContains( response, _( @@ -448,21 +408,26 @@ class UVCommentCreationAndDisplay(TestCase): # Ensure that there is no crash when no uv or no author is given self.client.post( - reverse("pedagogy:uv_detail", kwargs={"uv_id": self.uv.id}), - create_uv_comment_template(self.bibou.id, exclude_list=["uv"]), + self.uv_url, create_uv_comment_template(self.bibou.id, exclude_list=["uv"]) ) - self.assertEqual(response.status_code, 200) + assert response.status_code == 200 self.client.post( - reverse("pedagogy:uv_detail", kwargs={"uv_id": self.uv.id}), + self.uv_url, create_uv_comment_template(self.bibou.id, exclude_list=["author"]), ) - self.assertEqual(response.status_code, 200) + assert response.status_code == 200 class UVCommentDeleteTest(TestCase): - """ - Test UVComment deletion rights - """ + """Test UVComment deletion rights.""" + + @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.krophil = User.objects.get(username="krophil") def setUp(self): comment_kwargs = create_uv_comment_template( @@ -474,58 +439,60 @@ class UVCommentDeleteTest(TestCase): self.comment.save() def test_uv_comment_delete_root_success(self): - self.client.login(username="root", password="plop") + self.client.force_login(self.bibou) self.client.post( reverse("pedagogy:comment_delete", kwargs={"comment_id": self.comment.id}) ) - self.assertFalse(UVComment.objects.filter(id=self.comment.id).exists()) + assert not UVComment.objects.filter(id=self.comment.id).exists() def test_uv_comment_delete_pedagogy_admin_success(self): - self.client.login(username="tutu", password="plop") + self.client.force_login(self.tutu) self.client.post( reverse("pedagogy:comment_delete", kwargs={"comment_id": self.comment.id}) ) - self.assertFalse(UVComment.objects.filter(id=self.comment.id).exists()) + assert not UVComment.objects.filter(id=self.comment.id).exists() def test_uv_comment_delete_author_success(self): - self.client.login(username="krophil", password="plop") + self.client.force_login(self.krophil) self.client.post( reverse("pedagogy:comment_delete", kwargs={"comment_id": self.comment.id}) ) - self.assertFalse(UVComment.objects.filter(id=self.comment.id).exists()) + assert not UVComment.objects.filter(id=self.comment.id).exists() def test_uv_comment_delete_unauthorized_fail(self): # Anonymous user response = self.client.post( reverse("pedagogy:comment_delete", kwargs={"comment_id": self.comment.id}) ) - self.assertEqual(response.status_code, 403) + assert response.status_code == 403 # Unsbscribed user - self.client.login(username="guy", password="plop") + self.client.force_login(self.guy) response = self.client.post( reverse("pedagogy:comment_delete", kwargs={"comment_id": self.comment.id}) ) - self.assertEqual(response.status_code, 403) + assert response.status_code == 403 # Subscribed user (not author of the comment) - self.client.login(username="sli", password="plop") + self.client.force_login(self.sli) response = self.client.post( reverse("pedagogy:comment_delete", kwargs={"comment_id": self.comment.id}) ) - self.assertEqual(response.status_code, 403) + assert response.status_code == 403 # Check that the comment still exists - self.assertTrue(UVComment.objects.filter(id=self.comment.id).exists()) + assert UVComment.objects.filter(id=self.comment.id).exists() class UVCommentUpdateTest(TestCase): - """ - Test UVComment update rights - """ + """Test UVComment update rights.""" @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.krophil = User.objects.get(username="krophil") def setUp(self): @@ -541,32 +508,32 @@ class UVCommentUpdateTest(TestCase): self.comment_edit["comment"] = "Edited" def test_uv_comment_update_root_success(self): - self.client.login(username="root", password="plop") + self.client.force_login(self.bibou) response = self.client.post( reverse("pedagogy:comment_update", kwargs={"comment_id": self.comment.id}), self.comment_edit, ) - self.assertEqual(response.status_code, 302) + assert response.status_code == 302 self.comment.refresh_from_db() self.assertEqual(self.comment.comment, self.comment_edit["comment"]) def test_uv_comment_update_pedagogy_admin_success(self): - self.client.login(username="tutu", password="plop") + self.client.force_login(self.tutu) response = self.client.post( reverse("pedagogy:comment_update", kwargs={"comment_id": self.comment.id}), self.comment_edit, ) - self.assertEqual(response.status_code, 302) + assert response.status_code == 302 self.comment.refresh_from_db() self.assertEqual(self.comment.comment, self.comment_edit["comment"]) def test_uv_comment_update_author_success(self): - self.client.login(username="krophil", password="plop") + self.client.force_login(self.krophil) response = self.client.post( reverse("pedagogy:comment_update", kwargs={"comment_id": self.comment.id}), self.comment_edit, ) - self.assertEqual(response.status_code, 302) + assert response.status_code == 302 self.comment.refresh_from_db() self.assertEqual(self.comment.comment, self.comment_edit["comment"]) @@ -576,35 +543,35 @@ class UVCommentUpdateTest(TestCase): reverse("pedagogy:comment_update", kwargs={"comment_id": self.comment.id}), self.comment_edit, ) - self.assertEqual(response.status_code, 403) + assert response.status_code == 403 # Unsbscribed user response = self.client.post( reverse("pedagogy:comment_update", kwargs={"comment_id": self.comment.id}), self.comment_edit, ) - self.assertEqual(response.status_code, 403) + assert response.status_code == 403 # Subscribed user (not author of the comment) response = self.client.post( reverse("pedagogy:comment_update", kwargs={"comment_id": self.comment.id}), self.comment_edit, ) - self.assertEqual(response.status_code, 403) + assert response.status_code == 403 # Check that the comment hasn't change self.comment.refresh_from_db() self.assertNotEqual(self.comment.comment, self.comment_edit["comment"]) def test_uv_comment_update_original_author_does_not_change(self): - self.client.login(username="root", password="plop") + self.client.force_login(self.bibou) self.comment_edit["author"] = User.objects.get(username="root").id response = self.client.post( reverse("pedagogy:comment_update", kwargs={"comment_id": self.comment.id}), self.comment_edit, ) - self.assertEqual(response.status_code, 200) + assert response.status_code == 200 self.assertEqual(self.comment.author, self.krophil) @@ -614,37 +581,44 @@ class UVSearchTest(TestCase): Test that the API is working well """ + @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") + def setUp(self): call_command("update_index", "pedagogy") def test_get_page_authorized_success(self): # Test with root user - self.client.login(username="root", password="plop") + self.client.force_login(self.bibou) response = self.client.get(reverse("pedagogy:guide")) - self.assertEqual(response.status_code, 200) + assert response.status_code == 200 # Test with pedagogy admin - self.client.login(username="tutu", password="plop") + self.client.force_login(self.tutu) response = self.client.get(reverse("pedagogy:guide")) - self.assertEqual(response.status_code, 200) + assert response.status_code == 200 # Test with subscribed user - self.client.login(username="sli", password="plop") + self.client.force_login(self.sli) response = self.client.get(reverse("pedagogy:guide")) - self.assertEqual(response.status_code, 200) + assert response.status_code == 200 def test_get_page_unauthorized_fail(self): # Test with anonymous user response = self.client.get(reverse("pedagogy:guide")) - self.assertEqual(response.status_code, 403) + assert response.status_code == 403 # Test with not subscribed user - self.client.login(username="guy", password="plop") + self.client.force_login(self.guy) response = self.client.get(reverse("pedagogy:guide")) - self.assertEqual(response.status_code, 403) + assert response.status_code == 403 def test_search_pa00_success(self): - self.client.login(username="sli", password="plop") + self.client.force_login(self.sli) # Search with UV code response = self.client.get(reverse("pedagogy:guide"), {"search": "PA00"}) @@ -783,9 +757,15 @@ class UVModerationFormTest(TestCase): Assert access rights and if the form works well """ - def setUp(self): - self.krophil = User.objects.get(username="krophil") + @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.krophil = User.objects.get(username="krophil") + def setUp(self): # Prepare a comment comment_kwargs = create_uv_comment_template(self.krophil.id) comment_kwargs["author"] = self.krophil @@ -818,119 +798,109 @@ class UVModerationFormTest(TestCase): def test_access_authorized_success(self): # Test with root - self.client.login(username="root", password="plop") + self.client.force_login(self.bibou) response = self.client.get(reverse("pedagogy:moderation")) - self.assertEqual(response.status_code, 200) + assert response.status_code == 200 # Test with pedagogy admin - self.client.login(username="tutu", password="plop") + self.client.force_login(self.tutu) response = self.client.get(reverse("pedagogy:moderation")) - self.assertEqual(response.status_code, 200) + assert response.status_code == 200 def test_access_unauthorized_fail(self): # Test with anonymous user response = self.client.get(reverse("pedagogy:moderation")) - self.assertEqual(response.status_code, 403) + assert response.status_code == 403 # Test with unsubscribed user - self.client.login(username="guy", password="plop") + self.client.force_login(self.guy) response = self.client.get(reverse("pedagogy:moderation")) - self.assertEqual(response.status_code, 403) + assert response.status_code == 403 # Test with subscribed user - self.client.login(username="sli", password="plop") + self.client.force_login(self.sli) response = self.client.get(reverse("pedagogy:moderation")) - self.assertEqual(response.status_code, 403) + assert response.status_code == 403 def test_do_nothing(self): - self.client.login(username="root", password="plop") + self.client.force_login(self.bibou) response = self.client.post(reverse("pedagogy:moderation")) - self.assertEqual(response.status_code, 302) + assert response.status_code == 302 # Test that nothing has changed - self.assertTrue(UVCommentReport.objects.filter(id=self.report_1.id).exists()) - self.assertTrue(UVComment.objects.filter(id=self.comment_1.id).exists()) - self.assertTrue( - UVCommentReport.objects.filter(id=self.report_1_bis.id).exists() - ) - self.assertTrue(UVCommentReport.objects.filter(id=self.report_2.id).exists()) - self.assertTrue(UVComment.objects.filter(id=self.comment_2.id).exists()) + assert UVCommentReport.objects.filter(id=self.report_1.id).exists() + assert UVComment.objects.filter(id=self.comment_1.id).exists() + assert UVCommentReport.objects.filter(id=self.report_1_bis.id).exists() + assert UVCommentReport.objects.filter(id=self.report_2.id).exists() + assert UVComment.objects.filter(id=self.comment_2.id).exists() def test_delete_comment(self): - self.client.login(username="root", password="plop") + self.client.force_login(self.bibou) response = self.client.post( reverse("pedagogy:moderation"), {"accepted_reports": [self.report_1.id]} ) - self.assertEqual(response.status_code, 302) + assert response.status_code == 302 # Test that the comment and it's associated report has been deleted - self.assertFalse(UVCommentReport.objects.filter(id=self.report_1.id).exists()) - self.assertFalse(UVComment.objects.filter(id=self.comment_1.id).exists()) + assert not UVCommentReport.objects.filter(id=self.report_1.id).exists() + assert not UVComment.objects.filter(id=self.comment_1.id).exists() # Test that the bis report has been deleted - self.assertFalse( - UVCommentReport.objects.filter(id=self.report_1_bis.id).exists() - ) + assert not UVCommentReport.objects.filter(id=self.report_1_bis.id).exists() # Test that the other comment and report still exists - self.assertTrue(UVCommentReport.objects.filter(id=self.report_2.id).exists()) - self.assertTrue(UVComment.objects.filter(id=self.comment_2.id).exists()) + assert UVCommentReport.objects.filter(id=self.report_2.id).exists() + assert UVComment.objects.filter(id=self.comment_2.id).exists() def test_delete_comment_bulk(self): - self.client.login(username="root", password="plop") + self.client.force_login(self.bibou) response = self.client.post( reverse("pedagogy:moderation"), {"accepted_reports": [self.report_1.id, self.report_2.id]}, ) - self.assertEqual(response.status_code, 302) + assert response.status_code == 302 # Test that comments and their associated reports has been deleted - self.assertFalse(UVCommentReport.objects.filter(id=self.report_1.id).exists()) - self.assertFalse(UVComment.objects.filter(id=self.comment_1.id).exists()) - self.assertFalse(UVCommentReport.objects.filter(id=self.report_2.id).exists()) - self.assertFalse(UVComment.objects.filter(id=self.comment_2.id).exists()) + assert not UVCommentReport.objects.filter(id=self.report_1.id).exists() + assert not UVComment.objects.filter(id=self.comment_1.id).exists() + assert not UVCommentReport.objects.filter(id=self.report_2.id).exists() + assert not UVComment.objects.filter(id=self.comment_2.id).exists() # Test that the bis report has been deleted - self.assertFalse( - UVCommentReport.objects.filter(id=self.report_1_bis.id).exists() - ) + assert not UVCommentReport.objects.filter(id=self.report_1_bis.id).exists() def test_delete_comment_with_bis(self): # Test case if two reports targets the same comment and are both deleted - self.client.login(username="root", password="plop") + self.client.force_login(self.bibou) response = self.client.post( reverse("pedagogy:moderation"), {"accepted_reports": [self.report_1.id, self.report_1_bis.id]}, ) - self.assertEqual(response.status_code, 302) + assert response.status_code == 302 # Test that the comment and it's associated report has been deleted - self.assertFalse(UVCommentReport.objects.filter(id=self.report_1.id).exists()) - self.assertFalse(UVComment.objects.filter(id=self.comment_1.id).exists()) + assert not UVCommentReport.objects.filter(id=self.report_1.id).exists() + assert not UVComment.objects.filter(id=self.comment_1.id).exists() # Test that the bis report has been deleted - self.assertFalse( - UVCommentReport.objects.filter(id=self.report_1_bis.id).exists() - ) + assert not UVCommentReport.objects.filter(id=self.report_1_bis.id).exists() def test_delete_report(self): - self.client.login(username="root", password="plop") + self.client.force_login(self.bibou) response = self.client.post( reverse("pedagogy:moderation"), {"denied_reports": [self.report_1.id]} ) - self.assertEqual(response.status_code, 302) + assert response.status_code == 302 # Test that the report has been deleted and that the comment still exists - self.assertFalse(UVCommentReport.objects.filter(id=self.report_1.id).exists()) - self.assertTrue(UVComment.objects.filter(id=self.comment_1.id).exists()) + assert not UVCommentReport.objects.filter(id=self.report_1.id).exists() + assert UVComment.objects.filter(id=self.comment_1.id).exists() # Test that the bis report is still there - self.assertTrue( - UVCommentReport.objects.filter(id=self.report_1_bis.id).exists() - ) + assert UVCommentReport.objects.filter(id=self.report_1_bis.id).exists() # Test that the other comment and report still exists - self.assertTrue(UVCommentReport.objects.filter(id=self.report_2.id).exists()) - self.assertTrue(UVComment.objects.filter(id=self.comment_2.id).exists()) + assert UVCommentReport.objects.filter(id=self.report_2.id).exists() + assert UVComment.objects.filter(id=self.comment_2.id).exists() def test_delete_report_bulk(self): - self.client.login(username="root", password="plop") + self.client.force_login(self.bibou) response = self.client.post( reverse("pedagogy:moderation"), { @@ -941,21 +911,18 @@ class UVModerationFormTest(TestCase): ] }, ) - self.assertEqual(response.status_code, 302) + assert response.status_code == 302 # Test that every reports has been deleted - self.assertFalse(UVCommentReport.objects.filter(id=self.report_1.id).exists()) - self.assertFalse( - UVCommentReport.objects.filter(id=self.report_1_bis.id).exists() - ) - self.assertFalse(UVCommentReport.objects.filter(id=self.report_2.id).exists()) - + assert not UVCommentReport.objects.filter(id=self.report_1.id).exists() + assert not UVCommentReport.objects.filter(id=self.report_1_bis.id).exists() + assert not UVCommentReport.objects.filter(id=self.report_2.id).exists() # Test that comments still exists - self.assertTrue(UVComment.objects.filter(id=self.comment_1.id).exists()) - self.assertTrue(UVComment.objects.filter(id=self.comment_2.id).exists()) + assert UVComment.objects.filter(id=self.comment_1.id).exists() + assert UVComment.objects.filter(id=self.comment_2.id).exists() def test_delete_mixed(self): - self.client.login(username="root", password="plop") + self.client.force_login(self.bibou) response = self.client.post( reverse("pedagogy:moderation"), { @@ -963,23 +930,21 @@ class UVModerationFormTest(TestCase): "denied_reports": [self.report_1.id], }, ) - self.assertEqual(response.status_code, 302) + assert response.status_code == 302 # Test that report 2 and his comment has been deleted - self.assertFalse(UVCommentReport.objects.filter(id=self.report_2.id).exists()) - self.assertFalse(UVComment.objects.filter(id=self.comment_2.id).exists()) + assert not UVCommentReport.objects.filter(id=self.report_2.id).exists() + assert not UVComment.objects.filter(id=self.comment_2.id).exists() # Test that report 1 has been deleted and it's comment still exists - self.assertFalse(UVCommentReport.objects.filter(id=self.report_1.id).exists()) - self.assertTrue(UVComment.objects.filter(id=self.comment_1.id).exists()) + assert not UVCommentReport.objects.filter(id=self.report_1.id).exists() + assert UVComment.objects.filter(id=self.comment_1.id).exists() # Test that report 1 bis is still there - self.assertTrue( - UVCommentReport.objects.filter(id=self.report_1_bis.id).exists() - ) + assert UVCommentReport.objects.filter(id=self.report_1_bis.id).exists() def test_delete_mixed_with_bis(self): - self.client.login(username="root", password="plop") + self.client.force_login(self.bibou) response = self.client.post( reverse("pedagogy:moderation"), { @@ -987,21 +952,19 @@ class UVModerationFormTest(TestCase): "denied_reports": [self.report_1_bis.id], }, ) - self.assertEqual(response.status_code, 302) + assert response.status_code == 302 # Test that report 1 and 1 bis has been deleted - self.assertFalse( - UVCommentReport.objects.filter( - id__in=[self.report_1.id, self.report_1_bis.id] - ).exists() - ) + assert not UVCommentReport.objects.filter( + id__in=[self.report_1.id, self.report_1_bis.id] + ).exists() # Test that comment 1 has been deleted - self.assertFalse(UVComment.objects.filter(id=self.comment_1.id).exists()) + assert not UVComment.objects.filter(id=self.comment_1.id).exists() # Test that report and comment 2 still exists - self.assertTrue(UVCommentReport.objects.filter(id=self.report_2.id).exists()) - self.assertTrue(UVComment.objects.filter(id=self.comment_2.id).exists()) + assert UVCommentReport.objects.filter(id=self.report_2.id).exists() + assert UVComment.objects.filter(id=self.comment_2.id).exists() class UVCommentReportCreateTest(TestCase): @@ -1032,9 +995,9 @@ class UVCommentReportCreateTest(TestCase): }, ) if success: - self.assertEqual(response.status_code, 302) + assert response.status_code == 302 else: - self.assertEqual(response.status_code, 403) + assert response.status_code == 403 self.assertEqual(UVCommentReport.objects.all().exists(), success) def test_create_report_root_success(self): @@ -1054,32 +1017,24 @@ class UVCommentReportCreateTest(TestCase): reverse("pedagogy:comment_report", kwargs={"comment_id": self.comment.id}), {"comment": self.comment.id, "reporter": 0, "reason": "C'est moche"}, ) - self.assertEqual(response.status_code, 403) - self.assertFalse(UVCommentReport.objects.all().exists()) + assert response.status_code == 403 + assert not UVCommentReport.objects.all().exists() def test_notifications(self): - self.assertFalse( - self.tutu.notifications.filter(type="PEDAGOGY_MODERATION").exists() - ) + assert not self.tutu.notifications.filter(type="PEDAGOGY_MODERATION").exists() # Create a comment report self.create_report_test("tutu", True) # Check that a notification has been created for pedagogy admins - self.assertTrue( - self.tutu.notifications.filter(type="PEDAGOGY_MODERATION").exists() - ) + assert self.tutu.notifications.filter(type="PEDAGOGY_MODERATION").exists() # Check that only pedagogy admins recieves this notification for notif in Notification.objects.filter(type="PEDAGOGY_MODERATION").all(): - self.assertTrue( - notif.user.is_in_group(pk=settings.SITH_GROUP_PEDAGOGY_ADMIN_ID) - ) + assert notif.user.is_in_group(pk=settings.SITH_GROUP_PEDAGOGY_ADMIN_ID) # Check that notifications are not duplicated if not viewed self.create_report_test("tutu", True) - self.assertEqual( - self.tutu.notifications.filter(type="PEDAGOGY_MODERATION").count(), 1 - ) + assert self.tutu.notifications.filter(type="PEDAGOGY_MODERATION").count() == 1 # Check that a new notification is created when the old one has been viewed notif = self.tutu.notifications.filter(type="PEDAGOGY_MODERATION").first() @@ -1088,6 +1043,4 @@ class UVCommentReportCreateTest(TestCase): self.create_report_test("tutu", True) - self.assertEqual( - self.tutu.notifications.filter(type="PEDAGOGY_MODERATION").count(), 2 - ) + assert self.tutu.notifications.filter(type="PEDAGOGY_MODERATION").count() == 2 diff --git a/poetry.lock b/poetry.lock index f43c9663..937b4ad7 100644 --- a/poetry.lock +++ b/poetry.lock @@ -321,6 +321,9 @@ files = [ {file = "coverage-7.5.4.tar.gz", hash = "sha256:a44963520b069e12789d0faea4e9fdb1e410cdc4aab89d94f7f55cbb7fef0353"}, ] +[package.dependencies] +tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} + [package.extras] toml = ["tomli"] @@ -575,6 +578,20 @@ files = [ {file = "docutils-0.18.1.tar.gz", hash = "sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06"}, ] +[[package]] +name = "exceptiongroup" +version = "1.2.1" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.2.1-py3-none-any.whl", hash = "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad"}, + {file = "exceptiongroup-1.2.1.tar.gz", hash = "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16"}, +] + +[package.extras] +test = ["pytest (>=6)"] + [[package]] name = "filelock" version = "3.15.4" @@ -627,6 +644,17 @@ files = [ {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, ] +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + [[package]] name = "ipython" version = "7.34.0" @@ -949,6 +977,21 @@ files = [ docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] +[[package]] +name = "pluggy" +version = "1.5.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + [[package]] name = "prompt-toolkit" version = "3.0.47" @@ -1108,6 +1151,64 @@ cryptography = ">=38.0.0,<40.0.0 || >40.0.0,<40.0.1 || >40.0.1,<42" docs = ["sphinx (!=5.2.0,!=5.2.0.post0)", "sphinx-rtd-theme"] test = ["flaky", "pretend", "pytest (>=3.0.1)"] +[[package]] +name = "pytest" +version = "8.2.2" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest-8.2.2-py3-none-any.whl", hash = "sha256:c434598117762e2bd304e526244f67bf66bbd7b5d6cf22138be51ff661980343"}, + {file = "pytest-8.2.2.tar.gz", hash = "sha256:de4bb8104e201939ccdc688b27a89a7be2079b22e2bd2b07f806b6ba71117977"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=1.5,<2.0" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} + +[package.extras] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "pytest-cov" +version = "5.0.0" +description = "Pytest plugin for measuring coverage." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857"}, + {file = "pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652"}, +] + +[package.dependencies] +coverage = {version = ">=5.2.1", extras = ["toml"]} +pytest = ">=4.6" + +[package.extras] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] + +[[package]] +name = "pytest-django" +version = "4.8.0" +description = "A Django plugin for pytest." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest-django-4.8.0.tar.gz", hash = "sha256:5d054fe011c56f3b10f978f41a8efb2e5adfc7e680ef36fb571ada1f24779d90"}, + {file = "pytest_django-4.8.0-py3-none-any.whl", hash = "sha256:ca1ddd1e0e4c227cf9e3e40a6afc6d106b3e70868fd2ac5798a22501271cd0c7"}, +] + +[package.dependencies] +pytest = ">=7.0.0" + +[package.extras] +docs = ["sphinx", "sphinx-rtd-theme"] +testing = ["Django", "django-configurations (>=2.0)"] + [[package]] name = "python-dateutil" version = "2.9.0.post0" @@ -1561,4 +1662,4 @@ filelock = ">=3.4" [metadata] lock-version = "2.0" python-versions = "^3.10,<3.12" -content-hash = "78f859d93ec1f207dbdebd5b608abfac44f87bb254a37ebeafaaf1823f605a71" +content-hash = "76711479953fc14d7761c3bdcc27088d301df318ebda1a6d8c4a4ab930e341f3" diff --git a/pyproject.toml b/pyproject.toml index e9dfe6d4..dbba8ce7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,10 +55,9 @@ ipython = "^7.28.0" ruff = "^0.4.10" [tool.poetry.group.tests.dependencies] -coverage = "^7.5.4" - -[tool.poetry.group.tests] -optional = true +pytest = "^8.2.2" +pytest-cov = "^5.0.0" +pytest-django = "^4.8.0" [tool.poetry.group.docs.dependencies] sphinx-rtd-theme = "^1.0.0" @@ -73,6 +72,10 @@ version = "1.4.25" [tool.ruff.lint] select = ["I", "F401"] +[tool.pytest.ini_options] +DJANGO_SETTINGS_MODULE = "sith.settings" +python_files = ["tests.py", "test_*.py", "*_tests.py"] + [build-system] requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" diff --git a/rootplace/tests.py b/rootplace/tests.py index 80119edf..81d0b616 100644 --- a/rootplace/tests.py +++ b/rootplace/tests.py @@ -13,10 +13,11 @@ # OR WITHIN THE LOCAL FILE "LICENSE" # # -from datetime import date, timedelta +from datetime import timedelta from django.test import TestCase from django.urls import reverse +from django.utils.timezone import localtime, now from club.models import Club from core.models import RealGroup, User @@ -41,7 +42,7 @@ class MergeUserTest(TestCase): ) def setUp(self) -> None: - self.client.login(username="root", password="plop") + self.client.force_login(self.root) def test_simple(self): self.to_delete.first_name = "Biggus" @@ -66,15 +67,15 @@ class MergeUserTest(TestCase): self.to_keep = User.objects.get(pk=self.to_keep.pk) # fields of to_delete should be assigned to to_keep # if they were not set beforehand - self.assertEqual("Biggus", self.to_keep.first_name) - self.assertEqual("Dickus", self.to_keep.last_name) - self.assertEqual("B'ian", self.to_keep.nick_name) - self.assertEqual("Jerusalem", self.to_keep.address) - self.assertEqual("Rome", self.to_keep.parent_address) - self.assertEqual(3, self.to_keep.groups.count()) - groups = list(self.to_keep.groups.all()) - expected = [subscribers, mde_admin, sas_admin] - self.assertCountEqual(groups, expected) + assert "Biggus" == self.to_keep.first_name + assert "Dickus" == self.to_keep.last_name + assert "B'ian" == self.to_keep.nick_name + assert "Jerusalem" == self.to_keep.address + assert "Rome" == self.to_keep.parent_address + assert (3, self.to_keep.groups.count()) + groups = sorted(self.to_keep.groups.all(), key=lambda i: i.id) + expected = sorted([subscribers, mde_admin, sas_admin], key=lambda i: i.id) + assert groups == expected def test_both_subscribers_and_with_account(self): Customer(user=self.to_keep, account_id="11000l", amount=0).save() @@ -113,7 +114,7 @@ class MergeUserTest(TestCase): quantity=4, payment_method="SITH_ACCOUNT", ).save() - today = date.today() + today = localtime(now()).date() # both subscriptions began last month and shall end in 5 months Subscription( member=self.to_keep, @@ -137,9 +138,9 @@ class MergeUserTest(TestCase): # to_delete had 20€ and bought 4 barbar # total should be 10 - 4 + 20 - 8 = 18 self.assertAlmostEqual(18, self.to_keep.customer.amount, delta=0.0001) - self.assertEqual(2, self.to_keep.customer.buyings.count()) - self.assertEqual(2, self.to_keep.customer.refillings.count()) - self.assertTrue(self.to_keep.is_subscribed) + assert self.to_keep.customer.buyings.count() == 2 + assert self.to_keep.customer.refillings.count() == 2 + assert self.to_keep.is_subscribed # to_keep had 5 months of subscription remaining and received # 5 more months from to_delete, so he should be subscribed for 10 months self.assertAlmostEqual( @@ -191,7 +192,7 @@ class MergeUserTest(TestCase): self.assertRedirects(res, self.to_keep.get_absolute_url()) # to_delete had 20€ and bought 4 barbar worth 2€ each # total should be 20 - 8 = 12 - self.assertTrue(hasattr(self.to_keep, "customer")) + assert hasattr(self.to_keep, "customer") self.assertAlmostEqual(12, self.to_keep.customer.amount, delta=0.0001) def test_delete_has_no_account(self): @@ -219,5 +220,5 @@ class MergeUserTest(TestCase): self.assertRedirects(res, self.to_keep.get_absolute_url()) # to_keep had 20€ and bought 4 barbar worth 2€ each # total should be 20 - 8 = 12 - self.assertTrue(hasattr(self.to_keep, "customer")) + assert hasattr(self.to_keep, "customer") self.assertAlmostEqual(12, self.to_keep.customer.amount, delta=0.0001) diff --git a/sith/settings.py b/sith/settings.py index df2b4ced..8680be2a 100644 --- a/sith/settings.py +++ b/sith/settings.py @@ -57,6 +57,7 @@ SECRET_KEY = "(4sjxvhz@m5$0a$j0_pqicnc$s!vbve)z+&++m%g%bjhlz4+g2" # SECURITY WARNING: don't run with debug turned on in production! DEBUG = False +TESTING = "pytest" in sys.modules INTERNAL_IPS = ["127.0.0.1"] ALLOWED_HOSTS = ["*"] @@ -113,8 +114,6 @@ MIDDLEWARE = ( "core.middleware.SignalRequestMiddleware", ) -TEST_RUNNER = "sith.testrunner.SithTestRunner" - ROOT_URLCONF = "sith.urls" TEMPLATES = [ @@ -697,7 +696,7 @@ if DEBUG: SASS_INCLUDE_FOLDERS = ["core/static/"] SENTRY_ENV = "development" -if "test" in sys.argv: +if TESTING: CAPTCHA_TEST_MODE = True if SENTRY_DSN: diff --git a/sith/testrunner.py b/sith/testrunner.py deleted file mode 100644 index 1112cf89..00000000 --- a/sith/testrunner.py +++ /dev/null @@ -1,9 +0,0 @@ -from django.core.management import call_command -from django.test.runner import DiscoverRunner - - -class SithTestRunner(DiscoverRunner): - def setup_databases(self, **kwargs): - res = super().setup_databases(**kwargs) - call_command("populate") - return res diff --git a/subscription/tests.py b/subscription/tests.py index 1b9924e8..c347ab65 100644 --- a/subscription/tests.py +++ b/subscription/tests.py @@ -14,8 +14,9 @@ # # from datetime import date -from unittest import mock +import freezegun +import pytest from django.conf import settings from django.test import TestCase @@ -23,113 +24,92 @@ from core.models import User from subscription.models import Subscription -class FakeDate(date): - """A fake replacement for date that can be mocked for testing.""" - - def __new__(cls, *args, **kwargs): - return date.__new__(date, *args, **kwargs) +@pytest.mark.parametrize( + ("today", "duration", "expected_start"), + [ + (date(2020, 9, 18), 1, date(2020, 9, 18)), + (date(2020, 9, 18), 2, date(2020, 9, 18)), + (date(2020, 5, 17), 3, date(2020, 2, 15)), + (date(2021, 1, 18), 4, date(2020, 8, 15)), + (date(2020, 9, 18), 4, date(2020, 8, 15)), + ], +) +def test_subscription_compute_start_from_today(today, duration, expected_start): + with freezegun.freeze_time(today): + assert Subscription.compute_start(duration=duration) == expected_start -def date_mock_today(year, month, day): - FakeDate.today = classmethod(lambda cls: date(year, month, day)) +@pytest.mark.parametrize( + ("start_date", "duration", "expected_start"), + [ + (date(2020, 5, 17), 1, date(2020, 5, 17)), + (date(2020, 5, 17), 2, date(2020, 5, 17)), + (date(2020, 5, 17), 3, date(2020, 2, 15)), + (date(2020, 1, 11), 3, date(2019, 8, 15)), + ], +) +def test_subscription_compute_start_explicit(start_date, duration, expected_start): + assert Subscription.compute_start(start_date, duration=duration) == expected_start -class SubscriptionUnitTest(TestCase): - @mock.patch("subscription.models.date", FakeDate) - def test_start_dates_sliding_without_start(self): - date_mock_today(2015, 9, 18) - d = Subscription.compute_start(duration=1) - self.assertTrue(d == date(2015, 9, 18)) - self.assertTrue(Subscription.compute_start(duration=2) == date(2015, 9, 18)) +@pytest.mark.parametrize( + ("today", "duration", "expected_end"), + [ + (date(2020, 9, 18), 1, date(2021, 3, 18)), + (date(2020, 9, 18), 2, date(2021, 9, 18)), + (date(2020, 9, 18), 3, date(2022, 2, 15)), + (date(2020, 5, 17), 4, date(2022, 8, 15)), + (date(2020, 9, 18), 0.33, date(2020, 11, 18)), + (date(2020, 9, 18), 0.67, date(2021, 1, 19)), + (date(2020, 9, 18), 0.5, date(2020, 12, 18)), + ], +) +def test_subscription_compute_end_from_today(today, duration, expected_end): + with freezegun.freeze_time(today): + assert Subscription.compute_end(duration=duration) == expected_end - def test_start_dates_sliding_with_start(self): - self.assertTrue( - Subscription.compute_start(date(2015, 5, 17), 1) == date(2015, 5, 17) - ) - self.assertTrue( - Subscription.compute_start(date(2015, 5, 17), 2) == date(2015, 5, 17) - ) - @mock.patch("subscription.models.date", FakeDate) - def test_start_dates_not_sliding_without_start(self): - date_mock_today(2015, 5, 17) - self.assertTrue(Subscription.compute_start(duration=3) == date(2015, 2, 15)) - date_mock_today(2016, 1, 18) - self.assertTrue(Subscription.compute_start(duration=4) == date(2015, 8, 15)) - date_mock_today(2015, 9, 18) - self.assertTrue(Subscription.compute_start(duration=4) == date(2015, 8, 15)) - - def test_start_dates_not_sliding_with_start(self): - self.assertTrue( - Subscription.compute_start(date(2015, 5, 17), 3) == date(2015, 2, 15) - ) - self.assertTrue( - Subscription.compute_start(date(2015, 1, 11), 3) == date(2014, 8, 15) - ) - - @mock.patch("subscription.models.date", FakeDate) - def test_end_dates_sliding(self): - date_mock_today(2015, 9, 18) - d = Subscription.compute_end(2) - self.assertTrue(d == date(2016, 9, 18)) - d = Subscription.compute_end(1) - self.assertTrue(d == date(2016, 3, 18)) - - @mock.patch("subscription.models.date", FakeDate) - def test_end_dates_not_sliding_without_start(self): - date_mock_today(2015, 9, 18) - d = Subscription.compute_end(duration=3) - self.assertTrue(d == date(2017, 2, 15)) - d = Subscription.compute_end(duration=4) - self.assertTrue(d == date(2017, 8, 15)) - - @mock.patch("subscription.models.date", FakeDate) - def test_end_dates_with_float(self): - date_mock_today(2015, 9, 18) - d = Subscription.compute_end(duration=0.33) - self.assertTrue(d == date(2015, 11, 18)) - d = Subscription.compute_end(duration=0.67) - self.assertTrue(d == date(2016, 1, 19)) - d = Subscription.compute_end(duration=0.5) - self.assertTrue(d == date(2015, 12, 18)) - - def test_end_dates_not_sliding_with_start(self): - d = Subscription.compute_end(duration=3, start=date(2015, 9, 18)) - self.assertTrue(d == date(2017, 3, 18)) - d = Subscription.compute_end(duration=4, start=date(2015, 9, 18)) - self.assertTrue(d == date(2017, 9, 18)) +@pytest.mark.parametrize( + ("start_date", "duration", "expected_end"), + [ + (date(2020, 9, 18), 3, date(2022, 3, 18)), + (date(2020, 9, 18), 4, date(2022, 9, 18)), + ], +) +def test_subscription_compute_end_from_today(start_date, duration, expected_end): + assert Subscription.compute_end(duration, start_date) == expected_end class SubscriptionIntegrationTest(TestCase): @classmethod - def setUp(cls): - cls.user = User.objects.filter(username="public").first() + def setUpTestData(cls): + cls.user = User.objects.get(username="public") def test_duration_one_month(self): s = Subscription( - member=User.objects.filter(pk=self.user.pk).first(), + member=self.user, subscription_type=list(settings.SITH_SUBSCRIPTIONS.keys())[3], payment_method=settings.SITH_SUBSCRIPTION_PAYMENT_METHOD[0], ) s.subscription_start = date(2017, 8, 29) s.subscription_end = s.compute_end(duration=0.166, start=s.subscription_start) s.save() - self.assertTrue(s.subscription_end == date(2017, 9, 29)) + assert s.subscription_end == date(2017, 9, 29) def test_duration_two_months(self): s = Subscription( - member=User.objects.filter(pk=self.user.pk).first(), + member=self.user, subscription_type=list(settings.SITH_SUBSCRIPTIONS.keys())[3], payment_method=settings.SITH_SUBSCRIPTION_PAYMENT_METHOD[0], ) s.subscription_start = date(2017, 8, 29) s.subscription_end = s.compute_end(duration=0.333, start=s.subscription_start) s.save() - self.assertTrue(s.subscription_end == date(2017, 10, 29)) + assert s.subscription_end == date(2017, 10, 29) def test_duration_one_day(self): s = Subscription( - member=User.objects.filter(pk=self.user.pk).first(), + member=self.user, subscription_type=list(settings.SITH_SUBSCRIPTIONS.keys())[3], payment_method=settings.SITH_SUBSCRIPTION_PAYMENT_METHOD[0], ) @@ -139,44 +119,43 @@ class SubscriptionIntegrationTest(TestCase): start=s.subscription_start, ) s.save() - self.assertTrue(s.subscription_end == date(2017, 8, 30)) + assert s.subscription_end == date(2017, 8, 30) def test_duration_three_months(self): s = Subscription( - member=User.objects.filter(pk=self.user.pk).first(), + member=self.user, subscription_type=list(settings.SITH_SUBSCRIPTIONS.keys())[3], payment_method=settings.SITH_SUBSCRIPTION_PAYMENT_METHOD[0], ) s.subscription_start = date(2017, 8, 29) s.subscription_end = s.compute_end(duration=0.5, start=s.subscription_start) s.save() - self.assertTrue(s.subscription_end == date(2017, 11, 29)) + assert s.subscription_end == date(2017, 11, 29) def test_duration_four_months(self): s = Subscription( - member=User.objects.filter(pk=self.user.pk).first(), + member=self.user, subscription_type=list(settings.SITH_SUBSCRIPTIONS.keys())[3], payment_method=settings.SITH_SUBSCRIPTION_PAYMENT_METHOD[0], ) s.subscription_start = date(2017, 8, 29) s.subscription_end = s.compute_end(duration=0.67, start=s.subscription_start) s.save() - self.assertTrue(s.subscription_end == date(2017, 12, 30)) + assert s.subscription_end == date(2017, 12, 30) def test_duration_six_weeks(self): s = Subscription( - member=User.objects.filter(pk=self.user.pk).first(), + member=self.user, subscription_type=list(settings.SITH_SUBSCRIPTIONS.keys())[3], payment_method=settings.SITH_SUBSCRIPTION_PAYMENT_METHOD[0], ) s.subscription_start = date(2018, 9, 1) s.subscription_end = s.compute_end(duration=0.23, start=s.subscription_start) s.save() - self.assertTrue(s.subscription_end == date(2018, 10, 13)) + assert s.subscription_end == date(2018, 10, 13) - @mock.patch("subscription.models.date", FakeDate) def test_dates_sliding_with_subscribed_user(self): - user = User.objects.filter(pk=self.user.pk).first() + user = self.user s = Subscription( member=user, subscription_type="deux-semestres", @@ -188,18 +167,16 @@ class SubscriptionIntegrationTest(TestCase): start=s.subscription_start, ) s.save() - self.assertTrue(s.subscription_end == date(2016, 8, 29)) - date_mock_today(2016, 8, 25) - d = Subscription.compute_end( - duration=settings.SITH_SUBSCRIPTIONS["deux-semestres"]["duration"], - user=user, - ) + assert s.subscription_end == date(2016, 8, 29) + with freezegun.freeze_time("2016-08-25"): + d = Subscription.compute_end( + duration=settings.SITH_SUBSCRIPTIONS["deux-semestres"]["duration"], + user=user, + ) + assert d == date(2017, 8, 29) - self.assertTrue(d == date(2017, 8, 29)) - - @mock.patch("subscription.models.date", FakeDate) def test_dates_renewal_sliding_during_two_free_monthes(self): - user = User.objects.filter(pk=self.user.pk).first() + user = self.user s = Subscription( member=user, subscription_type="deux-mois-essai", @@ -211,17 +188,16 @@ class SubscriptionIntegrationTest(TestCase): start=s.subscription_start, ) s.save() - self.assertTrue(s.subscription_end == date(2015, 10, 29)) - date_mock_today(2015, 9, 25) - d = Subscription.compute_end( - duration=settings.SITH_SUBSCRIPTIONS["deux-semestres"]["duration"], - user=user, - ) - self.assertTrue(d == date(2016, 10, 29)) + assert s.subscription_end == date(2015, 10, 29) + with freezegun.freeze_time("2015-09-25"): + d = Subscription.compute_end( + duration=settings.SITH_SUBSCRIPTIONS["deux-semestres"]["duration"], + user=user, + ) + assert d == date(2016, 10, 29) - @mock.patch("subscription.models.date", FakeDate) def test_dates_renewal_sliding_after_two_free_monthes(self): - user = User.objects.filter(pk=self.user.pk).first() + user = self.user s = Subscription( member=user, subscription_type="deux-mois-essai", @@ -233,10 +209,10 @@ class SubscriptionIntegrationTest(TestCase): start=s.subscription_start, ) s.save() - self.assertTrue(s.subscription_end == date(2015, 10, 29)) - date_mock_today(2015, 11, 5) - d = Subscription.compute_end( - duration=settings.SITH_SUBSCRIPTIONS["deux-semestres"]["duration"], - user=user, - ) - self.assertTrue(d == date(2016, 11, 5)) + assert s.subscription_end == date(2015, 10, 29) + with freezegun.freeze_time("2015-11-05"): + d = Subscription.compute_end( + duration=settings.SITH_SUBSCRIPTIONS["deux-semestres"]["duration"], + user=user, + ) + assert d == date(2016, 11, 5)
UtilisateurRôleDescription
Cotis 2 semestres128.00 €
Barbar31.70 €