Add tests for cards
This commit is contained in:
parent
23d334c596
commit
fd6d75bbac
1 changed files with 286 additions and 2 deletions
288
cards/tests.py
288
cards/tests.py
|
|
@ -1,3 +1,287 @@
|
|||
from django.test import TestCase
|
||||
from django.test import TestCase, Client
|
||||
from django.template import Template, Context
|
||||
from datetime import timedelta
|
||||
|
||||
# Create your tests here.
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
|
||||
from accounts.models import CustomUser, FriendCode
|
||||
from cards.models import Card, Deck, DeckNameTranslation, CardNameTranslation
|
||||
from trades.models import TradeOffer, TradeOfferHaveCard, TradeOfferWantCard
|
||||
from cards.templatetags import card_badge, card_multiselect
|
||||
|
||||
class CardsModelsTestCase(TestCase):
|
||||
def setUp(self):
|
||||
self.deck = Deck.objects.create(
|
||||
name="Test Deck", hex_color="#FFFFFF", cardset="A"
|
||||
)
|
||||
self.card = Card.objects.create(
|
||||
name="Test Card",
|
||||
cardset="A",
|
||||
cardnum=1,
|
||||
style="color: blue;",
|
||||
rarity_icon="★",
|
||||
rarity_level=1
|
||||
)
|
||||
# Establish many-to-many relationship.
|
||||
self.card.decks.add(self.deck)
|
||||
|
||||
def test_card_str(self):
|
||||
expected = f"{self.card.name} {self.card.rarity_icon} {self.card.cardset}"
|
||||
self.assertEqual(str(self.card), expected)
|
||||
|
||||
def test_deck_str(self):
|
||||
self.assertEqual(str(self.deck), self.deck.name)
|
||||
|
||||
def test_deck_name_translation_str(self):
|
||||
deck_translation = DeckNameTranslation.objects.create(
|
||||
name="Deck Translated", deck=self.deck, language="en"
|
||||
)
|
||||
self.assertEqual(str(deck_translation), "Deck Translated")
|
||||
|
||||
def test_card_name_translation_str(self):
|
||||
card_translation = CardNameTranslation.objects.create(
|
||||
name="Card Translated", card=self.card, language="en"
|
||||
)
|
||||
self.assertEqual(str(card_translation), "Card Translated")
|
||||
|
||||
class CardTemplatetagsTestCase(TestCase):
|
||||
def setUp(self):
|
||||
# Create a dummy card to use in template tag tests.
|
||||
self.card = Card.objects.create(
|
||||
name="Template Test Card",
|
||||
cardset="B",
|
||||
cardnum=2,
|
||||
style="background: green;",
|
||||
rarity_icon="☆",
|
||||
rarity_level=2
|
||||
)
|
||||
|
||||
def test_card_badge_inclusion_tag(self):
|
||||
"""Test the card_badge inclusion tag renders correctly."""
|
||||
template_str = '{% load card_badge %}{% card_badge card quantity=3 %}'
|
||||
t = Template(template_str)
|
||||
c = Context({"card": self.card})
|
||||
rendered = t.render(c)
|
||||
# Check that the rendered HTML contains the card name, quantity, and rarity.
|
||||
self.assertIn(self.card.name, rendered)
|
||||
self.assertIn("3", rendered)
|
||||
self.assertIn(self.card.rarity_icon, rendered)
|
||||
|
||||
def test_card_badge_inline_filter(self):
|
||||
"""Test the card_badge_inline filter returns safe HTML with correct data."""
|
||||
template_str = '{% load card_badge %}{{ card|card_badge_inline:5 }}'
|
||||
t = Template(template_str)
|
||||
c = Context({"card": self.card})
|
||||
rendered = t.render(c)
|
||||
self.assertIn(self.card.name, rendered)
|
||||
self.assertIn("5", rendered)
|
||||
self.assertIn(self.card.rarity_icon, rendered)
|
||||
|
||||
def test_card_multiselect_tag_no_selected_values(self):
|
||||
"""Test card_multiselect tag with no selected values."""
|
||||
context = card_multiselect.card_multiselect(
|
||||
field_name="cards",
|
||||
label="Select Cards",
|
||||
placeholder="Choose a card",
|
||||
cards=[self.card],
|
||||
selected_values=None,
|
||||
)
|
||||
self.assertEqual(context["field_name"], "cards")
|
||||
self.assertEqual(context["label"], "Select Cards")
|
||||
self.assertEqual(context["placeholder"], "Choose a card")
|
||||
# When no cards are preselected, each card should have default attributes.
|
||||
for card in context["cards"]:
|
||||
self.assertFalse(getattr(card, "selected", False))
|
||||
self.assertEqual(getattr(card, "selected_quantity", 1), 1)
|
||||
self.assertEqual(context["selected_values"], [])
|
||||
|
||||
def test_card_multiselect_tag_with_selected_values(self):
|
||||
"""Test card_multiselect tag with preselected values (testing both with and without explicit quantity)."""
|
||||
# Create a second card.
|
||||
card2 = Card.objects.create(
|
||||
name="Another Card",
|
||||
cardset="B",
|
||||
cardnum=3,
|
||||
style="background: blue;",
|
||||
rarity_icon="★",
|
||||
rarity_level=2,
|
||||
)
|
||||
selected_values = [f"{self.card.pk}:4", f"{card2.pk}"]
|
||||
context = card_multiselect.card_multiselect(
|
||||
field_name="cards",
|
||||
label="Select Cards",
|
||||
placeholder="Choose a card",
|
||||
cards=[self.card, card2],
|
||||
selected_values=selected_values,
|
||||
)
|
||||
# Verify that self.card is marked as selected with quantity "4" and card2 with default quantity 1.
|
||||
for card in context["cards"]:
|
||||
if card.pk == self.card.pk:
|
||||
self.assertTrue(getattr(card, "selected", False))
|
||||
self.assertEqual(getattr(card, "selected_quantity", 1), "4")
|
||||
elif card.pk == card2.pk:
|
||||
self.assertTrue(getattr(card, "selected", False))
|
||||
self.assertEqual(getattr(card, "selected_quantity", 1), 1)
|
||||
else:
|
||||
self.fail("Unexpected card in the multiselect context.")
|
||||
self.assertCountEqual(
|
||||
context["selected_values"], [str(self.card.pk), str(card2.pk)]
|
||||
)
|
||||
|
||||
def test_card_multiselect_default_cards_when_none_provided(self):
|
||||
"""Test that card_multiselect defaults to Card.objects.all() when no cards are provided."""
|
||||
# Capture all cards from the database.
|
||||
default_cards = list(Card.objects.all())
|
||||
context = card_multiselect.card_multiselect(
|
||||
field_name="cards",
|
||||
label="Select Cards",
|
||||
placeholder="Choose a card",
|
||||
cards=None,
|
||||
selected_values=[],
|
||||
)
|
||||
# Verify that the context's cards match those in the database.
|
||||
self.assertEqual(list(context["cards"]), default_cards)
|
||||
|
||||
class CardsViewsTestCase(TestCase):
|
||||
def setUp(self):
|
||||
self.client = Client()
|
||||
# Create a test user and friend code for trade offers.
|
||||
self.user = CustomUser.objects.create_user(
|
||||
username="testuser", password="secret", email="test@example.com"
|
||||
)
|
||||
self.friendcode = FriendCode.objects.create(
|
||||
user=self.user, friend_code="1234-5678-9012", in_game_name="TestPlayer"
|
||||
)
|
||||
# Create a test card.
|
||||
self.card = Card.objects.create(
|
||||
name="Test Card",
|
||||
cardset="A",
|
||||
cardnum=1,
|
||||
style="background: red;",
|
||||
rarity_icon="★",
|
||||
rarity_level=1
|
||||
)
|
||||
|
||||
def test_card_detail_view_context(self):
|
||||
"""Test that the card detail view includes correct trade offer counts in context."""
|
||||
# Create a trade offer where the card appears as a "have" card.
|
||||
trade_offer_have = TradeOffer.objects.create(initiated_by=self.friendcode)
|
||||
TradeOfferHaveCard.objects.create(
|
||||
trade_offer=trade_offer_have, card=self.card, quantity=2
|
||||
)
|
||||
|
||||
# Create a trade offer where the card appears as a "want" card.
|
||||
trade_offer_want = TradeOffer.objects.create(initiated_by=self.friendcode)
|
||||
TradeOfferWantCard.objects.create(
|
||||
trade_offer=trade_offer_want, card=self.card, quantity=3
|
||||
)
|
||||
|
||||
url = reverse("cards:card_detail", kwargs={"pk": self.card.pk})
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
# Verify that the card instance is in context.
|
||||
self.assertEqual(response.context["card"], self.card)
|
||||
# Verify that the counts are correctly computed.
|
||||
self.assertEqual(response.context.get("trade_offer_have_count"), 1)
|
||||
self.assertEqual(response.context.get("trade_offer_want_count"), 1)
|
||||
|
||||
def test_card_detail_view_404(self):
|
||||
"""Test that the card detail view returns a 404 for a non-existent card."""
|
||||
url = reverse("cards:card_detail", kwargs={"pk": 99999})
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def create_trade_offer_for_have(self, updated_delta_minutes=0):
|
||||
"""
|
||||
Helper method to create a trade offer for the 'have' side with a custom updated_at.
|
||||
"""
|
||||
offer = TradeOffer.objects.create(initiated_by=self.friendcode)
|
||||
TradeOfferHaveCard.objects.create(
|
||||
trade_offer=offer, card=self.card, quantity=1
|
||||
)
|
||||
# Adjust updated_at so that ordering can be tested.
|
||||
new_time = timezone.now() + timedelta(minutes=updated_delta_minutes)
|
||||
TradeOffer.objects.filter(pk=offer.pk).update(updated_at=new_time)
|
||||
offer.refresh_from_db()
|
||||
return offer
|
||||
|
||||
def create_trade_offer_for_want(self, updated_delta_minutes=0):
|
||||
"""
|
||||
Helper method to create a trade offer for the 'want' side with a custom updated_at.
|
||||
"""
|
||||
offer = TradeOffer.objects.create(initiated_by=self.friendcode)
|
||||
TradeOfferWantCard.objects.create(
|
||||
trade_offer=offer, card=self.card, quantity=1
|
||||
)
|
||||
new_time = timezone.now() + timedelta(minutes=updated_delta_minutes)
|
||||
TradeOffer.objects.filter(pk=offer.pk).update(updated_at=new_time)
|
||||
offer.refresh_from_db()
|
||||
return offer
|
||||
|
||||
def test_trade_offer_have_list_view_pagination_and_ordering(self):
|
||||
"""Test the have list view for correct pagination and ordering."""
|
||||
# Create three trade offers with distinct updated_at times.
|
||||
offer1 = self.create_trade_offer_for_have(updated_delta_minutes=1)
|
||||
offer2 = self.create_trade_offer_for_have(updated_delta_minutes=2)
|
||||
offer3 = self.create_trade_offer_for_have(updated_delta_minutes=3)
|
||||
|
||||
url = reverse("cards:card_trade_offer_have_list", kwargs={"pk": self.card.pk})
|
||||
|
||||
# Test default ordering ("newest" which orders descending by updated_at).
|
||||
response = self.client.get(url, {"order": "newest"})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
trade_offers = response.context.get("trade_offers")
|
||||
self.assertEqual(response.context.get("side"), "have")
|
||||
# With paginate_by=2, the first page should have 2 offers.
|
||||
self.assertEqual(len(trade_offers), 2)
|
||||
# The first offer should be the newest (offer3).
|
||||
self.assertEqual(trade_offers[0].pk, offer3.pk)
|
||||
self.assertEqual(trade_offers[1].pk, offer2.pk)
|
||||
|
||||
# Test pagination: second page should contain the remaining offer.
|
||||
response_page2 = self.client.get(url, {"order": "newest", "page": 2})
|
||||
self.assertEqual(response_page2.status_code, 200)
|
||||
trade_offers_page2 = response_page2.context.get("trade_offers")
|
||||
self.assertEqual(len(trade_offers_page2), 1)
|
||||
self.assertEqual(trade_offers_page2[0].pk, offer1.pk)
|
||||
|
||||
# Test "oldest" ordering (ascending by updated_at).
|
||||
response_oldest = self.client.get(url, {"order": "oldest"})
|
||||
self.assertEqual(response_oldest.status_code, 200)
|
||||
trade_offers_oldest = response_oldest.context.get("trade_offers")
|
||||
self.assertEqual(len(trade_offers_oldest), 2)
|
||||
self.assertEqual(trade_offers_oldest[0].pk, offer1.pk)
|
||||
self.assertEqual(trade_offers_oldest[1].pk, offer2.pk)
|
||||
|
||||
def test_trade_offer_want_list_view_pagination_and_ordering(self):
|
||||
"""Test the want list view for correct pagination and ordering."""
|
||||
offer1 = self.create_trade_offer_for_want(updated_delta_minutes=1)
|
||||
offer2 = self.create_trade_offer_for_want(updated_delta_minutes=2)
|
||||
offer3 = self.create_trade_offer_for_want(updated_delta_minutes=3)
|
||||
|
||||
url = reverse("cards:card_trade_offer_want_list", kwargs={"pk": self.card.pk})
|
||||
|
||||
# Test order with "newest" first.
|
||||
response = self.client.get(url, {"order": "newest"})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
trade_offers = response.context.get("trade_offers")
|
||||
self.assertEqual(response.context.get("side"), "want")
|
||||
self.assertEqual(len(trade_offers), 2)
|
||||
self.assertEqual(trade_offers[0].pk, offer3.pk)
|
||||
self.assertEqual(trade_offers[1].pk, offer2.pk)
|
||||
|
||||
# Test pagination boundary on page 2.
|
||||
response_page2 = self.client.get(url, {"order": "newest", "page": 2})
|
||||
self.assertEqual(response_page2.status_code, 200)
|
||||
trade_offers_page2 = response_page2.context.get("trade_offers")
|
||||
self.assertEqual(len(trade_offers_page2), 1)
|
||||
self.assertEqual(trade_offers_page2[0].pk, offer1.pk)
|
||||
|
||||
# Test ordering parameter for "oldest" ordering.
|
||||
response_oldest = self.client.get(url, {"order": "oldest"})
|
||||
self.assertEqual(response_oldest.status_code, 200)
|
||||
trade_offers_oldest = response_oldest.context.get("trade_offers")
|
||||
self.assertEqual(len(trade_offers_oldest), 2)
|
||||
self.assertEqual(trade_offers_oldest[0].pk, offer1.pk)
|
||||
self.assertEqual(trade_offers_oldest[1].pk, offer2.pk)
|
||||
Loading…
Add table
Add a link
Reference in a new issue