Files
k-boris-website/backlogger/tests.py
Boris 8f0667d160
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
add tests
2026-03-31 21:52:26 +03:00

284 lines
10 KiB
Python

from django.contrib.auth.models import User
from django.test import TestCase
from django.urls import reverse
from .forms import ItemForm, SignupForm
from .models import Item
def make_user(username='alice', active=True):
user = User.objects.create_user(username=username, password='testpass123', email=f'{username}@example.com')
user.is_active = active
user.save()
return user
def make_item(user, name='Test Game', category=Item.GAMES, **kwargs):
return Item.objects.create(user=user, name=name, category=category, **kwargs)
# ---------------------------------------------------------------------------
# Auth
# ---------------------------------------------------------------------------
class AuthRequiredTests(TestCase):
def test_list_redirects_anonymous(self):
response = self.client.get(reverse('backlogger:list'))
self.assertRedirects(response, '/accounts/login/?next=/backlogger/')
def test_add_redirects_anonymous(self):
response = self.client.get(reverse('backlogger:add'))
self.assertEqual(response.status_code, 302)
def test_inactive_user_cannot_login(self):
make_user('bob', active=False)
response = self.client.post(reverse('login'), {'username': 'bob', 'password': 'testpass123'})
# Should stay on login page, not redirect to backlogger
self.assertEqual(response.status_code, 200)
self.assertFalse(response.wsgi_request.user.is_authenticated)
def test_active_user_can_login(self):
make_user('alice')
response = self.client.post(reverse('login'), {'username': 'alice', 'password': 'testpass123'}, follow=True)
self.assertTrue(response.wsgi_request.user.is_authenticated)
# ---------------------------------------------------------------------------
# Signup
# ---------------------------------------------------------------------------
class SignupTests(TestCase):
def test_get_signup_page(self):
response = self.client.get(reverse('signup'))
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Request account')
def test_signup_creates_inactive_user(self):
response = self.client.post(reverse('signup'), {
'username': 'newuser',
'email': 'new@example.com',
'password1': 'StrongPass99!',
'password2': 'StrongPass99!',
})
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'pending')
user = User.objects.get(username='newuser')
self.assertFalse(user.is_active)
def test_signup_invalid_mismatched_passwords(self):
self.client.post(reverse('signup'), {
'username': 'newuser',
'email': 'new@example.com',
'password1': 'StrongPass99!',
'password2': 'WrongPass99!',
})
self.assertFalse(User.objects.filter(username='newuser').exists())
def test_signup_duplicate_username(self):
make_user('taken')
response = self.client.post(reverse('signup'), {
'username': 'taken',
'email': 'other@example.com',
'password1': 'StrongPass99!',
'password2': 'StrongPass99!',
})
self.assertEqual(response.status_code, 200)
self.assertEqual(User.objects.filter(username='taken').count(), 1)
# ---------------------------------------------------------------------------
# Item list
# ---------------------------------------------------------------------------
class ItemListTests(TestCase):
def setUp(self):
self.alice = make_user('alice')
self.bob = make_user('bob')
self.client.force_login(self.alice)
def test_list_shows_own_items(self):
make_item(self.alice, name='Alice Game')
make_item(self.bob, name='Bob Game')
response = self.client.get(reverse('backlogger:list'))
self.assertContains(response, 'Alice Game')
self.assertNotContains(response, 'Bob Game')
def test_list_category_filter(self):
make_item(self.alice, name='My Game', category=Item.GAMES)
make_item(self.alice, name='My Book', category=Item.BOOKS)
response = self.client.get(reverse('backlogger:list') + '?category=games')
self.assertContains(response, 'My Game')
self.assertNotContains(response, 'My Book')
def test_list_empty_state(self):
response = self.client.get(reverse('backlogger:list'))
self.assertContains(response, 'Add your first one')
def test_list_sort_az(self):
make_item(self.alice, name='Zelda')
make_item(self.alice, name='Ape')
response = self.client.get(reverse('backlogger:list') + '?sort=az')
names = [item.name for item in response.context['items']]
self.assertEqual(names, sorted(names))
def test_list_sort_favorites_first(self):
make_item(self.alice, name='Normal')
make_item(self.alice, name='Fav', favorite=True)
response = self.client.get(reverse('backlogger:list') + '?sort=fav')
names = [item.name for item in response.context['items']]
self.assertEqual(names[0], 'Fav')
# ---------------------------------------------------------------------------
# Item add
# ---------------------------------------------------------------------------
class ItemAddTests(TestCase):
def setUp(self):
self.user = make_user('alice')
self.client.force_login(self.user)
def test_add_game(self):
self.client.post(reverse('backlogger:add'), {
'category': 'games',
'name': 'Elden Ring',
'progress_percent': 50,
'favorite': False,
'hours_played': 20,
'total_hours': 80,
})
item = Item.objects.get(name='Elden Ring')
self.assertEqual(item.user, self.user)
self.assertEqual(item.category, Item.GAMES)
self.assertEqual(item.hours_played, 20)
def test_add_assigns_current_user(self):
self.client.post(reverse('backlogger:add'), {
'category': 'books',
'name': 'Dune',
'progress_percent': 0,
'favorite': False,
})
item = Item.objects.get(name='Dune')
self.assertEqual(item.user, self.user)
def test_add_invalid_shows_form(self):
response = self.client.post(reverse('backlogger:add'), {'name': ''})
self.assertEqual(response.status_code, 200)
self.assertFalse(Item.objects.exists())
# ---------------------------------------------------------------------------
# Item edit
# ---------------------------------------------------------------------------
class ItemEditTests(TestCase):
def setUp(self):
self.alice = make_user('alice')
self.bob = make_user('bob')
self.client.force_login(self.alice)
def test_edit_own_item(self):
item = make_item(self.alice, name='Original')
self.client.post(reverse('backlogger:edit', args=[item.pk]), {
'category': 'games',
'name': 'Updated',
'progress_percent': 75,
'favorite': False,
})
item.refresh_from_db()
self.assertEqual(item.name, 'Updated')
def test_edit_other_user_item_returns_404(self):
item = make_item(self.bob, name='Bobs Item')
response = self.client.get(reverse('backlogger:edit', args=[item.pk]))
self.assertEqual(response.status_code, 404)
# ---------------------------------------------------------------------------
# Item delete
# ---------------------------------------------------------------------------
class ItemDeleteTests(TestCase):
def setUp(self):
self.alice = make_user('alice')
self.bob = make_user('bob')
self.client.force_login(self.alice)
def test_delete_own_item(self):
item = make_item(self.alice, name='To Delete')
self.client.post(reverse('backlogger:delete', args=[item.pk]))
self.assertFalse(Item.objects.filter(pk=item.pk).exists())
def test_delete_other_user_item_returns_404(self):
item = make_item(self.bob, name='Bobs Item')
response = self.client.post(reverse('backlogger:delete', args=[item.pk]))
self.assertEqual(response.status_code, 404)
self.assertTrue(Item.objects.filter(pk=item.pk).exists())
# ---------------------------------------------------------------------------
# Forms
# ---------------------------------------------------------------------------
class ItemFormTests(TestCase):
def _post(self, **kwargs):
data = {'category': 'games', 'name': 'Test', 'progress_percent': 0, 'favorite': False}
data.update(kwargs)
form = ItemForm(data)
form.is_valid()
return form
def test_game_fields_kept_for_games(self):
form = self._post(category='games', hours_played=10, total_hours=40)
self.assertEqual(form.cleaned_data['hours_played'], 10)
def test_game_fields_nulled_for_books(self):
form = self._post(category='books', hours_played=10)
self.assertIsNone(form.cleaned_data['hours_played'])
def test_book_fields_kept_for_books(self):
form = self._post(category='books', pages_read=100, total_pages=300)
self.assertEqual(form.cleaned_data['pages_read'], 100)
def test_book_fields_nulled_for_games(self):
form = self._post(category='games', pages_read=100)
self.assertIsNone(form.cleaned_data['pages_read'])
def test_film_fields_nulled_for_games(self):
form = self._post(category='games', duration_minutes=120)
self.assertIsNone(form.cleaned_data['duration_minutes'])
def test_progress_over_100_invalid(self):
form = self._post(progress_percent=150)
self.assertIn('progress_percent', form.errors)
def test_progress_negative_invalid(self):
form = self._post(progress_percent=-1)
self.assertIn('progress_percent', form.errors)
class SignupFormTests(TestCase):
def _data(self, **overrides):
data = {
'username': 'newuser',
'email': 'new@example.com',
'password1': 'StrongPass99!',
'password2': 'StrongPass99!',
}
data.update(overrides)
return data
def test_valid_form(self):
form = SignupForm(self._data())
self.assertTrue(form.is_valid())
def test_email_required(self):
form = SignupForm(self._data(email=''))
self.assertFalse(form.is_valid())
self.assertIn('email', form.errors)
def test_password_mismatch(self):
form = SignupForm(self._data(password2='different'))
self.assertFalse(form.is_valid())