nk20/apps/treasury/tests/test_treasury.py

485 lines
18 KiB
Python
Raw Normal View History

Update 131 files - /apps/activity/api/serializers.py - /apps/activity/api/urls.py - /apps/activity/api/views.py - /apps/activity/tests/test_activities.py - /apps/activity/__init__.py - /apps/activity/admin.py - /apps/activity/apps.py - /apps/activity/forms.py - /apps/activity/tables.py - /apps/activity/urls.py - /apps/activity/views.py - /apps/api/__init__.py - /apps/api/apps.py - /apps/api/serializers.py - /apps/api/tests.py - /apps/api/urls.py - /apps/api/views.py - /apps/api/viewsets.py - /apps/logs/signals.py - /apps/logs/apps.py - /apps/logs/__init__.py - /apps/logs/api/serializers.py - /apps/logs/api/urls.py - /apps/logs/api/views.py - /apps/member/api/serializers.py - /apps/member/api/urls.py - /apps/member/api/views.py - /apps/member/templatetags/memberinfo.py - /apps/member/__init__.py - /apps/member/admin.py - /apps/member/apps.py - /apps/member/auth.py - /apps/member/forms.py - /apps/member/hashers.py - /apps/member/signals.py - /apps/member/tables.py - /apps/member/urls.py - /apps/member/views.py - /apps/note/api/serializers.py - /apps/note/api/urls.py - /apps/note/api/views.py - /apps/note/models/__init__.py - /apps/note/static/note/js/consos.js - /apps/note/templates/note/mails/negative_balance.txt - /apps/note/templatetags/getenv.py - /apps/note/templatetags/pretty_money.py - /apps/note/tests/test_transactions.py - /apps/note/__init__.py - /apps/note/admin.py - /apps/note/apps.py - /apps/note/forms.py - /apps/note/signals.py - /apps/note/tables.py - /apps/note/urls.py - /apps/note/views.py - /apps/permission/api/serializers.py - /apps/permission/api/urls.py - /apps/permission/api/views.py - /apps/permission/templatetags/perms.py - /apps/permission/tests/test_oauth2.py - /apps/permission/tests/test_permission_denied.py - /apps/permission/tests/test_permission_queries.py - /apps/permission/tests/test_rights_page.py - /apps/permission/__init__.py - /apps/permission/admin.py - /apps/permission/backends.py - /apps/permission/apps.py - /apps/permission/decorators.py - /apps/permission/permissions.py - /apps/permission/scopes.py - /apps/permission/signals.py - /apps/permission/tables.py - /apps/permission/urls.py - /apps/permission/views.py - /apps/registration/tests/test_registration.py - /apps/registration/__init__.py - /apps/registration/apps.py - /apps/registration/forms.py - /apps/registration/tables.py - /apps/registration/tokens.py - /apps/registration/urls.py - /apps/registration/views.py - /apps/treasury/api/serializers.py - /apps/treasury/api/urls.py - /apps/treasury/api/views.py - /apps/treasury/templatetags/escape_tex.py - /apps/treasury/tests/test_treasury.py - /apps/treasury/__init__.py - /apps/treasury/admin.py - /apps/treasury/apps.py - /apps/treasury/forms.py - /apps/treasury/signals.py - /apps/treasury/tables.py - /apps/treasury/urls.py - /apps/treasury/views.py - /apps/wei/api/serializers.py - /apps/wei/api/urls.py - /apps/wei/api/views.py - /apps/wei/forms/surveys/__init__.py - /apps/wei/forms/surveys/base.py - /apps/wei/forms/surveys/wei2021.py - /apps/wei/forms/surveys/wei2022.py - /apps/wei/forms/surveys/wei2023.py - /apps/wei/forms/__init__.py - /apps/wei/forms/registration.py - /apps/wei/management/commands/export_wei_registrations.py - /apps/wei/management/commands/import_scores.py - /apps/wei/management/commands/wei_algorithm.py - /apps/wei/templates/wei/weilist_sample.tex - /apps/wei/tests/test_wei_algorithm_2021.py - /apps/wei/tests/test_wei_algorithm_2022.py - /apps/wei/tests/test_wei_algorithm_2023.py - /apps/wei/tests/test_wei_registration.py - /apps/wei/__init__.py - /apps/wei/admin.py - /apps/wei/apps.py - /apps/wei/tables.py - /apps/wei/urls.py - /apps/wei/views.py - /note_kfet/settings/__init__.py - /note_kfet/settings/base.py - /note_kfet/settings/development.py - /note_kfet/settings/secrets_example.py - /note_kfet/static/js/base.js - /note_kfet/admin.py - /note_kfet/inputs.py - /note_kfet/middlewares.py - /note_kfet/urls.py - /note_kfet/views.py - /note_kfet/wsgi.py - /entrypoint.sh
2024-02-07 01:26:49 +00:00
# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
2020-09-04 13:53:00 +00:00
# SPDX-License-Identifier: GPL-3.0-or-later
from api.tests import TestAPI
2020-09-04 13:53:00 +00:00
from django.contrib.auth.models import User
from django.core.exceptions import ValidationError
from django.db.models import Q
from django.test import TestCase
from django.urls import reverse
from member.models import Membership, Club
from note.models import SpecialTransaction, NoteSpecial, Transaction
from ..api.views import InvoiceViewSet, ProductViewSet, RemittanceViewSet, RemittanceTypeViewSet, \
SogeCreditViewSet
from ..models import Invoice, Product, Remittance, RemittanceType, SogeCredit
2020-09-04 13:53:00 +00:00
class TestInvoices(TestCase):
"""
Check that invoices can be created and rendered properly.
"""
def setUp(self) -> None:
self.user = User.objects.create_superuser(
username="admintoto",
password="totototo",
email="admin@example.com",
)
self.client.force_login(self.user)
sess = self.client.session
sess["permission_mask"] = 42
sess.save()
self.invoice = Invoice.objects.create(
id=1,
object="Object",
description="Description",
name="Me",
address="Earth",
acquitted=False,
)
self.product = Product.objects.create(
invoice=self.invoice,
designation="Product",
quantity=3,
amount=3.14,
)
def test_admin_page(self):
"""
Display the invoice admin page.
"""
response = self.client.get(reverse("admin:index") + "treasury/invoice/")
self.assertEqual(response.status_code, 200)
def test_invoices_list(self):
"""
Display the list of invoices.
"""
response = self.client.get(reverse("treasury:invoice_list"))
self.assertEqual(response.status_code, 200)
def test_invoice_create(self):
"""
Try to create a new invoice.
"""
response = self.client.get(reverse("treasury:invoice_create"))
self.assertEqual(response.status_code, 200)
response = self.client.post(reverse("treasury:invoice_create"), data={
"id": 42,
"object": "Same object",
2024-03-24 14:20:46 +00:00
"quotation": True,
2020-09-04 13:53:00 +00:00
"description": "Longer description",
"name": "Me and others",
"address": "Alwways earth",
2024-03-24 14:20:46 +00:00
"payment_date": "Maybe someday...",
2020-09-04 13:53:00 +00:00
"acquitted": True,
"products-0-designation": "Designation",
"products-0-quantity": 1,
"products-0-amount": 42,
"products-TOTAL_FORMS": 1,
"products-INITIAL_FORMS": 0,
"products-MIN_NUM_FORMS": 0,
"products-MAX_NUM_FORMS": 1000,
})
self.assertRedirects(response, reverse("treasury:invoice_list"), 302, 200)
self.assertTrue(Invoice.objects.filter(object="Same object", id=42).exists())
self.assertTrue(Product.objects.filter(designation="Designation", invoice_id=42).exists())
self.assertTrue(Invoice.objects.get(id=42).tex)
def test_invoice_update(self):
"""
Try to update an invoice.
"""
response = self.client.get(reverse("treasury:invoice_update", args=(self.invoice.id,)))
self.assertEqual(response.status_code, 200)
data = {
"object": "Same object",
"description": "Longer description",
"name": "Me and others",
2024-03-24 14:55:46 +00:00
"quotation": False,
2020-09-04 13:53:00 +00:00
"address": "Always earth",
"acquitted": True,
2024-03-24 14:55:46 +00:00
"payment_date": "Never",
2020-09-04 13:53:00 +00:00
"locked": True,
"products-0-designation": "Designation",
"products-0-quantity": 1,
"products-0-amount": 4200,
"products-1-designation": "Second designation",
"products-1-quantity": 5,
"products-1-amount": -1800,
"products-TOTAL_FORMS": 2,
"products-INITIAL_FORMS": 0,
"products-MIN_NUM_FORMS": 0,
"products-MAX_NUM_FORMS": 1000,
}
response = self.client.post(reverse("treasury:invoice_update", args=(self.invoice.id,)), data=data)
self.assertRedirects(response, reverse("treasury:invoice_list"), 302, 200)
self.invoice.refresh_from_db()
self.assertTrue(Invoice.objects.filter(pk=1, object="Same object", locked=True).exists())
self.assertTrue(Product.objects.filter(designation="Second designation", invoice_id=1).exists())
# Resend the same data, but the invoice is locked.
response = self.client.get(reverse("treasury:invoice_update", args=(self.invoice.id,)))
self.assertTrue(response.status_code, 200)
response = self.client.post(reverse("treasury:invoice_update", args=(self.invoice.id,)), data=data)
self.assertTrue(response.status_code, 200)
def test_delete_invoice(self):
"""
Try to delete an invoice.
"""
response = self.client.get(reverse("treasury:invoice_delete", args=(self.invoice.id,)))
self.assertEqual(response.status_code, 200)
# Can't delete a locked invoice
self.invoice.locked = True
self.invoice.save()
response = self.client.delete(reverse("treasury:invoice_delete", args=(self.invoice.id,)))
self.assertEqual(response.status_code, 403)
self.assertTrue(Invoice.objects.filter(pk=self.invoice.id).exists())
# Unlock invoice and truly delete it.
self.invoice.locked = False
self.invoice._force_save = True
self.invoice.save()
response = self.client.delete(reverse("treasury:invoice_delete", args=(self.invoice.id,)))
self.assertRedirects(response, reverse("treasury:invoice_list"), 302, 200)
self.assertFalse(Invoice.objects.filter(pk=self.invoice.id).exists())
def test_invoice_render_pdf(self):
"""
Generate the PDF file of an invoice.
"""
response = self.client.get(reverse("treasury:invoice_render", args=(self.invoice.id,)))
self.assertEqual(response.status_code, 200)
def test_invoice_api(self):
"""
Load some API pages
"""
response = self.client.get("/api/treasury/invoice/")
self.assertEqual(response.status_code, 200)
response = self.client.get("/api/treasury/product/")
self.assertEqual(response.status_code, 200)
class TestRemittances(TestCase):
"""
Create some credits and close remittances.
"""
fixtures = ('initial',)
def setUp(self) -> None:
self.user = User.objects.create_superuser(
username="admintoto",
password="totototo",
email="admin@example.com",
)
self.client.force_login(self.user)
sess = self.client.session
sess["permission_mask"] = 42
sess.save()
self.credit = SpecialTransaction.objects.create(
source=NoteSpecial.objects.get(special_type="Chèque"),
destination=self.user.note,
amount=4200,
reason="Credit",
last_name="TOTO",
first_name="Toto",
bank="Société générale",
)
self.second_credit = SpecialTransaction.objects.create(
source=self.user.note,
destination=NoteSpecial.objects.get(special_type="Chèque"),
amount=424200,
reason="Second credit",
last_name="TOTO",
first_name="Toto",
bank="Société générale",
)
self.remittance = Remittance.objects.create(
remittance_type=RemittanceType.objects.get(),
comment="Test remittance",
closed=False,
)
self.credit.specialtransactionproxy.remittance = self.remittance
self.credit.specialtransactionproxy.save()
def test_admin_page(self):
"""
Load the admin page.
"""
response = self.client.get(reverse("admin:index") + "treasury/remittance/")
self.assertEqual(response.status_code, 200)
def test_remittances_list(self):
"""
Display the remittance list.
:return:
"""
response = self.client.get(reverse("treasury:remittance_list"))
self.assertEqual(response.status_code, 200)
def test_remittance_create(self):
"""
Create a new Remittance.
"""
response = self.client.get(reverse("treasury:remittance_create"))
self.assertEqual(response.status_code, 200)
response = self.client.post(reverse("treasury:remittance_create"), data=dict(
remittance_type=RemittanceType.objects.get().pk,
comment="Created remittance",
))
self.assertRedirects(response, reverse("treasury:remittance_list"), 302, 200)
self.assertTrue(Remittance.objects.filter(comment="Created remittance").exists())
def test_remittance_update(self):
"""
Update an existing remittance.
"""
response = self.client.get(reverse("treasury:remittance_update", args=(self.remittance.pk,)))
self.assertEqual(response.status_code, 200)
response = self.client.post(reverse("treasury:remittance_update", args=(self.remittance.pk,)), data=dict(
comment="Updated remittance",
))
self.assertRedirects(response, reverse("treasury:remittance_list"), 302, 200)
self.assertTrue(Remittance.objects.filter(comment="Updated remittance").exists())
def test_remittance_close(self):
"""
Try to close an open remittance.
"""
response = self.client.get(reverse("treasury:remittance_update", args=(self.remittance.pk,)))
self.assertEqual(response.status_code, 200)
response = self.client.post(reverse("treasury:remittance_update", args=(self.remittance.pk,)), data=dict(
comment="Closed remittance",
close=True,
))
self.assertRedirects(response, reverse("treasury:remittance_list"), 302, 200)
self.assertTrue(Remittance.objects.filter(comment="Closed remittance", closed=True).exists())
def test_remittance_link_transaction(self):
"""
Link a transaction to an open remittance.
"""
response = self.client.get(reverse("treasury:link_transaction", args=(self.credit.pk,)))
self.assertEqual(response.status_code, 200)
response = self.client.post(reverse("treasury:link_transaction", args=(self.credit.pk,)), data=dict(
remittance=self.remittance.pk,
last_name="Last Name",
first_name="First Name",
bank="Bank",
))
self.assertRedirects(response, reverse("treasury:remittance_list"), 302, 200)
self.credit.refresh_from_db()
self.assertEqual(self.credit.last_name, "Last Name")
self.assertEqual(self.remittance.transactions.count(), 1)
response = self.client.get(reverse("treasury:unlink_transaction", args=(self.credit.pk,)))
self.assertRedirects(response, reverse("treasury:remittance_list"), 302, 200)
def test_invoice_api(self):
"""
Load some API pages
"""
response = self.client.get("/api/treasury/remittance_type/")
self.assertEqual(response.status_code, 200)
response = self.client.get("/api/treasury/remittance/")
self.assertEqual(response.status_code, 200)
class TestSogeCredits(TestCase):
"""
Check that credits from the Société générale are working correctly.
"""
fixtures = ('initial',)
def setUp(self) -> None:
self.user = User.objects.create_superuser(
username="admintoto",
password="totototo",
email="admin@example.com",
)
self.client.force_login(self.user)
sess = self.client.session
sess["permission_mask"] = 42
sess.save()
self.kfet = Club.objects.get(name="Kfet")
self.bde = self.kfet.parent_club
self.kfet_membership = Membership(
user=self.user,
club=self.kfet,
)
self.kfet_membership._force_renew_parent = True
self.kfet_membership._soge = True
self.kfet_membership.save()
def test_admin_page(self):
"""
Render the admin page.
"""
response = self.client.get(reverse("admin:index") + "treasury/sogecredit/")
self.assertEqual(response.status_code, 200)
def test_sogecredit_list(self):
"""
Display the list of all credits.
"""
response = self.client.get(reverse("treasury:soge_credits"))
self.assertEqual(response.status_code, 200)
response = self.client.get(reverse("treasury:soge_credits") + "?search=toto&valid=")
self.assertEqual(response.status_code, 200)
def test_validate_soge_credit(self):
"""
Try to validate a credit.
"""
soge_credit = SogeCredit.objects.get(user=self.user)
response = self.client.get(reverse("treasury:manage_soge_credit", args=(soge_credit.pk,)))
self.assertEqual(response.status_code, 200)
response = self.client.post(reverse("treasury:manage_soge_credit", args=(soge_credit.pk,)), data=dict(
validate=True,
))
self.assertRedirects(response, reverse("treasury:manage_soge_credit", args=(soge_credit.pk,)), 302, 200)
soge_credit.refresh_from_db()
self.assertTrue(soge_credit.valid)
self.user.note.refresh_from_db()
self.assertEqual(
Transaction.objects.filter(Q(source=self.user.note) | Q(destination=self.user.note)).count(), 3)
self.assertTrue(self.user.profile.soge)
def test_delete_soge_credit(self):
"""
Try to invalidate a credit.
"""
soge_credit = SogeCredit.objects.get(user=self.user)
response = self.client.get(reverse("treasury:manage_soge_credit", args=(soge_credit.pk,)))
self.assertEqual(response.status_code, 200)
self.assertRaises(ValidationError, self.client.post,
reverse("treasury:manage_soge_credit", args=(soge_credit.pk,)), data=dict(delete=True))
2020-09-04 13:53:00 +00:00
SpecialTransaction.objects.create(
source=NoteSpecial.objects.get(special_type="Carte bancaire"),
destination=self.user.note,
amount=self.bde.membership_fee_paid + self.kfet.membership_fee_paid,
quantity=1,
reason="Registration is not complete, pliz pay",
last_name="TOTO",
first_name="Toto",
)
response = self.client.post(reverse("treasury:manage_soge_credit", args=(soge_credit.pk,)),
data=dict(delete=True))
self.assertRedirects(response, reverse("treasury:soge_credits"), 302, 200)
2020-09-04 13:53:00 +00:00
self.assertFalse(SogeCredit.objects.filter(pk=soge_credit.pk))
self.user.note.refresh_from_db()
self.assertEqual(self.user.note.balance, 0)
self.assertEqual(
Transaction.objects.filter(Q(source=self.user.note) | Q(destination=self.user.note)).count(), 4)
2020-09-04 13:53:00 +00:00
self.assertFalse(self.user.profile.soge)
def test_invoice_api(self):
"""
Load some API pages
"""
response = self.client.get("/api/treasury/soge_credit/")
self.assertEqual(response.status_code, 200)
class TestTreasuryAPI(TestAPI):
def setUp(self) -> None:
super().setUp()
self.invoice = Invoice.objects.create(
id=1,
object="Object",
description="Description",
name="Me",
address="Earth",
acquitted=False,
)
self.product = Product.objects.create(
invoice=self.invoice,
designation="Product",
quantity=3,
amount=3.14,
)
self.credit = SpecialTransaction.objects.create(
source=NoteSpecial.objects.get(special_type="Chèque"),
destination=self.user.note,
amount=4200,
reason="Credit",
last_name="TOTO",
first_name="Toto",
bank="Société générale",
)
self.remittance = Remittance.objects.create(
remittance_type=RemittanceType.objects.get(),
comment="Test remittance",
closed=False,
)
self.credit.specialtransactionproxy.remittance = self.remittance
self.credit.specialtransactionproxy.save()
self.kfet = Club.objects.get(name="Kfet")
self.bde = self.kfet.parent_club
self.kfet_membership = Membership(
user=self.user,
club=self.kfet,
)
self.kfet_membership._force_renew_parent = True
self.kfet_membership._soge = True
self.kfet_membership.save()
def test_invoice_api(self):
"""
Load Invoice API page and test all filters and permissions
"""
self.check_viewset(InvoiceViewSet, "/api/treasury/invoice/")
def test_product_api(self):
"""
Load Product API page and test all filters and permissions
"""
self.check_viewset(ProductViewSet, "/api/treasury/product/")
def test_remittance_api(self):
"""
Load Remittance API page and test all filters and permissions
"""
self.check_viewset(RemittanceViewSet, "/api/treasury/remittance/")
def test_remittance_type_api(self):
"""
Load RemittanceType API page and test all filters and permissions
"""
self.check_viewset(RemittanceTypeViewSet, "/api/treasury/remittance_type/")
def test_sogecredit_api(self):
"""
Load SogeCredit API page and test all filters and permissions
"""
self.check_viewset(SogeCreditViewSet, "/api/treasury/soge_credit/")