Add tests for accounts, and fix allowing user to delete friend code with active trade offers and in-game-name not being set on signup
This commit is contained in:
parent
65ca344582
commit
23d334c596
6 changed files with 658 additions and 10 deletions
|
|
@ -74,12 +74,13 @@ class CustomUserCreationForm(SignupForm):
|
|||
def save(self, request):
|
||||
# First, complete the normal signup process.
|
||||
user = super(CustomUserCreationForm, self).save(request)
|
||||
# Create the associated FriendCode record.
|
||||
friend_code_pk = FriendCode.objects.create(
|
||||
# Create the associated FriendCode record, now including in_game_name.
|
||||
friend_code_instance = FriendCode.objects.create(
|
||||
friend_code=self.cleaned_data["friend_code"],
|
||||
in_game_name=self.cleaned_data["in_game_name"],
|
||||
user=user
|
||||
)
|
||||
user.default_friend_code = friend_code_pk
|
||||
user.default_friend_code = friend_code_instance
|
||||
user.save()
|
||||
return user
|
||||
|
||||
|
|
|
|||
|
|
@ -23,11 +23,14 @@ class CustomUser(AbstractUser):
|
|||
def remove_default_friend_code(self, friend_code):
|
||||
"""
|
||||
If the given friend code is the current default,
|
||||
assign another of the user's friend codes (if any) as default.
|
||||
assign another of the user's friend codes as default.
|
||||
Raises ValidationError if it's the only friend code.
|
||||
"""
|
||||
if self.default_friend_code == friend_code:
|
||||
other_codes = self.friend_codes.exclude(pk=friend_code.pk)
|
||||
self.default_friend_code = other_codes.first() if other_codes.exists() else None
|
||||
if not other_codes.exists():
|
||||
raise ValidationError("A user must always have a default friend code.")
|
||||
self.default_friend_code = other_codes.first()
|
||||
self.save(update_fields=["default_friend_code"])
|
||||
|
||||
class FriendCode(models.Model):
|
||||
|
|
|
|||
|
|
@ -1,3 +1,637 @@
|
|||
from django.test import TestCase
|
||||
import hashlib
|
||||
from unittest.mock import patch, MagicMock
|
||||
import requests
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.test import TestCase, RequestFactory
|
||||
from django.urls import reverse
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.contrib.sessions.middleware import SessionMiddleware
|
||||
|
||||
from accounts.models import FriendCode
|
||||
from accounts.forms import FriendCodeForm, CustomUserCreationForm, UserSettingsForm
|
||||
from accounts.templatetags import gravatar
|
||||
from trades.models import TradeOffer
|
||||
|
||||
# Create your tests here.
|
||||
|
||||
# -----------------------------
|
||||
# Model Tests
|
||||
# -----------------------------
|
||||
class CustomUserModelTests(TestCase):
|
||||
def setUp(self):
|
||||
self.user = get_user_model().objects.create_user(
|
||||
username="testuser",
|
||||
email="test@example.com",
|
||||
password="password123"
|
||||
)
|
||||
def test_set_default_friend_code(self):
|
||||
"""User can manually set a friend code as their default."""
|
||||
fc1 = FriendCode.objects.create(
|
||||
friend_code="1234-5678-9012-3456",
|
||||
user=self.user,
|
||||
in_game_name="GameOne"
|
||||
)
|
||||
fc2 = FriendCode.objects.create(
|
||||
friend_code="2345-6789-0123-4567",
|
||||
user=self.user,
|
||||
in_game_name="GameTwo"
|
||||
)
|
||||
# Manually set fc2 as default.
|
||||
self.user.set_default_friend_code(fc2)
|
||||
self.user.refresh_from_db()
|
||||
self.assertEqual(self.user.default_friend_code, fc2)
|
||||
|
||||
def test_set_default_friend_code_invalid(self):
|
||||
"""
|
||||
Attempting to set a friend code that does not belong to the user should raise an exception.
|
||||
"""
|
||||
other_user = get_user_model().objects.create_user(
|
||||
username="otheruser",
|
||||
email="other@example.com",
|
||||
password="password456"
|
||||
)
|
||||
fc_other = FriendCode.objects.create(
|
||||
friend_code="3456-7890-1234-5678",
|
||||
user=other_user,
|
||||
in_game_name="OtherGame"
|
||||
)
|
||||
with self.assertRaises(ValidationError):
|
||||
self.user.set_default_friend_code(fc_other)
|
||||
|
||||
def test_remove_default_friend_code_with_multiple_codes(self):
|
||||
"""
|
||||
When removing the default friend code and other friend codes exist,
|
||||
the default should be reassigned to another friend code.
|
||||
"""
|
||||
fc1 = FriendCode.objects.create(
|
||||
friend_code="1234-5678-9012-3456",
|
||||
user=self.user,
|
||||
in_game_name="GameOne"
|
||||
)
|
||||
fc2 = FriendCode.objects.create(
|
||||
friend_code="2345-6789-0123-4567",
|
||||
user=self.user,
|
||||
in_game_name="GameTwo"
|
||||
)
|
||||
# Set fc2 as default.
|
||||
self.user.set_default_friend_code(fc2)
|
||||
# Removing fc2 should reassign the default to fc1.
|
||||
self.user.remove_default_friend_code(fc2)
|
||||
self.user.refresh_from_db()
|
||||
self.assertEqual(self.user.default_friend_code, fc1)
|
||||
|
||||
def test_removing_only_friend_code_raises(self):
|
||||
"""
|
||||
A user must always have a default friend code.
|
||||
Attempting to remove the only friend code (and thus the default)
|
||||
should be prohibited.
|
||||
"""
|
||||
fc = FriendCode.objects.create(
|
||||
friend_code="1234-5678-9012-3456",
|
||||
user=self.user,
|
||||
in_game_name="OnlyGame"
|
||||
)
|
||||
self.user.refresh_from_db()
|
||||
self.assertEqual(self.user.default_friend_code, fc)
|
||||
with self.assertRaises(ValidationError):
|
||||
self.user.remove_default_friend_code(fc)
|
||||
|
||||
def test_remove_non_default_friend_code_does_nothing(self):
|
||||
"""
|
||||
When attempting to remove a friend code that isn't the default,
|
||||
the current default should remain unchanged.
|
||||
"""
|
||||
fc1 = FriendCode.objects.create(
|
||||
friend_code="1234-5678-9012-3456",
|
||||
user=self.user,
|
||||
in_game_name="GameOne"
|
||||
)
|
||||
fc2 = FriendCode.objects.create(
|
||||
friend_code="2345-6789-0123-4567",
|
||||
user=self.user,
|
||||
in_game_name="GameTwo"
|
||||
)
|
||||
# By default, fc1 is the default friend code.
|
||||
self.assertEqual(self.user.default_friend_code, fc1)
|
||||
try:
|
||||
self.user.remove_default_friend_code(fc2)
|
||||
except Exception as e:
|
||||
self.fail("remove_default_friend_code raised an exception when removing a non-default code.")
|
||||
self.user.refresh_from_db()
|
||||
self.assertEqual(self.user.default_friend_code, fc1)
|
||||
|
||||
|
||||
# -----------------------------
|
||||
# FriendCode Model Tests
|
||||
# -----------------------------
|
||||
class FriendCodeModelTests(TestCase):
|
||||
def setUp(self):
|
||||
self.user = get_user_model().objects.create_user(
|
||||
username="testuser2",
|
||||
email="test2@example.com",
|
||||
password="password123"
|
||||
)
|
||||
|
||||
def test_default_set_on_creation(self):
|
||||
"""
|
||||
When creating a FriendCode for a user with no default,
|
||||
the new friend code is automatically set as the default.
|
||||
"""
|
||||
fc = FriendCode.objects.create(
|
||||
friend_code="1234-5678-9012-3456",
|
||||
user=self.user,
|
||||
in_game_name="GameDefault"
|
||||
)
|
||||
self.user.refresh_from_db()
|
||||
self.assertEqual(self.user.default_friend_code, fc)
|
||||
|
||||
def test_adding_additional_friend_code_preserves_default(self):
|
||||
"""
|
||||
When additional friend codes are added to a user who already has a default,
|
||||
the initial friend code remains the default.
|
||||
"""
|
||||
fc1 = FriendCode.objects.create(
|
||||
friend_code="1111-1111-1111-1111",
|
||||
user=self.user,
|
||||
in_game_name="PrimaryGame"
|
||||
)
|
||||
# fc1 becomes the default automatically.
|
||||
self.assertEqual(self.user.default_friend_code, fc1)
|
||||
fc2 = FriendCode.objects.create(
|
||||
friend_code="2222-2222-2222-2222",
|
||||
user=self.user,
|
||||
in_game_name="SecondaryGame"
|
||||
)
|
||||
self.user.refresh_from_db()
|
||||
self.assertEqual(self.user.default_friend_code, fc1)
|
||||
|
||||
|
||||
# -----------------------------
|
||||
# Form Tests
|
||||
# -----------------------------
|
||||
class FriendCodeFormTests(TestCase):
|
||||
def test_valid_friend_code(self):
|
||||
"""Ensure valid friend code is cleaned and formatted properly."""
|
||||
form_data = {
|
||||
"friend_code": "1234567890123456",
|
||||
"in_game_name": "GameTest"
|
||||
}
|
||||
form = FriendCodeForm(data=form_data)
|
||||
self.assertTrue(form.is_valid())
|
||||
self.assertEqual(form.cleaned_data["friend_code"], "1234-5678-9012-3456")
|
||||
|
||||
def test_invalid_friend_code_length(self):
|
||||
"""Friend codes with incorrect length should cause validation errors."""
|
||||
form_data = {
|
||||
"friend_code": "12345",
|
||||
"in_game_name": "GameTest"
|
||||
}
|
||||
form = FriendCodeForm(data=form_data)
|
||||
self.assertFalse(form.is_valid())
|
||||
self.assertIn("Friend code must be exactly 16 digits long.", form.errors["friend_code"])
|
||||
|
||||
def test_invalid_friend_code_characters(self):
|
||||
"""Friend codes containing non-digit characters should cause validation errors."""
|
||||
form_data = {
|
||||
"friend_code": "12345678901234ab",
|
||||
"in_game_name": "GameTest"
|
||||
}
|
||||
form = FriendCodeForm(data=form_data)
|
||||
self.assertFalse(form.is_valid())
|
||||
self.assertIn("Friend code must be exactly 16 digits long.", form.errors["friend_code"])
|
||||
|
||||
def test_friend_code_with_whitespace(self):
|
||||
"""Ensure that leading/trailing whitespace is stripped."""
|
||||
form_data = {
|
||||
"friend_code": " 1234567890123456 ",
|
||||
"in_game_name": "WhitespaceGame"
|
||||
}
|
||||
form = FriendCodeForm(data=form_data)
|
||||
self.assertTrue(form.is_valid())
|
||||
self.assertEqual(form.cleaned_data["friend_code"], "1234-5678-9012-3456")
|
||||
|
||||
def test_friend_code_with_dashes(self):
|
||||
"""Proper dashes in the input should be accepted."""
|
||||
form_data = {
|
||||
"friend_code": "1234-5678-9012-3456",
|
||||
"in_game_name": "ExtraDashGame"
|
||||
}
|
||||
form = FriendCodeForm(data=form_data)
|
||||
self.assertTrue(form.is_valid())
|
||||
self.assertEqual(form.cleaned_data["friend_code"], "1234-5678-9012-3456")
|
||||
|
||||
|
||||
class CustomUserCreationFormTests(TestCase):
|
||||
def _get_request_with_session(self):
|
||||
"""
|
||||
Helper to create a Request object that has a session,
|
||||
so that the signup view and form can use request.session.
|
||||
"""
|
||||
request = RequestFactory().get("/")
|
||||
middleware = SessionMiddleware(lambda r: None)
|
||||
middleware.process_request(request)
|
||||
request.session.save()
|
||||
return request
|
||||
|
||||
def test_valid_custom_user_creation(self):
|
||||
"""
|
||||
Test that the custom sign‑up form creates a user and associated friend code properly.
|
||||
"""
|
||||
form_data = {
|
||||
"email": "new@example.com",
|
||||
"username": "newuser",
|
||||
"password1": "complexpass123",
|
||||
"password2": "complexpass123",
|
||||
"friend_code": "5555-5555-5555-5555",
|
||||
"in_game_name": "NewGame",
|
||||
}
|
||||
form = CustomUserCreationForm(data=form_data)
|
||||
self.assertTrue(form.is_valid())
|
||||
request = self._get_request_with_session()
|
||||
user = form.save(request)
|
||||
self.assertIsNotNone(user)
|
||||
# Check that the associated friend code exists and marked as the default.
|
||||
friend_code = user.default_friend_code
|
||||
self.assertIsNotNone(friend_code)
|
||||
self.assertEqual(friend_code.friend_code, "5555-5555-5555-5555")
|
||||
self.assertEqual(friend_code.in_game_name, "NewGame")
|
||||
|
||||
def test_user_always_has_default_after_signup(self):
|
||||
"""
|
||||
Ensure that after sign-up (which creates the initial friend code),
|
||||
the user always has a default friend code.
|
||||
"""
|
||||
form_data = {
|
||||
"email": "another@example.com",
|
||||
"username": "anotheruser",
|
||||
"password1": "complexpass456",
|
||||
"password2": "complexpass456",
|
||||
"friend_code": "6666-6666-6666-6666",
|
||||
"in_game_name": "AnotherGame",
|
||||
}
|
||||
form = CustomUserCreationForm(data=form_data)
|
||||
self.assertTrue(form.is_valid())
|
||||
request = self._get_request_with_session()
|
||||
user = form.save(request)
|
||||
# Immediately after signup, the user should have a default friend code.
|
||||
self.assertIsNotNone(user.default_friend_code)
|
||||
|
||||
def test_invalid_custom_user_creation_invalid_friend_code(self):
|
||||
"""
|
||||
Supplying an invalid friend code (wrong length/format) should cause the form to fail.
|
||||
"""
|
||||
form_data = {
|
||||
"email": "bad@example.com",
|
||||
"username": "baduser",
|
||||
"password1": "pass12345",
|
||||
"password2": "pass12345",
|
||||
"friend_code": "abcde", # Invalid friend code
|
||||
"in_game_name": "BadGame",
|
||||
}
|
||||
form = CustomUserCreationForm(data=form_data)
|
||||
self.assertFalse(form.is_valid())
|
||||
self.assertIn("Friend code must be exactly 16 digits long.", form.errors["friend_code"])
|
||||
|
||||
def test_invalid_custom_user_creation_password_mismatch(self):
|
||||
"""
|
||||
The form should catch mismatched passwords.
|
||||
"""
|
||||
form_data = {
|
||||
"email": "passmismatch@example.com",
|
||||
"username": "passmismatch",
|
||||
"password1": "pass12345",
|
||||
"password2": "differentpass",
|
||||
"friend_code": "5555-5555-5555-5555",
|
||||
"in_game_name": "MismatchGame",
|
||||
}
|
||||
form = CustomUserCreationForm(data=form_data)
|
||||
self.assertFalse(form.is_valid())
|
||||
# The error key may be '__all__' or 'password2' depending on the implementation.
|
||||
errors = form.errors.get("__all__") or form.errors.get("password2")
|
||||
self.assertTrue(errors, "Expected a password mismatch error.")
|
||||
|
||||
|
||||
class UserSettingsFormTests(TestCase):
|
||||
def setUp(self):
|
||||
self.user = get_user_model().objects.create_user(
|
||||
username="settingsuser",
|
||||
email="settings@example.com",
|
||||
password="password123"
|
||||
)
|
||||
|
||||
def test_toggle_show_friend_code_on_link_previews(self):
|
||||
"""Test updating the user setting for showing friend code on link previews."""
|
||||
form_data = {"show_friend_code_on_link_previews": True}
|
||||
form = UserSettingsForm(form_data, instance=self.user)
|
||||
self.assertTrue(form.is_valid())
|
||||
form.save()
|
||||
self.user.refresh_from_db()
|
||||
self.assertTrue(self.user.show_friend_code_on_link_previews)
|
||||
|
||||
|
||||
# -----------------------------
|
||||
# View Tests
|
||||
# -----------------------------
|
||||
class FriendCodeViewsTests(TestCase):
|
||||
def setUp(self):
|
||||
self.user = get_user_model().objects.create_user(
|
||||
username="viewuser",
|
||||
email="viewuser@example.com",
|
||||
password="password123"
|
||||
)
|
||||
# Log in this user.
|
||||
self.client.login(username="viewuser", password="password123")
|
||||
# Create two friend codes.
|
||||
self.friend_code1 = FriendCode.objects.create(
|
||||
friend_code="7777-7777-7777-7777",
|
||||
user=self.user,
|
||||
in_game_name="ViewGameOne"
|
||||
)
|
||||
self.friend_code2 = FriendCode.objects.create(
|
||||
friend_code="8888-8888-8888-8888",
|
||||
user=self.user,
|
||||
in_game_name="ViewGameTwo"
|
||||
)
|
||||
# By default, friend_code1 is the default.
|
||||
|
||||
def test_list_friend_codes_view(self):
|
||||
"""The list view should display all friend codes with a correct default flag."""
|
||||
url = reverse("list_friend_codes")
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
friend_codes = response.context["friend_codes"]
|
||||
self.assertEqual(friend_codes.count(), 2)
|
||||
for fc in friend_codes:
|
||||
if fc.pk == self.friend_code1.pk:
|
||||
self.assertTrue(fc.is_default)
|
||||
else:
|
||||
self.assertFalse(fc.is_default)
|
||||
|
||||
def test_list_friend_codes_view_unauthenticated(self):
|
||||
"""An unauthenticated user should be redirected from the friend codes list view."""
|
||||
self.client.logout()
|
||||
url = reverse("list_friend_codes")
|
||||
response = self.client.get(url)
|
||||
self.assertNotEqual(response.status_code, 200)
|
||||
# Adjust the login URL as per your configuration.
|
||||
self.assertIn("/accounts/login/", response.url)
|
||||
|
||||
def test_add_friend_code_view(self):
|
||||
"""Test both GET and POST for adding a new friend code."""
|
||||
url = reverse("add_friend_code")
|
||||
# GET request.
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
# POST request.
|
||||
data = {"friend_code": "9999999999999999", "in_game_name": "ViewGameThree"}
|
||||
response = self.client.post(url, data)
|
||||
self.assertRedirects(response, reverse("list_friend_codes"))
|
||||
self.assertTrue(
|
||||
FriendCode.objects.filter(
|
||||
user=self.user,
|
||||
friend_code="9999-9999-9999-9999"
|
||||
).exists()
|
||||
)
|
||||
# Ensure that adding a new friend code does not change the default.
|
||||
self.user.refresh_from_db()
|
||||
self.assertEqual(self.user.default_friend_code, self.friend_code1)
|
||||
|
||||
def test_add_friend_code_view_invalid_data(self):
|
||||
"""Submitting invalid friend code data should not create a new record."""
|
||||
url = reverse("add_friend_code")
|
||||
data = {"friend_code": "invalidfriendcode", "in_game_name": "InvalidGame"}
|
||||
response = self.client.post(url, data)
|
||||
# Extract the form from the response's context. If response.context is a list, use its first element.
|
||||
context = response.context[0] if isinstance(response.context, list) else response.context
|
||||
form = context.get("form")
|
||||
self.assertIsNotNone(form, "Form not found in response context")
|
||||
self.assertFormError(form, "friend_code", "Friend code must be exactly 16 digits long.")
|
||||
|
||||
def test_edit_friend_code_view(self):
|
||||
"""Test editing the in-game name of an existing friend code."""
|
||||
url = reverse("edit_friend_code", kwargs={"pk": self.friend_code2.pk})
|
||||
# GET request.
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
# POST request.
|
||||
new_data = {"in_game_name": "UpdatedViewGame"}
|
||||
response = self.client.post(url, new_data)
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.friend_code2.refresh_from_db()
|
||||
self.assertEqual(self.friend_code2.in_game_name, "UpdatedViewGame")
|
||||
|
||||
def test_edit_friend_code_view_wrong_user(self):
|
||||
"""A user should not be able to edit a friend code that does not belong to them."""
|
||||
other_user = get_user_model().objects.create_user(
|
||||
username="otheruser",
|
||||
email="other@example.com",
|
||||
password="password1234"
|
||||
)
|
||||
friend_code_other = FriendCode.objects.create(
|
||||
friend_code="0000-0000-0000-0000",
|
||||
user=other_user,
|
||||
in_game_name="OtherGame"
|
||||
)
|
||||
url = reverse("edit_friend_code", kwargs={"pk": friend_code_other.pk})
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_edit_friend_code_view_invalid_data(self):
|
||||
"""Invalid POST data for editing friend code should result in form errors."""
|
||||
url = reverse("edit_friend_code", kwargs={"pk": self.friend_code2.pk})
|
||||
new_data = {"in_game_name": ""} # in_game_name is required.
|
||||
response = self.client.post(url, new_data)
|
||||
context = response.context[0] if isinstance(response.context, list) else response.context
|
||||
form = context.get("form")
|
||||
self.assertIsNotNone(form, "Form not found in response context")
|
||||
self.assertFormError(form, "in_game_name", "This field is required.")
|
||||
|
||||
def test_delete_friend_code_view_only_code(self):
|
||||
"""
|
||||
If the user has only one friend code, deletion should be disabled.
|
||||
This test uses a new user with a single friend code.
|
||||
"""
|
||||
user_only = get_user_model().objects.create_user(
|
||||
username="onlyuser",
|
||||
email="onlyuser@example.com",
|
||||
password="password123"
|
||||
)
|
||||
friend_code_only = FriendCode.objects.create(
|
||||
friend_code="4444-4444-4444-4444",
|
||||
user=user_only,
|
||||
in_game_name="SoloGame"
|
||||
)
|
||||
self.client.logout()
|
||||
self.client.login(username="onlyuser", password="password123")
|
||||
url = reverse("delete_friend_code", kwargs={"pk": friend_code_only.pk})
|
||||
# GET request: deletion should be disabled.
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertIn("disable_delete", response.context)
|
||||
self.assertTrue(response.context["disable_delete"])
|
||||
# POST request should not delete the friend code.
|
||||
response = self.client.post(url, {})
|
||||
self.assertRedirects(response, reverse("list_friend_codes"))
|
||||
self.assertTrue(FriendCode.objects.filter(pk=friend_code_only.pk).exists())
|
||||
|
||||
def test_delete_friend_code_view_default_code(self):
|
||||
"""Deleting the default friend code should be prevented."""
|
||||
url = reverse("delete_friend_code", kwargs={"pk": self.friend_code1.pk})
|
||||
response = self.client.post(url, {})
|
||||
self.assertRedirects(response, reverse("list_friend_codes"))
|
||||
self.assertTrue(FriendCode.objects.filter(pk=self.friend_code1.pk).exists())
|
||||
|
||||
def test_delete_friend_code_view_with_trade_offers(self):
|
||||
"""
|
||||
If a friend code is associated with trade offers, deletion should be blocked.
|
||||
Instead of direct assignment, we patch the `exists` methods on the related managers.
|
||||
"""
|
||||
self.trade_offer = TradeOffer.objects.create(
|
||||
initiated_by=self.friend_code2,
|
||||
is_closed=False,
|
||||
rarity_icon="⭐️",
|
||||
rarity_level=5
|
||||
)
|
||||
url = reverse("delete_friend_code", kwargs={"pk": self.friend_code2.pk})
|
||||
response = self.client.post(url, {})
|
||||
self.assertRedirects(response, reverse("list_friend_codes"))
|
||||
self.assertTrue(FriendCode.objects.filter(pk=self.friend_code2.pk).exists())
|
||||
self.trade_offer.delete()
|
||||
|
||||
def test_change_default_friend_code_view(self):
|
||||
"""Test that a POST to change the default friend code updates the user setting."""
|
||||
url = reverse("change_default_friend_code", kwargs={"pk": self.friend_code2.pk})
|
||||
response = self.client.post(url, {})
|
||||
self.assertRedirects(response, reverse("list_friend_codes"))
|
||||
self.user.refresh_from_db()
|
||||
self.assertEqual(self.user.default_friend_code.pk, self.friend_code2.pk)
|
||||
|
||||
def test_change_default_friend_code_view_invalid_friend_code(self):
|
||||
"""Posting a non-existent friend code id should return a 404 error."""
|
||||
url = reverse("change_default_friend_code", kwargs={"pk": 99999})
|
||||
response = self.client.post(url, {})
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_change_default_friend_code_view_not_owned(self):
|
||||
"""A friend code that does not belong to the current user should result in a 404."""
|
||||
other_user = get_user_model().objects.create_user(
|
||||
username="otheruser2",
|
||||
email="other2@example.com",
|
||||
password="password789"
|
||||
)
|
||||
friend_code_other = FriendCode.objects.create(
|
||||
friend_code="1111-1111-1111-1111",
|
||||
user=other_user,
|
||||
in_game_name="NotMine"
|
||||
)
|
||||
url = reverse("change_default_friend_code", kwargs={"pk": friend_code_other.pk})
|
||||
response = self.client.post(url, {})
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_settings_view(self):
|
||||
"""Settings view should allow updating of user settings."""
|
||||
url = reverse("settings")
|
||||
# GET request.
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
# POST request.
|
||||
data = {"show_friend_code_on_link_previews": True}
|
||||
response = self.client.post(url, data)
|
||||
self.assertRedirects(response, reverse("settings"))
|
||||
self.user.refresh_from_db()
|
||||
self.assertTrue(self.user.show_friend_code_on_link_previews)
|
||||
|
||||
def test_profile_view(self):
|
||||
"""Profile page should be accessible for authenticated users."""
|
||||
url = reverse("profile")
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_profile_view_unauthenticated(self):
|
||||
"""Unauthenticated users should be redirected from the profile page."""
|
||||
self.client.logout()
|
||||
url = reverse("profile")
|
||||
response = self.client.get(url)
|
||||
self.assertNotEqual(response.status_code, 200)
|
||||
|
||||
def test_delete_friend_code_view_wrong_user(self):
|
||||
"""A user should not be able to delete a friend code that does not belong to them."""
|
||||
other_user = get_user_model().objects.create_user(
|
||||
username="otherdeluser",
|
||||
email="otherdel@example.com",
|
||||
password="password321"
|
||||
)
|
||||
friend_code_other = FriendCode.objects.create(
|
||||
friend_code="2222-2222-2222-2222",
|
||||
user=other_user,
|
||||
in_game_name="OtherDelete"
|
||||
)
|
||||
url = reverse("delete_friend_code", kwargs={"pk": friend_code_other.pk})
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
|
||||
# -----------------------------
|
||||
# Template Tags Tests
|
||||
# -----------------------------
|
||||
class TemplateTagTests(TestCase):
|
||||
def test_gravatar_hash(self):
|
||||
"""Test that gravatar_hash returns the correct SHA256 hash."""
|
||||
email = "Test@Example.com"
|
||||
expected = hashlib.sha256(email.strip().lower().encode("utf-8")).hexdigest()
|
||||
result = gravatar.gravatar_hash(email)
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
def test_gravatar_url(self):
|
||||
"""Ensure gravatar_url returns a URL with the proper parameters."""
|
||||
email = "user@example.com"
|
||||
size = 100
|
||||
url = gravatar.gravatar_url(email, size)
|
||||
self.assertIn("s=100", url)
|
||||
self.assertIn("https://www.gravatar.com/avatar/", url)
|
||||
|
||||
def test_gravatar_profile_url_with_none(self):
|
||||
"""Test gravatar_profile_url returns the generic profile URL if no email is provided."""
|
||||
url = gravatar.gravatar_profile_url()
|
||||
self.assertEqual(url, "https://www.gravatar.com/profile")
|
||||
|
||||
def test_gravatar_filter(self):
|
||||
"""Test that the gravatar filter returns an HTML image tag with expected attributes."""
|
||||
email = "user@example.com"
|
||||
size = 50
|
||||
result = gravatar.gravatar(email, size)
|
||||
self.assertIn('img src="', result)
|
||||
self.assertIn(f'width="{size}"', result)
|
||||
|
||||
@patch("accounts.templatetags.gravatar.requests.get")
|
||||
def test_gravatar_profile_data_success(self, mock_get):
|
||||
"""Test that gravatar_profile_data returns the first entry when JSON response is valid."""
|
||||
dummy_entry = {"name": "Test User"}
|
||||
mock_response = MagicMock()
|
||||
mock_response.json.return_value = {"entry": [dummy_entry]}
|
||||
mock_response.raise_for_status.return_value = None
|
||||
mock_get.return_value = mock_response
|
||||
data = gravatar.gravatar_profile_data("user@example.com")
|
||||
self.assertEqual(data, dummy_entry)
|
||||
|
||||
@patch("accounts.templatetags.gravatar.requests.get")
|
||||
def test_gravatar_profile_data_failure(self, mock_get):
|
||||
"""
|
||||
If requests.get fails or the JSON is not valid,
|
||||
gravatar_profile_data should return an empty dictionary.
|
||||
"""
|
||||
mock_get.side_effect = requests.RequestException("Request failed")
|
||||
data = gravatar.gravatar_profile_data("user@example.com")
|
||||
self.assertEqual(data, {})
|
||||
|
||||
def test_gravatar_no_hover(self):
|
||||
"""Test that gravatar_no_hover returns an image tag with the additional 'ignore' class."""
|
||||
email = "hover@example.com"
|
||||
result = gravatar.gravatar_no_hover(email, 30)
|
||||
self.assertIn('class="ignore"', result)
|
||||
|
||||
def test_gravatar_filter_with_empty_string(self):
|
||||
"""Even if an empty email is passed, the gravatar filter should return an image tag."""
|
||||
result = gravatar.gravatar("", 40)
|
||||
self.assertIn('img src="', result)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ from django.views.generic import ListView, CreateView, DeleteView, View, Templat
|
|||
from accounts.models import FriendCode, CustomUser
|
||||
from accounts.forms import FriendCodeForm, UserSettingsForm
|
||||
from django.db.models import Case, When, Value, BooleanField
|
||||
from trades.models import TradeOffer, TradeAcceptance
|
||||
|
||||
class ListFriendCodesView(LoginRequiredMixin, ListView):
|
||||
"""
|
||||
|
|
@ -99,8 +100,11 @@ class DeleteFriendCodeView(LoginRequiredMixin, DeleteView):
|
|||
)
|
||||
return redirect(self.success_url)
|
||||
|
||||
# Also check if this friend code is referenced by any trade offer.
|
||||
if self.object.initiated_trade_offers.exists() or self.object.trade_acceptances.exists():
|
||||
# Use the unfiltered manager and filter by the friend code's primary key
|
||||
trade_offer_exists = TradeOffer.all_offers.filter(initiated_by_id=self.object.pk).exists()
|
||||
trade_acceptance_exists = TradeAcceptance.objects.filter(accepted_by_id=self.object.pk).exists()
|
||||
|
||||
if trade_offer_exists or trade_acceptance_exists:
|
||||
messages.error(
|
||||
request,
|
||||
"Cannot remove this friend code because there are existing trade offers associated with it."
|
||||
|
|
@ -110,7 +114,7 @@ class DeleteFriendCodeView(LoginRequiredMixin, DeleteView):
|
|||
# Proceed to safe deletion.
|
||||
self.object.delete()
|
||||
messages.success(request, "Friend code removed successfully.")
|
||||
return redirect(self.success_url + "?deleted=true")
|
||||
return redirect(self.success_url)
|
||||
|
||||
class ChangeDefaultFriendCodeView(LoginRequiredMixin, View):
|
||||
"""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue