diff --git a/src/app.js b/src/app.js index 46dd724..121e9aa 100644 --- a/src/app.js +++ b/src/app.js @@ -67,13 +67,13 @@ function render() { const label = document.createElement("span"); label.className = "task-title"; - label.textContent = task.title; + label.append(document.createTextNode(task.title)); const del = document.createElement("button"); del.type = "button"; del.className = "task-delete"; del.textContent = "โœ•"; - del.setAttribute("aria-label", `Delete task: ${task.title}`); + del.setAttribute("aria-label", "Delete task"); del.addEventListener("click", async () => { tasks = removeTask(tasks, task.id); await save(tasks, user); diff --git a/test/server.test.js b/test/server.test.js index c3b9f65..3c89dd6 100644 --- a/test/server.test.js +++ b/test/server.test.js @@ -19,6 +19,27 @@ test("sanitizeTasks drops malformed rows and trims persisted fields", () => { ); }); +test("sanitizeTasks preserves complex emoji title sequences", () => { + assert.deepEqual( + sanitizeTasks([ + { + id: "emoji", + title: "Plan trip ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ", + done: false, + createdAt: 20, + }, + ]), + [ + { + id: "emoji", + title: "Plan trip ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ", + done: false, + createdAt: 20, + }, + ], + ); +}); + test("GitHub OAuth exchange sets an HTTP-only session cookie without exposing tokens", async () => { const previousClientId = process.env.GITHUB_CLIENT_ID; process.env.GITHUB_CLIENT_ID = "client-id";