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:
18
src/apps/lyric/migrations/0009_alter_token_token_type.py
Normal file
18
src/apps/lyric/migrations/0009_alter_token_token_type.py
Normal 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),
|
||||
),
|
||||
]
|
||||
@@ -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)
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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())
|
||||
|
||||
|
||||
Reference in New Issue
Block a user