from django.test import TestCase, Client from django.urls import reverse from django.contrib.auth import get_user_model from store.models import Game, Set, Card from decks.models import Deck from .utils import parse_deck_list User = get_user_model() class DeckImportParsingTests(TestCase): def test_parse_arena_format(self): text = """ 1 Laughing Jasper Flint (OTJ) 215 *F* 1 Arcane Signet (LTC) 273 1 At Knifepoint (OTJ) 193 SIDEBOARD: 1 Agate Instigator (BLC) 21 """ parsed = parse_deck_list(text) self.assertEqual(len(parsed), 4) self.assertEqual(parsed[0]['name'], "Laughing Jasper Flint") self.assertEqual(parsed[0]['quantity'], 1) self.assertFalse(parsed[0]['is_sideboard']) self.assertEqual(parsed[2]['name'], "At Knifepoint") self.assertFalse(parsed[2]['is_sideboard']) self.assertEqual(parsed[3]['name'], "Agate Instigator") self.assertTrue(parsed[3]['is_sideboard']) def test_parse_mtgo_format(self): text = """ 1 Arcane Signet 1 At Knifepoint SIDEBOARD: 1 Agate Instigator """ parsed = parse_deck_list(text) self.assertEqual(len(parsed), 3) self.assertEqual(parsed[0]['name'], "Arcane Signet") self.assertEqual(parsed[2]['name'], "Agate Instigator") self.assertTrue(parsed[2]['is_sideboard']) def test_parse_moxfield_complex(self): # Moxfield/Arena sometimes has confusing lines like split cards text = """ 1 Blightstep Pathway / Searstep Pathway (KHM) 291 1 Command Tower (PLST) C21-284 """ parsed = parse_deck_list(text) self.assertEqual(len(parsed), 2) # Verify it stops capturing before the (SET) part self.assertEqual(parsed[0]['name'], "Blightstep Pathway / Searstep Pathway") self.assertEqual(parsed[1]['name'], "Command Tower") def test_parse_plain_text(self): text = """ 10 Mountain 1 Sol Ring """ parsed = parse_deck_list(text) self.assertEqual(len(parsed), 2) self.assertEqual(parsed[0]['quantity'], 10) self.assertEqual(parsed[0]['name'], "Mountain") class DeckImportViewTests(TestCase): def setUp(self): self.user = User.objects.create_user(username='testuser', password='password') # Create profile and set is_pro = True # Using get_or_create to handle signal-created profiles if any, though standard is signals usually handle create if not hasattr(self.user, 'profile'): from users.models import Profile Profile.objects.create(user=self.user) self.user.profile.is_pro = True self.user.profile.save() self.client = Client() self.client.login(username='testuser', password='password') self.game = Game.objects.create(name='Magic: The Gathering', slug='mtg') self.set = Set.objects.create(game=self.game, name='Test Set', code='TST') self.card1 = Card.objects.create(set=self.set, name='Lightning Bolt') self.card2 = Card.objects.create(set=self.set, name='Mountain') def test_import_simple_deck(self): url = reverse('decks:deck_import') deck_text = """ 4 Lightning Bolt 10 Mountain """ data = { 'name': 'Red Deck', 'game': self.game.id, 'deck_list': deck_text } response = self.client.post(url, data, follow=True) self.assertContains(response, 'Successfully imported deck') deck = Deck.objects.get(name='Red Deck') self.assertEqual(deck.cards.count(), 2) bolt = deck.cards.get(card=self.card1) self.assertEqual(bolt.quantity, 4) mountain = deck.cards.get(card=self.card2) self.assertEqual(mountain.quantity, 10) def test_import_with_missing_cards(self): url = reverse('decks:deck_import') deck_text = """ 4 Lightning Bolt 1 Black Lotus """ data = { 'name': 'Power Deck', 'game': self.game.id, 'deck_list': deck_text } response = self.client.post(url, data, follow=True) self.assertContains(response, 'Could not find') deck = Deck.objects.get(name='Power Deck') self.assertEqual(deck.cards.count(), 1) # Only bolt