You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
343 lines
14 KiB
Python
343 lines
14 KiB
Python
from django.test import TestCase, override_settings
|
|
from django.contrib.admin.sites import AdminSite
|
|
from django.test import RequestFactory, Client
|
|
from django.contrib.auth.models import User, Permission
|
|
from django.utils import timezone
|
|
from django.contrib.sessions.middleware import SessionMiddleware
|
|
from django.contrib.messages.middleware import MessageMiddleware
|
|
from django.contrib.messages.storage.fallback import FallbackStorage
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
from members.models import Member, MALE
|
|
from ..models import Ledger, Statement, StatementConfirmed, Transaction, Bill
|
|
from ..admin import (
|
|
LedgerAdmin, StatementUnSubmittedAdmin, StatementSubmittedAdmin,
|
|
StatementConfirmedAdmin, TransactionAdmin, BillAdmin
|
|
)
|
|
|
|
|
|
class StatementUnSubmittedAdminTestCase(TestCase):
|
|
"""Test cases for StatementUnSubmittedAdmin"""
|
|
|
|
def setUp(self):
|
|
self.site = AdminSite()
|
|
self.factory = RequestFactory()
|
|
self.admin = StatementUnSubmittedAdmin(Statement, self.site)
|
|
|
|
self.user = User.objects.create_user('testuser', 'test@example.com', 'pass')
|
|
self.member = Member.objects.create(
|
|
prename="Test", lastname="User", birth_date=timezone.now().date(),
|
|
email="test@example.com", gender=MALE, user=self.user
|
|
)
|
|
|
|
self.statement = Statement.objects.create(
|
|
short_description='Test Statement',
|
|
explanation='Test explanation',
|
|
night_cost=25
|
|
)
|
|
|
|
def _add_session_to_request(self, request):
|
|
"""Add session to request"""
|
|
middleware = SessionMiddleware(lambda req: None)
|
|
middleware.process_request(request)
|
|
request.session.save()
|
|
|
|
middleware = MessageMiddleware(lambda req: None)
|
|
middleware.process_request(request)
|
|
request._messages = FallbackStorage(request)
|
|
|
|
def test_save_model_with_member(self):
|
|
"""Test save_model sets created_by for new objects"""
|
|
request = self.factory.post('/')
|
|
request.user = self.user
|
|
|
|
# Test with change=False (new object)
|
|
new_statement = Statement(short_description='New Statement')
|
|
self.admin.save_model(request, new_statement, None, change=False)
|
|
self.assertEqual(new_statement.created_by, self.member)
|
|
|
|
def test_get_readonly_fields_submitted(self):
|
|
"""Test readonly fields when statement is submitted"""
|
|
# Mark statement as submitted
|
|
self.statement.submitted = True
|
|
readonly_fields = self.admin.get_readonly_fields(None, self.statement)
|
|
self.assertIn('submitted', readonly_fields)
|
|
self.assertIn('excursion', readonly_fields)
|
|
self.assertIn('short_description', readonly_fields)
|
|
|
|
def test_get_readonly_fields_not_submitted(self):
|
|
"""Test readonly fields when statement is not submitted"""
|
|
readonly_fields = self.admin.get_readonly_fields(None, self.statement)
|
|
self.assertEqual(readonly_fields, ['submitted', 'excursion'])
|
|
|
|
|
|
class StatementSubmittedAdminTestCase(TestCase):
|
|
"""Test cases for StatementSubmittedAdmin"""
|
|
|
|
def setUp(self):
|
|
self.site = AdminSite()
|
|
self.factory = RequestFactory()
|
|
self.admin = StatementSubmittedAdmin(Statement, self.site)
|
|
|
|
self.user = User.objects.create_user('testuser', 'test@example.com', 'pass')
|
|
self.member = Member.objects.create(
|
|
prename="Test", lastname="User", birth_date=timezone.now().date(),
|
|
email="test@example.com", gender=MALE, user=self.user
|
|
)
|
|
|
|
self.finance_user = User.objects.create_user('finance', 'finance@example.com', 'pass')
|
|
finance_perm = Permission.objects.get(codename='process_statementsubmitted')
|
|
self.finance_user.user_permissions.add(finance_perm)
|
|
|
|
self.statement = Statement.objects.create(
|
|
short_description='Submitted Statement',
|
|
explanation='Test explanation',
|
|
submitted=True,
|
|
submitted_by=self.member,
|
|
submitted_date=timezone.now(),
|
|
night_cost=25
|
|
)
|
|
|
|
def _add_session_to_request(self, request):
|
|
"""Add session to request"""
|
|
middleware = SessionMiddleware(lambda req: None)
|
|
middleware.process_request(request)
|
|
request.session.save()
|
|
|
|
middleware = MessageMiddleware(lambda req: None)
|
|
middleware.process_request(request)
|
|
request._messages = FallbackStorage(request)
|
|
|
|
def test_has_add_permission(self):
|
|
"""Test that add permission is disabled"""
|
|
request = self.factory.get('/')
|
|
request.user = self.finance_user
|
|
self.assertFalse(self.admin.has_add_permission(request))
|
|
|
|
def test_has_change_permission_with_permission(self):
|
|
"""Test change permission with proper permission"""
|
|
request = self.factory.get('/')
|
|
request.user = self.finance_user
|
|
self.assertTrue(self.admin.has_change_permission(request))
|
|
|
|
def test_has_change_permission_without_permission(self):
|
|
"""Test change permission without proper permission"""
|
|
request = self.factory.get('/')
|
|
request.user = self.user
|
|
self.assertFalse(self.admin.has_change_permission(request))
|
|
|
|
def test_has_delete_permission(self):
|
|
"""Test that delete permission is disabled"""
|
|
request = self.factory.get('/')
|
|
request.user = self.finance_user
|
|
self.assertFalse(self.admin.has_delete_permission(request))
|
|
|
|
def test_reduce_transactions_view(self):
|
|
"""Test reduce_transactions_view logic"""
|
|
# Test GET parameters
|
|
request = self.factory.get('/', {'redirectTo': '/admin/'})
|
|
self.assertIn('redirectTo', request.GET)
|
|
self.assertEqual(request.GET['redirectTo'], '/admin/')
|
|
|
|
|
|
class StatementConfirmedAdminTestCase(TestCase):
|
|
"""Test cases for StatementConfirmedAdmin"""
|
|
|
|
def setUp(self):
|
|
self.site = AdminSite()
|
|
self.factory = RequestFactory()
|
|
self.admin = StatementConfirmedAdmin(StatementConfirmed, self.site)
|
|
|
|
# Register the admin with the site to enable URL resolution
|
|
self.site.register(StatementConfirmed, StatementConfirmedAdmin)
|
|
|
|
self.user = User.objects.create_user('testuser', 'test@example.com', 'pass')
|
|
self.member = Member.objects.create(
|
|
prename="Test", lastname="User", birth_date=timezone.now().date(),
|
|
email="test@example.com", gender=MALE, user=self.user
|
|
)
|
|
|
|
self.finance_user = User.objects.create_user('finance', 'finance@example.com', 'pass')
|
|
unconfirm_perm = Permission.objects.get(codename='may_manage_confirmed_statements')
|
|
self.finance_user.user_permissions.add(unconfirm_perm)
|
|
|
|
# Create a base statement first
|
|
base_statement = Statement.objects.create(
|
|
short_description='Confirmed Statement',
|
|
explanation='Test explanation',
|
|
submitted=True,
|
|
confirmed=True,
|
|
confirmed_by=self.member,
|
|
confirmed_date=timezone.now(),
|
|
night_cost=25
|
|
)
|
|
|
|
# StatementConfirmed is a proxy model, so we can get it from the base statement
|
|
self.statement = StatementConfirmed.objects.get(pk=base_statement.pk)
|
|
|
|
def _add_session_to_request(self, request):
|
|
"""Add session to request"""
|
|
middleware = SessionMiddleware(lambda req: None)
|
|
middleware.process_request(request)
|
|
request.session.save()
|
|
|
|
middleware = MessageMiddleware(lambda req: None)
|
|
middleware.process_request(request)
|
|
request._messages = FallbackStorage(request)
|
|
|
|
def test_has_add_permission(self):
|
|
"""Test that add permission is disabled"""
|
|
request = self.factory.get('/')
|
|
request.user = self.finance_user
|
|
self.assertFalse(self.admin.has_add_permission(request))
|
|
|
|
def test_has_change_permission(self):
|
|
"""Test that change permission is disabled"""
|
|
request = self.factory.get('/')
|
|
request.user = self.finance_user
|
|
self.assertFalse(self.admin.has_change_permission(request))
|
|
|
|
def test_has_delete_permission(self):
|
|
"""Test that delete permission is disabled"""
|
|
request = self.factory.get('/')
|
|
request.user = self.finance_user
|
|
self.assertFalse(self.admin.has_delete_permission(request))
|
|
|
|
def test_unconfirm_view_not_confirmed_statement(self):
|
|
"""Test unconfirm_view with statement that is not confirmed"""
|
|
# Add special permission for unconfirm
|
|
unconfirm_perm = Permission.objects.get(codename='may_manage_confirmed_statements')
|
|
self.finance_user.user_permissions.add(unconfirm_perm)
|
|
|
|
# Create request for unconfirmed statement
|
|
request = self.factory.get('/')
|
|
request.user = self.finance_user
|
|
self._add_session_to_request(request)
|
|
|
|
# Create an unconfirmed statement for this test
|
|
unconfirmed_base = Statement.objects.create(
|
|
short_description='Unconfirmed Statement',
|
|
explanation='Test explanation',
|
|
night_cost=25
|
|
)
|
|
# This won't be accessible via StatementConfirmed since it's not confirmed
|
|
unconfirmed_statement = unconfirmed_base
|
|
|
|
# Test with unconfirmed statement (should trigger error path)
|
|
self.assertFalse(unconfirmed_statement.confirmed)
|
|
|
|
# Call unconfirm_view - this should go through error path
|
|
response = self.admin.unconfirm_view(request, unconfirmed_statement.pk)
|
|
|
|
# Should redirect due to not confirmed error
|
|
self.assertEqual(response.status_code, 302)
|
|
|
|
def test_unconfirm_view_post_unconfirm_action(self):
|
|
"""Test unconfirm_view POST request with 'unconfirm' action"""
|
|
# Add special permission for unconfirm
|
|
unconfirm_perm = Permission.objects.get(codename='may_manage_confirmed_statements')
|
|
self.finance_user.user_permissions.add(unconfirm_perm)
|
|
|
|
# Create POST request with unconfirm action
|
|
request = self.factory.post('/', {'unconfirm': 'true'})
|
|
request.user = self.finance_user
|
|
self._add_session_to_request(request)
|
|
|
|
# Ensure statement is confirmed
|
|
self.assertTrue(self.statement.confirmed)
|
|
self.assertIsNotNone(self.statement.confirmed_by)
|
|
self.assertIsNotNone(self.statement.confirmed_date)
|
|
|
|
# Call unconfirm_view - this should execute the unconfirm action
|
|
response = self.admin.unconfirm_view(request, self.statement.pk)
|
|
|
|
# Should redirect after successful unconfirm
|
|
self.assertEqual(response.status_code, 302)
|
|
|
|
# Verify statement was unconfirmed (need to reload from DB)
|
|
self.statement.refresh_from_db()
|
|
self.assertFalse(self.statement.confirmed)
|
|
self.assertIsNone(self.statement.confirmed_date)
|
|
|
|
def test_unconfirm_view_get_render_template(self):
|
|
"""Test unconfirm_view GET request rendering template"""
|
|
# Add special permission for unconfirm
|
|
unconfirm_perm = Permission.objects.get(codename='may_manage_confirmed_statements')
|
|
self.finance_user.user_permissions.add(unconfirm_perm)
|
|
|
|
# Create GET request (no POST data)
|
|
request = self.factory.get('/')
|
|
request.user = self.finance_user
|
|
self._add_session_to_request(request)
|
|
|
|
# Ensure statement is confirmed
|
|
self.assertTrue(self.statement.confirmed)
|
|
|
|
# Call unconfirm_view
|
|
response = self.admin.unconfirm_view(request, self.statement.pk)
|
|
|
|
# Should render template (status 200)
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
# Check response content contains expected template elements
|
|
self.assertIn(str(_('Unconfirm statement')).encode('utf-8'), response.content)
|
|
self.assertIn(self.statement.short_description.encode(), response.content)
|
|
|
|
|
|
class TransactionAdminTestCase(TestCase):
|
|
"""Test cases for TransactionAdmin"""
|
|
|
|
def setUp(self):
|
|
self.site = AdminSite()
|
|
self.factory = RequestFactory()
|
|
self.admin = TransactionAdmin(Transaction, self.site)
|
|
|
|
self.user = User.objects.create_user('testuser', 'test@example.com', 'pass')
|
|
self.member = Member.objects.create(
|
|
prename="Test", lastname="User", birth_date=timezone.now().date(),
|
|
email="test@example.com", gender=MALE, user=self.user
|
|
)
|
|
|
|
self.ledger = Ledger.objects.create(name='Test Ledger')
|
|
self.statement = Statement.objects.create(
|
|
short_description='Test Statement',
|
|
explanation='Test explanation'
|
|
)
|
|
|
|
self.transaction = Transaction.objects.create(
|
|
member=self.member,
|
|
ledger=self.ledger,
|
|
amount=100,
|
|
reference='Test transaction',
|
|
statement=self.statement
|
|
)
|
|
|
|
def test_has_add_permission(self):
|
|
"""Test that add permission is disabled"""
|
|
request = self.factory.get('/')
|
|
request.user = self.user
|
|
self.assertFalse(self.admin.has_add_permission(request))
|
|
|
|
def test_has_change_permission(self):
|
|
"""Test that change permission is disabled"""
|
|
request = self.factory.get('/')
|
|
request.user = self.user
|
|
self.assertFalse(self.admin.has_change_permission(request))
|
|
|
|
def test_has_delete_permission(self):
|
|
"""Test that delete permission is disabled"""
|
|
request = self.factory.get('/')
|
|
request.user = self.user
|
|
self.assertFalse(self.admin.has_delete_permission(request))
|
|
|
|
def test_get_readonly_fields_confirmed(self):
|
|
"""Test readonly fields when transaction is confirmed"""
|
|
self.transaction.confirmed = True
|
|
readonly_fields = self.admin.get_readonly_fields(None, self.transaction)
|
|
self.assertEqual(readonly_fields, self.admin.fields)
|
|
|
|
def test_get_readonly_fields_not_confirmed(self):
|
|
"""Test readonly fields when transaction is not confirmed"""
|
|
readonly_fields = self.admin.get_readonly_fields(None, self.transaction)
|
|
self.assertEqual(readonly_fields, ())
|