|
1 | | -import { describe, it, expect, beforeEach, afterEach, vi } from "vitest"; |
| 1 | +import { describe, it, expect, beforeEach, beforeAll, afterEach, vi } from "vitest"; |
2 | 2 |
|
3 | 3 | describe("sanitize_content.cjs", () => { |
4 | 4 | let mockCore; |
@@ -2751,4 +2751,43 @@ describe("sanitize_content.cjs", () => { |
2751 | 2751 | expect(result).toContain("\\{\\{"); // template escaped |
2752 | 2752 | }); |
2753 | 2753 | }); |
| 2754 | + |
| 2755 | + describe("parity: sanitizeContent alias-branch vs sanitizeContentCore for template syntax (regression)", () => { |
| 2756 | + // Regression guard: sanitizeContent with allowedAliases must produce the same |
| 2757 | + // template-delimiter escaping as sanitizeContentCore. In v0.68.3 this parity was |
| 2758 | + // broken because the alias branch did not call neutralizeTemplateDelimiters. |
| 2759 | + // |
| 2760 | + // Parity verification is the right level of abstraction here: if the alias branch |
| 2761 | + // ever stops calling neutralizeTemplateDelimiters (or any equivalent escaping step), |
| 2762 | + // its output will contain raw template syntax while sanitizeContentCore output will |
| 2763 | + // have it escaped, causing these tests to fail and exposing the regression. |
| 2764 | + let sanitizeContentCore; |
| 2765 | + |
| 2766 | + beforeAll(async () => { |
| 2767 | + const coreModule = await import("./sanitize_content_core.cjs"); |
| 2768 | + sanitizeContentCore = coreModule.sanitizeContentCore; |
| 2769 | + }); |
| 2770 | + |
| 2771 | + const templateParityInputs = [ |
| 2772 | + { name: "Jinja2/Liquid double braces", input: "Result: {{ secret.token }}" }, |
| 2773 | + { name: "JavaScript template literal", input: "Value: ${ expression }" }, |
| 2774 | + { name: "Jekyll/Liquid directive", input: "{% if condition %}value{% endif %}" }, |
| 2775 | + { name: "ERB delimiter", input: "<%= config.adminToken %>" }, |
| 2776 | + { name: "Jinja2 comment", input: "{# this is a comment #}" }, |
| 2777 | + { |
| 2778 | + name: "all five patterns together", |
| 2779 | + input: "{{ var }}, ${ js }, {% tag %}, <%= erb %>, {# comment #}", |
| 2780 | + }, |
| 2781 | + ]; |
| 2782 | + |
| 2783 | + for (const { name, input } of templateParityInputs) { |
| 2784 | + it(`alias-branch and core produce identical template escaping for: ${name}`, async () => { |
| 2785 | + // Use an alias that will never match any mention in the input so the alias |
| 2786 | + // branch code-path is exercised without altering mention escaping. |
| 2787 | + const aliasResult = sanitizeContent(input, { allowedAliases: ["nobody"] }); |
| 2788 | + const coreResult = sanitizeContentCore(input); |
| 2789 | + expect(aliasResult).toBe(coreResult); |
| 2790 | + }); |
| 2791 | + } |
| 2792 | + }); |
2754 | 2793 | }); |
0 commit comments