new model fields & migrations for apps.epic & apps.lyric; new FTs, ITs & UTs passing

; some styling changes effected primarily to _gatekeetper.html modal
This commit is contained in:
Disco DeDisco
2026-03-14 22:00:16 -04:00
parent 26b6d4e7db
commit 4baaa63430
13 changed files with 410 additions and 28 deletions

View File

@@ -0,0 +1,18 @@
# Generated by Django 6.0 on 2026-03-15 00:32
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('lyric', '0008_token_current_room_token_next_ready_at'),
]
operations = [
migrations.AlterField(
model_name='token',
name='token_type',
field=models.CharField(choices=[('coin', 'Coin-on-a-String'), ('Free', 'Free Token'), ('tithe', 'Tithe Token'), ('pass', 'Backstage Pass')], max_length=8),
),
]

View File

@@ -71,10 +71,12 @@ class Token(models.Model):
COIN = "coin"
FREE = "Free"
TITHE = "tithe"
PASS = "pass"
TOKEN_TYPE_CHOICES = [
(COIN, "Coin-on-a-String"),
(FREE, "Free Token"),
(TITHE, "Tithe Token"),
(PASS, "Backstage Pass"),
]
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="tokens")
@@ -97,8 +99,8 @@ class Token(models.Model):
return ""
def tooltip_expiry(self):
if self.token_type == self.COIN:
if self.next_ready_at:
if self.token_type in (self.COIN, self.PASS):
if self.token_type == self.COIN and self.next_ready_at:
return f"Ready {self.next_ready_at.strftime('%Y-%m-%d')}"
return "no expiry"
if self.expires_at:
@@ -143,3 +145,5 @@ def create_wallet_and_tokens(sender, instance, created, **kwargs):
token_type=Token.FREE,
expires_at=timezone.now() + timedelta(days=7),
)
if instance.is_staff:
Token.objects.create(user=instance, token_type=Token.PASS)

View File

@@ -97,6 +97,30 @@ class TokenCreationTest(TestCase):
self.assertLessEqual(delta.days, 7)
self.assertGreater(delta.total_seconds(), 0)
def test_no_pass_token_for_regular_user(self):
self.assertFalse(
Token.objects.filter(user=self.user, token_type=Token.PASS).exists()
)
class SuperuserTokenCreationTest(TestCase):
def setUp(self):
self.user = User.objects.create_superuser(
email="admin@test.io", password="secret"
)
def test_pass_token_created_for_superuser(self):
self.assertTrue(
Token.objects.filter(user=self.user, token_type=Token.PASS).exists()
)
def test_superuser_also_gets_coin_and_free_token(self):
self.assertTrue(
Token.objects.filter(user=self.user, token_type=Token.COIN).exists()
)
self.assertTrue(
Token.objects.filter(user=self.user, token_type=Token.FREE).exists()
)
class WalletTooltipTest(TestCase):
def setUp(self):

View File

@@ -41,3 +41,17 @@ class FreeTokenTooltipTest(SimpleTestCase):
def test_tooltip_contains_expiry_date(self):
self.assertIn("2026-03-15", self.token.tooltip_text())
class PassTokenTooltipTest(SimpleTestCase):
def setUp(self):
self.token = Token()
self.token.token_type = Token.PASS
self.token.expires_at = None
self.token.next_ready_at = None
def test_tooltip_contains_name(self):
self.assertIn("Backstage Pass", self.token.tooltip_text())
def test_tooltip_contains_no_expiry(self):
self.assertIn("no expiry", self.token.tooltip_text())