From d5ebbab6a56228b86d2eb0ea30f172271e580651 Mon Sep 17 00:00:00 2001
From: th
Date: Wed, 15 Apr 2026 21:53:49 +0200
Subject: [PATCH] tests: assert journal entries don't get the local pulse
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Covers the board.js journal exemption on the 1× card-pulse-local
flash. Creates two probe cards via the raw API, flags both as
"just created locally" in state.recentlyCreatedIds, runs a render,
then asserts that the journal-format one (title 9999-12-31 — a
year we can't collide with real entries) skipped the pulse class
while the __prefixed__ control card still got it.
Both probes are deleted in a finally block so a failed assertion
doesn't leave them behind for later suites.
Co-Authored-By: Claude Opus 4.6 (1M context)
---
public/plugins/tests/board.test.js | 47 ++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/public/plugins/tests/board.test.js b/public/plugins/tests/board.test.js
index 22df825..687947e 100644
--- a/public/plugins/tests/board.test.js
+++ b/public/plugins/tests/board.test.js
@@ -184,3 +184,50 @@ describe('Board: Focus restoration after overlay close', () => {
expect(document.querySelector('#board .card-focused')).toExist();
});
});
+
+describe('Board: new-card pulse', () => {
+ // Journal entries shouldn't get the 1× card-pulse-local flash —
+ // they're daily-log jottings, not "new thing" moments. We use
+ // title "9999-12-31" for the journal probe to ensure we can't
+ // collide with a real user entry; a control card with a
+ // __prefixed__ title verifies the pulse still fires for normal
+ // local creations.
+
+ it('locally-created journal-format cards skip the pulse', async () => {
+ const token = csrf();
+ const hJson = { 'Content-Type': 'application/json', 'X-CSRF-Token': token };
+ const hCsrf = { 'X-CSRF-Token': token };
+ let journal, control;
+ try {
+ journal = await fetch('api/cards', { method: 'POST', headers: hJson, body: JSON.stringify({ title: '9999-12-31', body: '' }) }).then(r => r.json());
+ control = await fetch('api/cards', { method: 'POST', headers: hJson, body: JSON.stringify({ title: '__test_pulse_ctrl__', body: '' }) }).then(r => r.json());
+ expect(journal?.id).toExist();
+ expect(control?.id).toExist();
+
+ // Flag both as "just created locally" so renderBoard routes
+ // them through the local-pulse branch. The journal
+ // exemption then has to filter out the journal one.
+ window.state.recentlyCreatedIds.add(String(journal.id));
+ window.state.recentlyCreatedIds.add(String(control.id));
+ await window._reloadAll();
+ // Wait past the rAF tick so pulse classes have been
+ // applied, but well within the 900ms lifetime so we
+ // can still observe them.
+ await sleep(150);
+
+ const journalEl = document.querySelector(`.board-card[data-id="${journal.id}"]`);
+ const controlEl = document.querySelector(`.board-card[data-id="${control.id}"]`);
+ expect(journalEl).toExist();
+ expect(controlEl).toExist();
+ expect(journalEl.classList.contains('card-pulse-local')).toBe(false);
+ expect(controlEl.classList.contains('card-pulse-local')).toBe(true);
+ } finally {
+ // Clean up even on failure. Backup/restore would catch it
+ // eventually, but between tests we don't want a stray
+ // 9999-12-31 card floating around upsetting other suites.
+ if (journal?.id) await fetch(`api/cards/${journal.id}`, { method: 'DELETE', headers: hCsrf });
+ if (control?.id) await fetch(`api/cards/${control.id}`, { method: 'DELETE', headers: hCsrf });
+ await window._reloadAll?.();
+ }
+ });
+});
|