new apps.epic app migrations for token expiration & cooldown; reject token renamed to return token everywhere; new mapps.epic.models & .views for expiration & cooldown; new apps.dash.views to manage stacking of like Token types not just in the kit bag but in the Gameboard's Game Kit applet & in the Dashwallet's Tokens applet; Free Tokens now display correctly in kit bag; apps.lyric.admin now ensures superuser cannot grant Free Tokens without an expiration date; corresponding tests in .tests.integrated.test_admin.TokenAdminFormTest; screendumps occurring for every test, regardless of passfail status, after one fail fixed in FTs.base; FTs.test_gatekeeper.GameKitInsertTest.test_free_token_insert_via_kit_consumed_on_confirm, for test purposes only, ensures starting Free Token deleted before fresh one assigned w. full 7d expiration battery

This commit is contained in:
Disco DeDisco
2026-03-15 16:08:34 -04:00
parent 18ba242647
commit 2e24175ec8
16 changed files with 244 additions and 69 deletions

View File

@@ -59,7 +59,10 @@ class FunctionalTest(StaticLiveServerTestCase):
super().tearDown()
def _test_has_failed(self):
return self._outcome.result.failures or self._outcome.result.errors
return any(
failure[0] == self
for failure in self._outcome.result.failures + self._outcome.result.errors
)
def take_screenshot(self):
path = SCREEN_DUMP_LOCATION / self._get_filename("png")

View File

@@ -314,15 +314,15 @@ class CoinSlotTest(FunctionalTest):
slot.refresh_from_db()
self.assertEqual(slot.status, GateSlot.FILLED)
def test_gamer_can_reject_pending_token(self):
# Drop then reject via Push to Reject → slot remains empty
def test_gamer_can_return_pending_token(self):
# Drop then return via Push to Return → slot remains empty
self.browser.get(self.gate_url)
self.wait_for(
lambda: self.browser.find_element(By.CSS_SELECTOR, "button.token-rails")
).click()
# Push to Reject appears in coin slot
# Push to Return appears in coin slot
self.wait_for(
lambda: self.browser.find_element(By.CSS_SELECTOR, ".token-reject-btn")
lambda: self.browser.find_element(By.CSS_SELECTOR, ".token-return-btn")
).click()
# Slot 1 still empty; coin slot active again
self.wait_for(
@@ -535,6 +535,7 @@ class GameKitInsertTest(FunctionalTest):
self.assertEqual(self.browser.current_url, self.gate_url)
def test_free_token_insert_via_kit_consumed_on_confirm(self):
self.gamer.tokens.filter(token_type=Token.FREE).delete()
token = Token.objects.create(
user=self.gamer,
token_type=Token.FREE,