Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
Blame · Line-by-line history

sse-client.test.ts

Each line is annotated with the commit that last touched it. Click any SHA to jump to that commit and see the surrounding change.

sse-client.test.tsBlame80 lines · 1 contributor
febd4f0Claude1import { describe, it, expect } from "bun:test";
b584e52Claude2import {
3 liveSubscribeScript,
4 liveCommentBannerScript,
5} from "../lib/sse-client";
febd4f0Claude6
7describe("liveSubscribeScript", () => {
8 it("returns a string containing EventSource and the topic path", () => {
9 const js = liveSubscribeScript({
10 topic: "repo:abc",
11 targetElementId: "live-feed",
12 });
13
14 expect(typeof js).toBe("string");
15 expect(js).toContain("EventSource");
16 // topic is JSON-encoded then concatenated with the /live-events/ prefix
17 // at runtime, so both must appear in the emitted script.
18 expect(js).toContain("/live-events/");
19 expect(js).toContain('"repo:abc"');
20 // targetElementId must also be JSON-escaped into the snippet.
21 expect(js).toContain('"live-feed"');
22 });
23
24 it("JSON-escapes bad topic strings to prevent </script> injection", () => {
25 const malicious = '</script><script>alert(1)</script>';
26 const js = liveSubscribeScript({
27 topic: malicious,
28 targetElementId: "feed",
29 });
30
31 // Raw closing-tag sequence MUST NOT appear anywhere in the output —
32 // JSON.stringify escapes `<` when emitted for HTML, but we additionally
33 // verify the literal bad sequence is absent.
34 expect(js).not.toContain("</script>");
35 // Unescaped alert call (in the exact bad form) must not appear.
36 expect(js).not.toContain("<script>alert(1)");
37 // The topic should still be represented (escaped) so the subscription
38 // remains functional — at minimum the inner `alert(1)` literal is there
39 // as an escaped JSON string, but the HTML-breakout is gone.
40 expect(js).toContain("EventSource");
41 });
42});
b584e52Claude43
44describe("liveCommentBannerScript", () => {
45 it("emits a self-invoking IIFE that opens an EventSource", () => {
46 const js = liveCommentBannerScript({
47 topic: "repo:r1:issue:7",
48 bannerElementId: "live-comment-banner",
49 });
50 expect(typeof js).toBe("string");
51 expect(js).toContain("EventSource");
52 expect(js).toContain("/live-events/");
53 expect(js).toContain('"repo:r1:issue:7"');
54 expect(js).toContain('"live-comment-banner"');
55 // Counter increment + show contract.
56 expect(js).toContain("n++");
57 expect(js).toContain("js-live-count");
58 expect(js).toContain("js-live-link");
59 });
60
61 it("escapes topic strings to prevent </script> injection", () => {
62 const malicious = '</script><script>alert(1)</script>';
63 const js = liveCommentBannerScript({
64 topic: malicious,
65 bannerElementId: "banner",
66 });
67 expect(js).not.toContain("</script>");
68 expect(js).not.toContain("<script>alert(1)");
69 expect(js).toContain("EventSource");
70 });
71
72 it("uses the current location for the reload link", () => {
73 const js = liveCommentBannerScript({
74 topic: "repo:r1:pr:9",
75 bannerElementId: "banner",
76 });
77 // Must reference window.location so a click reloads the same page.
78 expect(js).toContain("window.location");
79 });
80});