mirror of https://gitlab.crans.org/bde/nk20
Test and cover note app
This commit is contained in:
parent
c6abad107a
commit
7c9287e387
|
@ -119,10 +119,6 @@ class TransactionAdmin(PolymorphicParentModelAdmin):
|
|||
list_display = ('created_at', 'poly_source', 'poly_destination',
|
||||
'quantity', 'amount', 'valid')
|
||||
list_filter = ('valid',)
|
||||
readonly_fields = (
|
||||
'source',
|
||||
'destination',
|
||||
)
|
||||
|
||||
def poly_source(self, obj):
|
||||
"""
|
||||
|
@ -145,10 +141,7 @@ class TransactionAdmin(PolymorphicParentModelAdmin):
|
|||
Only valid can be edited after creation
|
||||
Else the amount of money would not be transferred
|
||||
"""
|
||||
if obj: # user is editing an existing object
|
||||
return 'created_at', 'source', 'destination', 'quantity', \
|
||||
'amount'
|
||||
return []
|
||||
return 'created_at', 'source', 'destination', 'quantity', 'amount' if obj else ()
|
||||
|
||||
|
||||
@admin.register(MembershipTransaction, site=admin_site)
|
||||
|
@ -157,6 +150,13 @@ class MembershipTransactionAdmin(PolymorphicChildModelAdmin):
|
|||
Admin customisation for MembershipTransaction
|
||||
"""
|
||||
|
||||
def get_readonly_fields(self, request, obj=None):
|
||||
"""
|
||||
Only valid can be edited after creation
|
||||
Else the amount of money would not be transferred
|
||||
"""
|
||||
return ('created_at', 'source', 'destination', 'quantity', 'amount') if obj else ()
|
||||
|
||||
|
||||
@admin.register(RecurrentTransaction, site=admin_site)
|
||||
class RecurrentTransactionAdmin(PolymorphicChildModelAdmin):
|
||||
|
@ -164,6 +164,13 @@ class RecurrentTransactionAdmin(PolymorphicChildModelAdmin):
|
|||
Admin customisation for RecurrentTransaction
|
||||
"""
|
||||
|
||||
def get_readonly_fields(self, request, obj=None):
|
||||
"""
|
||||
Only valid can be edited after creation
|
||||
Else the amount of money would not be transferred
|
||||
"""
|
||||
return ('created_at', 'source', 'destination', 'quantity', 'amount') if obj else ()
|
||||
|
||||
|
||||
@admin.register(SpecialTransaction, site=admin_site)
|
||||
class SpecialTransactionAdmin(PolymorphicChildModelAdmin):
|
||||
|
@ -171,6 +178,13 @@ class SpecialTransactionAdmin(PolymorphicChildModelAdmin):
|
|||
Admin customisation for SpecialTransaction
|
||||
"""
|
||||
|
||||
def get_readonly_fields(self, request, obj=None):
|
||||
"""
|
||||
Only valid can be edited after creation
|
||||
Else the amount of money would not be transferred
|
||||
"""
|
||||
return ('created_at', 'source', 'destination', 'quantity', 'amount') if obj else ()
|
||||
|
||||
|
||||
@admin.register(TransactionTemplate, site=admin_site)
|
||||
class TransactionTemplateAdmin(admin.ModelAdmin):
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from django.conf import settings
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
from rest_framework.exceptions import ValidationError
|
||||
|
@ -124,9 +125,9 @@ class ConsumerSerializer(serializers.ModelSerializer):
|
|||
Display information about the associated note
|
||||
"""
|
||||
# If the user has no right to see the note, then we only display the note identifier
|
||||
if PermissionBackend.check_perm(get_current_authenticated_user(), "note.view_note", obj.note):
|
||||
return NotePolymorphicSerializer().to_representation(obj.note)
|
||||
return dict(id=obj.note.id, name=str(obj.note))
|
||||
return NotePolymorphicSerializer().to_representation(obj.note)\
|
||||
if PermissionBackend.check_perm(get_current_authenticated_user(), "note.view_note", obj.note)\
|
||||
else dict(id=obj.note.id, name=str(obj.note))
|
||||
|
||||
def get_email_confirmed(self, obj):
|
||||
if isinstance(obj.note, NoteUser):
|
||||
|
@ -231,12 +232,10 @@ class TransactionPolymorphicSerializer(PolymorphicSerializer):
|
|||
SpecialTransaction: SpecialTransactionSerializer,
|
||||
}
|
||||
|
||||
try:
|
||||
if "activity" in settings.INSTALLED_APPS:
|
||||
from activity.models import GuestTransaction
|
||||
from activity.api.serializers import GuestTransactionSerializer
|
||||
model_serializer_mapping[GuestTransaction] = GuestTransactionSerializer
|
||||
except ImportError: # Activity app is not loaded
|
||||
pass
|
||||
|
||||
def validate(self, attrs):
|
||||
resource_type = attrs.pop(self.resource_type_field_name)
|
||||
|
|
|
@ -45,7 +45,7 @@ class NotePolymorphicViewSet(ReadProtectedModelViewSet):
|
|||
| Q(alias__normalized_name__iregex="^" + alias.lower())
|
||||
)
|
||||
|
||||
return queryset
|
||||
return queryset.order_by("id")
|
||||
|
||||
|
||||
class AliasViewSet(ReadProtectedModelViewSet):
|
||||
|
@ -72,7 +72,6 @@ class AliasViewSet(ReadProtectedModelViewSet):
|
|||
try:
|
||||
self.perform_destroy(instance)
|
||||
except ValidationError as e:
|
||||
print(e)
|
||||
return Response({e.code: e.message}, status.HTTP_400_BAD_REQUEST)
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
|
@ -101,7 +100,7 @@ class AliasViewSet(ReadProtectedModelViewSet):
|
|||
),
|
||||
all=True)
|
||||
|
||||
return queryset
|
||||
return queryset.order_by("name")
|
||||
|
||||
|
||||
class ConsumerViewSet(ReadOnlyProtectedModelViewSet):
|
||||
|
@ -120,7 +119,7 @@ class ConsumerViewSet(ReadOnlyProtectedModelViewSet):
|
|||
queryset = super().get_queryset()
|
||||
|
||||
alias = self.request.query_params.get("alias", ".*")
|
||||
queryset = queryset.order_by('name').prefetch_related('note')
|
||||
queryset = queryset.prefetch_related('note')
|
||||
# We match first an alias if it is matched without normalization,
|
||||
# then if the normalized pattern matches a normalized alias.
|
||||
queryset = queryset.filter(
|
||||
|
@ -138,7 +137,7 @@ class ConsumerViewSet(ReadOnlyProtectedModelViewSet):
|
|||
),
|
||||
all=True)
|
||||
|
||||
return queryset.distinct()
|
||||
return queryset.order_by('name').distinct()
|
||||
|
||||
|
||||
class TemplateCategoryViewSet(ReadProtectedModelViewSet):
|
||||
|
@ -147,7 +146,7 @@ class TemplateCategoryViewSet(ReadProtectedModelViewSet):
|
|||
The djangorestframework plugin will get all `TemplateCategory` objects, serialize it to JSON with the given serializer,
|
||||
then render it on /api/note/transaction/category/
|
||||
"""
|
||||
queryset = TemplateCategory.objects.all()
|
||||
queryset = TemplateCategory.objects.order_by("name").all()
|
||||
serializer_class = TemplateCategorySerializer
|
||||
filter_backends = [SearchFilter]
|
||||
search_fields = ['$name', ]
|
||||
|
@ -159,7 +158,7 @@ class TransactionTemplateViewSet(viewsets.ModelViewSet):
|
|||
The djangorestframework plugin will get all `TransactionTemplate` objects, serialize it to JSON with the given serializer,
|
||||
then render it on /api/note/transaction/template/
|
||||
"""
|
||||
queryset = TransactionTemplate.objects.all()
|
||||
queryset = TransactionTemplate.objects.order_by("name").all()
|
||||
serializer_class = TransactionTemplateSerializer
|
||||
filter_backends = [SearchFilter, DjangoFilterBackend]
|
||||
filterset_fields = ['name', 'amount', 'display', 'category', ]
|
||||
|
@ -172,7 +171,7 @@ class TransactionViewSet(ReadProtectedModelViewSet):
|
|||
The djangorestframework plugin will get all `Transaction` objects, serialize it to JSON with the given serializer,
|
||||
then render it on /api/note/transaction/transaction/
|
||||
"""
|
||||
queryset = Transaction.objects.all()
|
||||
queryset = Transaction.objects.order_by("-created_at").all()
|
||||
serializer_class = TransactionPolymorphicSerializer
|
||||
filter_backends = [SearchFilter]
|
||||
search_fields = ['$reason', ]
|
||||
|
|
|
@ -6,11 +6,7 @@ def save_user_note(instance, raw, **_kwargs):
|
|||
"""
|
||||
Hook to create and save a note when an user is updated
|
||||
"""
|
||||
if raw:
|
||||
# When provisionning data, do not try to autocreate
|
||||
return
|
||||
|
||||
if instance.is_superuser or instance.profile.registration_valid:
|
||||
if not raw and (instance.is_superuser or instance.profile.registration_valid):
|
||||
# Create note only when the registration is validated
|
||||
from note.models import NoteUser
|
||||
NoteUser.objects.get_or_create(user=instance)
|
||||
|
|
|
@ -0,0 +1,365 @@
|
|||
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
from member.models import Club, Membership
|
||||
from note.models import NoteUser, Transaction, TemplateCategory, TransactionTemplate, RecurrentTransaction, \
|
||||
MembershipTransaction, SpecialTransaction, NoteSpecial, Alias
|
||||
from permission.models import Role
|
||||
|
||||
|
||||
class TestTransactions(TestCase):
|
||||
fixtures = ('initial', )
|
||||
|
||||
def setUp(self) -> None:
|
||||
self.user = User.objects.create_superuser(
|
||||
username="toto",
|
||||
password="totototo",
|
||||
email="toto@example.com",
|
||||
)
|
||||
|
||||
sess = self.client.session
|
||||
sess["permission_mask"] = 42
|
||||
sess.save()
|
||||
self.client.force_login(self.user)
|
||||
|
||||
membership = Membership.objects.create(club=Club.objects.get(name="BDE"), user=self.user)
|
||||
membership.roles.add(Role.objects.get(name="Respo info"))
|
||||
membership.save()
|
||||
Membership.objects.create(club=Club.objects.get(name="Kfet"), user=self.user)
|
||||
self.user.note.refresh_from_db()
|
||||
|
||||
self.second_user = User.objects.create(
|
||||
username="toto2",
|
||||
)
|
||||
# Non superusers have no note until the registration get validated
|
||||
NoteUser.objects.create(user=self.second_user)
|
||||
|
||||
self.club = Club.objects.create(
|
||||
name="clubtoto",
|
||||
)
|
||||
|
||||
self.transaction = Transaction.objects.create(
|
||||
source=self.second_user.note,
|
||||
destination=self.user.note,
|
||||
amount=4200,
|
||||
reason="Test transaction",
|
||||
)
|
||||
self.user.note.refresh_from_db()
|
||||
self.second_user.note.refresh_from_db()
|
||||
|
||||
self.category = TemplateCategory.objects.create(name="Test")
|
||||
self.template = TransactionTemplate.objects.create(
|
||||
name="Test",
|
||||
destination=self.club.note,
|
||||
category=self.category,
|
||||
amount=100,
|
||||
description="Test template",
|
||||
)
|
||||
|
||||
def test_admin_pages(self):
|
||||
"""
|
||||
Load some admin pages to check that they render successfully.
|
||||
"""
|
||||
response = self.client.get(reverse("admin:index") + "note/note/")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.get(reverse("admin:index") + "note/transaction/")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.get(reverse("admin:index") + "note/transaction/" + str(self.transaction.pk) + "/change/")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.get(reverse("admin:index") + "note/transaction/add/?ct_id="
|
||||
+ str(ContentType.objects.get_for_model(Transaction).id))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.get(reverse("admin:index") + "note/transaction/add/?ct_id="
|
||||
+ str(ContentType.objects.get_for_model(RecurrentTransaction).id))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.get(reverse("admin:index") + "note/transaction/add/?ct_id="
|
||||
+ str(ContentType.objects.get_for_model(MembershipTransaction).id))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.get(reverse("admin:index") + "note/transaction/add/?ct_id="
|
||||
+ str(ContentType.objects.get_for_model(SpecialTransaction).id))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.get(reverse("admin:index") + "note/transactiontemplate/")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.get(reverse("admin:index") + "note/templatecategory/")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_render_transfer_page(self):
|
||||
response = self.client.get(reverse("note:transfer"))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_transfer_api(self):
|
||||
old_user_balance = self.user.note.balance
|
||||
old_second_user_balance = self.second_user.note.balance
|
||||
quantity = 3
|
||||
amount = 314
|
||||
total = quantity * amount
|
||||
response = self.client.post("/api/note/transaction/transaction/", data=dict(
|
||||
quantity=quantity,
|
||||
amount=amount,
|
||||
reason="Transaction through API",
|
||||
valid=True,
|
||||
polymorphic_ctype=ContentType.objects.get_for_model(Transaction).id,
|
||||
resourcetype="Transaction",
|
||||
source=self.user.note.id,
|
||||
source_alias=self.user.username,
|
||||
destination=self.second_user.note.id,
|
||||
destination_alias=self.second_user.username,
|
||||
))
|
||||
self.assertEqual(response.status_code, 201) # 201 = Created
|
||||
self.assertTrue(Transaction.objects.filter(reason="Transaction through API").exists())
|
||||
|
||||
self.user.note.refresh_from_db()
|
||||
self.second_user.note.refresh_from_db()
|
||||
|
||||
self.assertTrue(self.user.note.balance == old_user_balance - total)
|
||||
self.assertTrue(self.second_user.note.balance == old_second_user_balance + total)
|
||||
|
||||
self.test_render_transfer_page()
|
||||
|
||||
def test_credit_api(self):
|
||||
old_user_balance = self.user.note.balance
|
||||
amount = 4242
|
||||
special_type = NoteSpecial.objects.first()
|
||||
response = self.client.post("/api/note/transaction/transaction/", data=dict(
|
||||
quantity=1,
|
||||
amount=amount,
|
||||
reason="Credit through API",
|
||||
valid=True,
|
||||
polymorphic_ctype=ContentType.objects.get_for_model(SpecialTransaction).id,
|
||||
resourcetype="SpecialTransaction",
|
||||
source=special_type.id,
|
||||
source_alias=str(special_type),
|
||||
destination=self.user.note.id,
|
||||
destination_alias=self.user.username,
|
||||
last_name="TOTO",
|
||||
first_name="Toto",
|
||||
))
|
||||
|
||||
self.assertEqual(response.status_code, 201) # 201 = Created
|
||||
self.assertTrue(Transaction.objects.filter(reason="Credit through API").exists())
|
||||
self.user.note.refresh_from_db()
|
||||
self.assertTrue(self.user.note.balance == old_user_balance + amount)
|
||||
|
||||
self.test_render_transfer_page()
|
||||
|
||||
def test_debit_api(self):
|
||||
old_user_balance = self.user.note.balance
|
||||
amount = 4242
|
||||
special_type = NoteSpecial.objects.first()
|
||||
response = self.client.post("/api/note/transaction/transaction/", data=dict(
|
||||
quantity=1,
|
||||
amount=amount,
|
||||
reason="Debit through API",
|
||||
valid=True,
|
||||
polymorphic_ctype=ContentType.objects.get_for_model(SpecialTransaction).id,
|
||||
resourcetype="SpecialTransaction",
|
||||
source=self.user.note.id,
|
||||
source_alias=self.user.username,
|
||||
destination=special_type.id,
|
||||
destination_alias=str(special_type),
|
||||
last_name="TOTO",
|
||||
first_name="Toto",
|
||||
))
|
||||
self.assertEqual(response.status_code, 201) # 201 = Created
|
||||
self.assertTrue(Transaction.objects.filter(reason="Debit through API").exists())
|
||||
self.user.note.refresh_from_db()
|
||||
self.assertTrue(self.user.note.balance == old_user_balance - amount)
|
||||
|
||||
self.test_render_transfer_page()
|
||||
|
||||
def test_render_consos_page(self):
|
||||
response = self.client.get(reverse("note:consos"))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_consumption_api(self):
|
||||
old_user_balance = self.user.note.balance
|
||||
old_club_balance = self.club.note.balance
|
||||
quantity = 2
|
||||
template = self.template
|
||||
total = quantity * template.amount
|
||||
response = self.client.post("/api/note/transaction/transaction/", data=dict(
|
||||
quantity=quantity,
|
||||
amount=template.amount,
|
||||
reason="Consumption through API (" + template.name + ")",
|
||||
valid=True,
|
||||
polymorphic_ctype=ContentType.objects.get_for_model(RecurrentTransaction).id,
|
||||
resourcetype="RecurrentTransaction",
|
||||
source=self.user.note.id,
|
||||
source_alias=self.user.username,
|
||||
destination=self.club.note.id,
|
||||
destination_alias=self.second_user.username,
|
||||
template=template.id,
|
||||
))
|
||||
self.assertEqual(response.status_code, 201) # 201 = Created
|
||||
self.assertTrue(Transaction.objects.filter(destination=self.club.note).exists())
|
||||
|
||||
self.user.note.refresh_from_db()
|
||||
self.club.note.refresh_from_db()
|
||||
|
||||
self.assertTrue(self.user.note.balance == old_user_balance - total)
|
||||
self.assertTrue(self.club.note.balance == old_club_balance + total)
|
||||
|
||||
self.test_render_consos_page()
|
||||
|
||||
def test_invalidate_transaction(self):
|
||||
old_second_user_balance = self.second_user.note.balance
|
||||
old_user_balance = self.user.note.balance
|
||||
total = self.transaction.total
|
||||
response = self.client.patch("/api/note/transaction/transaction/" + str(self.transaction.pk) + "/", data=dict(
|
||||
valid=False,
|
||||
resourcetype="Transaction",
|
||||
invalidity_reason="Test invalidate",
|
||||
), content_type="application/json")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTrue(Transaction.objects.filter(valid=False, invalidity_reason="Test invalidate").exists())
|
||||
|
||||
self.second_user.note.refresh_from_db()
|
||||
self.user.note.refresh_from_db()
|
||||
|
||||
self.assertTrue(self.second_user.note.balance == old_second_user_balance + total)
|
||||
self.assertTrue(self.user.note.balance == old_user_balance - total)
|
||||
|
||||
self.test_render_transfer_page()
|
||||
self.test_render_consos_page()
|
||||
|
||||
# Now we check if we can revalidate
|
||||
old_second_user_balance = self.second_user.note.balance
|
||||
old_user_balance = self.user.note.balance
|
||||
total = self.transaction.total
|
||||
response = self.client.patch("/api/note/transaction/transaction/" + str(self.transaction.pk) + "/", data=dict(
|
||||
valid=True,
|
||||
resourcetype="Transaction",
|
||||
), content_type="application/json")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTrue(Transaction.objects.filter(valid=True, pk=self.transaction.pk).exists())
|
||||
|
||||
self.second_user.note.refresh_from_db()
|
||||
self.user.note.refresh_from_db()
|
||||
|
||||
self.assertTrue(self.second_user.note.balance == old_second_user_balance - total)
|
||||
self.assertTrue(self.user.note.balance == old_user_balance + total)
|
||||
|
||||
self.test_render_transfer_page()
|
||||
self.test_render_consos_page()
|
||||
|
||||
def test_render_template_list(self):
|
||||
response = self.client.get(reverse("note:template_list") + "?search=test")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_render_template_create(self):
|
||||
response = self.client.get(reverse("note:template_create"))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.post(reverse("note:template_create"), data=dict(
|
||||
name="Test create button",
|
||||
destination=self.club.note.pk,
|
||||
category=self.category.pk,
|
||||
amount=4200,
|
||||
description="We have created a button",
|
||||
highlighted=True,
|
||||
display=True,
|
||||
))
|
||||
self.assertRedirects(response, reverse("note:template_list"), 302, 200)
|
||||
self.assertTrue(TransactionTemplate.objects.filter(name="Test create button").exists())
|
||||
|
||||
def test_render_template_update(self):
|
||||
response = self.client.get(self.template.get_absolute_url())
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.post(self.template.get_absolute_url(), data=dict(
|
||||
name="Test update button",
|
||||
destination=self.club.note.pk,
|
||||
category=self.category.pk,
|
||||
amount=4200,
|
||||
description="We have updated a button",
|
||||
highlighted=True,
|
||||
display=True,
|
||||
))
|
||||
self.assertRedirects(response, reverse("note:template_list"), 302, 200)
|
||||
self.assertTrue(TransactionTemplate.objects.filter(name="Test update button", pk=self.template.pk).exists())
|
||||
|
||||
# Check that the price history renders properly
|
||||
response = self.client.post(self.template.get_absolute_url(), data=dict(
|
||||
name="Test price history",
|
||||
destination=self.club.note.pk,
|
||||
category=self.category.pk,
|
||||
amount=4200,
|
||||
description="We have updated a button",
|
||||
highlighted=True,
|
||||
display=True,
|
||||
))
|
||||
self.assertRedirects(response, reverse("note:template_list"), 302, 200)
|
||||
self.assertTrue(TransactionTemplate.objects.filter(name="Test price history", pk=self.template.pk).exists())
|
||||
response = self.client.get(reverse("note:template_update", args=(self.template.pk,)))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_render_search_transactions(self):
|
||||
response = self.client.get(reverse("note:transactions", args=(self.user.note.pk,)), data=dict(
|
||||
source=self.second_user.note.alias_set.first().id,
|
||||
destination=self.user.note.alias_set.first().id,
|
||||
type=[ContentType.objects.get_for_model(Transaction).id],
|
||||
reason="test",
|
||||
valid=True,
|
||||
amount_gte=0,
|
||||
amount_lte=42424242,
|
||||
created_after="2000-01-01 00:00",
|
||||
created_before="2042-12-31 21:42",
|
||||
))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_delete_transaction(self):
|
||||
# Transactions can't be deleted with a normal usage, but it is possible through the admin interface.
|
||||
old_second_user_balance = self.second_user.note.balance
|
||||
old_user_balance = self.user.note.balance
|
||||
total = self.transaction.total
|
||||
|
||||
self.transaction.delete()
|
||||
self.second_user.note.refresh_from_db()
|
||||
self.user.note.refresh_from_db()
|
||||
|
||||
self.assertTrue(self.second_user.note.balance == old_second_user_balance + total)
|
||||
self.assertTrue(self.user.note.balance == old_user_balance - total)
|
||||
|
||||
def test_calculate_last_negative_duration(self):
|
||||
self.assertIsNone(self.user.note.last_negative_duration)
|
||||
self.assertIsNotNone(self.second_user.note.last_negative_duration)
|
||||
self.assertIsNone(self.club.note.last_negative_duration)
|
||||
|
||||
Transaction.objects.create(
|
||||
source=self.club.note,
|
||||
destination=self.user.note,
|
||||
amount=2 * self.club.note.balance + 100,
|
||||
reason="Club balance is negative",
|
||||
)
|
||||
|
||||
self.club.note.refresh_from_db()
|
||||
self.assertIsNotNone(self.club.note.last_negative_duration)
|
||||
|
||||
def test_api_search(self):
|
||||
response = self.client.get("/api/note/note/")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.get("/api/note/alias/?alias=.*")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.get("/api/note/consumer/")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.get("/api/note/transaction/transaction/")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.get("/api/note/transaction/template/")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_api_alias(self):
|
||||
response = self.client.post("/api/note/alias/", data=dict(
|
||||
name="testalias",
|
||||
note=self.user.note.id,
|
||||
))
|
||||
self.assertEqual(response.status_code, 201)
|
||||
self.assertTrue(Alias.objects.filter(name="testalias").exists())
|
||||
alias = Alias.objects.get(name="testalias")
|
||||
response = self.client.patch("/api/note/alias/" + str(alias.pk) + "/", dict(name="test_updated_alias"),
|
||||
content_type="application/json")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTrue(Alias.objects.filter(name="test_updated_alias").exists())
|
||||
response = self.client.delete("/api/note/alias/" + str(alias.pk) + "/")
|
||||
self.assertEqual(response.status_code, 204)
|
|
@ -206,10 +206,7 @@ class TransactionSearchView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView
|
|||
context["form"] = form
|
||||
|
||||
form.full_clean()
|
||||
if form.is_valid():
|
||||
data = form.cleaned_data
|
||||
else:
|
||||
data = {}
|
||||
data = form.cleaned_data if form.is_valid() else {}
|
||||
|
||||
transactions = Transaction.objects.annotate(total_amount=F("quantity") * F("amount")).filter(
|
||||
PermissionBackend.filter_queryset(self.request.user, Transaction, "view"))\
|
||||
|
|
|
@ -149,3 +149,9 @@ class TestPermissionDenied(TestCase):
|
|||
def test_list_soge_credits(self):
|
||||
response = self.client.get(reverse("treasury:soge_credits"))
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
|
||||
class TestLoginRedirect(TestCase):
|
||||
def test_consos_page(self):
|
||||
response = self.client.get(reverse("note:consos"))
|
||||
self.assertRedirects(response, reverse("login") + "?next=" + reverse("note:consos"), 302, 200)
|
||||
|
|
Loading…
Reference in New Issue