note title equip: DON/DOFF buttons outside top-left corner; User.active_title FK; don/doff views; greeting updated via JS — TDD
- lyric/models.py: active_title = ForeignKey('drama.Note', null=True, SET_NULL)
- lyric migration 0020_add_active_title
- billboard/views.py: don_title + doff_title views; is_equipped per note_item context
- billboard/urls.py: note/<slug>/don + note/<slug>/doff routes
- _navbar.html: id_greeting_name span; shows active_title.slug|capfirst when set
- my_notes.html: .note-don-doff buttons (DON/DOFF, × when disabled); data-don-url/doff-url/title attrs
- note-page.js: _bindDonDoff() — DON POST sets greeting + swaps btn state; DOFF restores Earthman
- _note.scss: .note-don-doff position:absolute left:-1rem top:0; flex-direction:column gap:1.25rem
- ITs: NoteEquipTitleViewTest (5 tests); UserModelTest.test_active_title_* (3 tests)
- FT: NoteEquipTitleTest.test_don_equips_title_greeting_and_doff_restores
Code architected by Disco DeDisco <discodedisco@outlook.com>
Git commit message Co-Authored-By:
Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -398,3 +398,68 @@ class StargazerNoteFromSkyPageTest(FunctionalTest):
|
||||
self.browser.find_elements(By.CSS_SELECTOR, ".nw-root")
|
||||
))
|
||||
self.assertFalse(self.browser.find_elements(By.CSS_SELECTOR, ".note-banner"))
|
||||
|
||||
|
||||
# ──────────────────────────────────────────────────────────────────────────────
|
||||
# Title equip — DON/DOFF buttons on the note item
|
||||
# ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
class NoteEquipTitleTest(FunctionalTest):
|
||||
"""DON button equips the note title as the sitewide greeting; DOFF restores it."""
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.browser.set_window_size(800, 1200)
|
||||
Applet.objects.get_or_create(
|
||||
slug="billboard-notes",
|
||||
defaults={"name": "My Notes", "grid_cols": 4, "grid_rows": 4, "context": "billboard"},
|
||||
)
|
||||
self.gamer = User.objects.create(email="stargazer@test.io")
|
||||
|
||||
def test_don_equips_title_greeting_and_doff_restores(self):
|
||||
"""DON replaces 'Earthman' with the note title; DOFF restores 'Earthman'.
|
||||
DON/DOFF follow the game-kit equip button pattern: the active btn is normal,
|
||||
the inactive btn is × + btn-disabled."""
|
||||
Note.objects.create(
|
||||
user=self.gamer, slug="stargazer", earned_at=timezone.now(),
|
||||
)
|
||||
self.create_pre_authenticated_session("stargazer@test.io")
|
||||
self.browser.get(self.live_server_url + "/billboard/my-notes/")
|
||||
|
||||
note_item = self.wait_for(
|
||||
lambda: self.browser.find_element(By.CSS_SELECTOR, ".note-item")
|
||||
)
|
||||
don_btn = note_item.find_element(By.CSS_SELECTOR, ".btn-equip")
|
||||
doff_btn = note_item.find_element(By.CSS_SELECTOR, ".btn-unequip")
|
||||
|
||||
# Initial state: DON active ("DON"), DOFF disabled ("×")
|
||||
self.assertNotIn("btn-disabled", don_btn.get_attribute("class"))
|
||||
self.assertEqual(don_btn.text, "DON")
|
||||
self.assertIn("btn-disabled", doff_btn.get_attribute("class"))
|
||||
self.assertEqual(doff_btn.text, "×")
|
||||
|
||||
# Click DON → greeting changes to the note title
|
||||
don_btn.click()
|
||||
self.wait_for(
|
||||
lambda: self.assertIn(
|
||||
"Stargazer",
|
||||
self.browser.find_element(By.ID, "id_greeting_name").text,
|
||||
)
|
||||
)
|
||||
self.assertIn("btn-disabled", don_btn.get_attribute("class"))
|
||||
self.assertEqual(don_btn.text, "×")
|
||||
self.assertNotIn("btn-disabled", doff_btn.get_attribute("class"))
|
||||
self.assertEqual(doff_btn.text, "DOFF")
|
||||
|
||||
# Click DOFF → greeting restored to "Earthman"
|
||||
doff_btn.click()
|
||||
self.wait_for(
|
||||
lambda: self.assertIn(
|
||||
"Earthman",
|
||||
self.browser.find_element(By.ID, "id_greeting_name").text,
|
||||
)
|
||||
)
|
||||
self.assertNotIn("btn-disabled", don_btn.get_attribute("class"))
|
||||
self.assertEqual(don_btn.text, "DON")
|
||||
self.assertIn("btn-disabled", doff_btn.get_attribute("class"))
|
||||
self.assertEqual(doff_btn.text, "×")
|
||||
|
||||
Reference in New Issue
Block a user