alepha
Version:
Easy-to-use modern TypeScript framework for building many kind of applications.
197 lines (158 loc) • 6.01 kB
text/typescript
import { Alepha } from "alepha";
import { beforeEach, describe, expect, it } from "vitest";
import type { Head } from "../interfaces/Head.ts";
import { BrowserHeadProvider } from "../providers/BrowserHeadProvider.ts";
describe("BrowserHeadProvider", () => {
let alepha: Alepha;
let provider: BrowserHeadProvider;
beforeEach(async () => {
alepha = Alepha.create();
provider = alepha.inject(BrowserHeadProvider);
// Reset document state
document.title = "";
document.head.innerHTML = "";
document.body.removeAttribute("class");
document.body.removeAttribute("style");
document.documentElement.removeAttribute("lang");
document.documentElement.removeAttribute("class");
});
describe("getHead", () => {
it("should return current document head state", () => {
document.title = "Test Title";
document.body.setAttribute("class", "test-class");
document.documentElement.setAttribute("lang", "en");
const meta = document.createElement("meta");
meta.setAttribute("name", "description");
meta.setAttribute("content", "Test description");
document.head.appendChild(meta);
const head = provider.getHead(document);
expect(head.title).toBe("Test Title");
expect(head.bodyAttributes?.class).toBe("test-class");
expect(head.htmlAttributes?.lang).toBe("en");
expect(head.meta).toContainEqual({
name: "description",
content: "Test description",
});
});
it("should handle empty document state", () => {
const head = provider.getHead(document);
expect(head.title).toBe("");
expect(head.bodyAttributes).toEqual({});
expect(head.htmlAttributes).toEqual({});
expect(head.meta).toEqual([]);
});
});
describe("renderHead", () => {
it("should set document title", () => {
const head: Head = { title: "New Title" };
provider.renderHead(document, head);
expect(document.title).toBe("New Title");
});
it("should set body attributes", () => {
const head: Head = {
bodyAttributes: {
class: "new-class",
style: "background: blue;",
},
};
provider.renderHead(document, head);
expect(document.body.getAttribute("class")).toBe("new-class");
expect(document.body.getAttribute("style")).toBe("background: blue;");
});
it("should remove body attributes when value is falsy", () => {
document.body.setAttribute("class", "old-class");
const head: Head = {
bodyAttributes: {
class: "",
},
};
provider.renderHead(document, head);
expect(document.body.hasAttribute("class")).toBe(false);
});
it("should set html attributes", () => {
const head: Head = {
htmlAttributes: {
lang: "fr",
dir: "ltr",
},
};
provider.renderHead(document, head);
expect(document.documentElement.getAttribute("lang")).toBe("fr");
expect(document.documentElement.getAttribute("dir")).toBe("ltr");
});
it("should remove html attributes when value is falsy", () => {
document.documentElement.setAttribute("lang", "en");
const head: Head = {
htmlAttributes: {
lang: "",
},
};
provider.renderHead(document, head);
expect(document.documentElement.hasAttribute("lang")).toBe(false);
});
it("should create new meta tags", () => {
const head: Head = {
meta: [
{ name: "description", content: "Test description" },
{ name: "keywords", content: "test, browser" },
],
};
provider.renderHead(document, head);
const descriptionMeta = document.querySelector(
'meta[name="description"]',
);
const keywordsMeta = document.querySelector('meta[name="keywords"]');
expect(descriptionMeta?.getAttribute("content")).toBe("Test description");
expect(keywordsMeta?.getAttribute("content")).toBe("test, browser");
});
it("should update existing meta tags", () => {
// Pre-populate with existing meta tag
const existingMeta = document.createElement("meta");
existingMeta.setAttribute("name", "description");
existingMeta.setAttribute("content", "Old description");
document.head.appendChild(existingMeta);
const head: Head = {
meta: [{ name: "description", content: "New description" }],
};
provider.renderHead(document, head);
const descriptionMeta = document.querySelector(
'meta[name="description"]',
);
expect(descriptionMeta?.getAttribute("content")).toBe("New description");
expect(
document.querySelectorAll('meta[name="description"]'),
).toHaveLength(1);
});
it("should handle complete head object", () => {
const head: Head = {
title: "Complete Test",
htmlAttributes: {
lang: "es",
class: "theme-dark",
},
bodyAttributes: {
class: "page-test",
"data-theme": "dark",
},
meta: [
{ name: "description", content: "Complete test page" },
{ name: "author", content: "Test Author" },
],
};
provider.renderHead(document, head);
expect(document.title).toBe("Complete Test");
expect(document.documentElement.getAttribute("lang")).toBe("es");
expect(document.documentElement.getAttribute("class")).toBe("theme-dark");
expect(document.body.getAttribute("class")).toBe("page-test");
expect(document.body.getAttribute("data-theme")).toBe("dark");
const descriptionMeta = document.querySelector(
'meta[name="description"]',
);
const authorMeta = document.querySelector('meta[name="author"]');
expect(descriptionMeta?.getAttribute("content")).toBe(
"Complete test page",
);
expect(authorMeta?.getAttribute("content")).toBe("Test Author");
});
});
});