diff --git a/packages/core/src/lint/rules/fonts.test.ts b/packages/core/src/lint/rules/fonts.test.ts
index 6e28c881a0..853781bd74 100644
--- a/packages/core/src/lint/rules/fonts.test.ts
+++ b/packages/core/src/lint/rules/fonts.test.ts
@@ -8,21 +8,24 @@ async function findByCode(html: string, code: string, isSubComposition = true) {
describe("font rules", () => {
describe("google_fonts_import", () => {
- it("flags @import url with fonts.googleapis.com", async () => {
+ it("warns on @import url with fonts.googleapis.com without failing lint", async () => {
const html = `
`;
- const findings = await findByCode(html, "google_fonts_import");
+ const result = await lintHyperframeHtml(html, { isSubComposition: true });
+ const findings = result.findings.filter((f) => f.code === "google_fonts_import");
expect(findings).toHaveLength(1);
- expect(findings[0]!.severity).toBe("error");
+ expect(findings[0]!.severity).toBe("warning");
+ expect(result.errorCount).toBe(0);
});
- it("flags to fonts.googleapis.com", async () => {
+ it("warns on to fonts.googleapis.com", async () => {
const html = `
`;
const findings = await findByCode(html, "google_fonts_import");
expect(findings).toHaveLength(1);
+ expect(findings[0]!.severity).toBe("warning");
});
it("does not flag local @font-face usage", async () => {
@@ -185,6 +188,58 @@ describe("font rules", () => {
expect(findings[0]!.message).toContain("geist");
});
+ it("does not flag a non-bundled family when a Google Fonts link loads it", async () => {
+ const html = `
+
+
+
`;
+ const result = await lintHyperframeHtml(html, { isSubComposition: true });
+ expect(result.findings.filter((f) => f.code === "google_fonts_import")).toHaveLength(1);
+ expect(
+ result.findings.filter((f) => f.code === "font_family_without_font_face"),
+ ).toHaveLength(0);
+ expect(result.errorCount).toBe(0);
+ });
+
+ it("parses unquoted Google Fonts link href values", async () => {
+ const html = `
+
+
+
`;
+ const result = await lintHyperframeHtml(html, { isSubComposition: true });
+ expect(result.findings.filter((f) => f.code === "google_fonts_import")).toHaveLength(1);
+ expect(
+ result.findings.filter((f) => f.code === "font_family_without_font_face"),
+ ).toHaveLength(0);
+ expect(result.errorCount).toBe(0);
+ });
+
+ it("parses multiple Google Fonts family parameters and URL-encoded spaces", async () => {
+ const html = `
+
+
`;
+ const result = await lintHyperframeHtml(html, { isSubComposition: true });
+ expect(result.findings.filter((f) => f.code === "google_fonts_import")).toHaveLength(1);
+ expect(
+ result.findings.filter((f) => f.code === "font_family_without_font_face"),
+ ).toHaveLength(0);
+ expect(result.errorCount).toBe(0);
+ });
+
+ it("still flags non-bundled families not covered by the Google Fonts URL", async () => {
+ const html = `
+
+
+
`;
+ const findings = await findByCode(html, "font_family_without_font_face");
+ expect(findings).toHaveLength(1);
+ expect(findings[0]!.message).toContain("geist");
+ });
+
it("is case-insensitive when matching @font-face to font-family", async () => {
const html = `