security and accessibility pass

This commit is contained in:
2025-05-07 22:15:29 +01:00
parent 6e01777678
commit 3604e0a889
5 changed files with 386 additions and 4 deletions

View File

@@ -0,0 +1,65 @@
import { describe, it, expect } from "vitest";
import { cn, getDifficultyColor, getDifficultyLabel, capitalize } from "./utils";
describe("cn", () => {
it("joins multiple class names", () => {
expect(cn("foo", "bar")).toBe("foo bar");
});
it("filters out falsy values", () => {
expect(cn("foo", undefined, false, "bar")).toBe("foo bar");
});
it("returns empty string for no classes", () => {
expect(cn()).toBe("");
});
});
describe("getDifficultyColor", () => {
it("returns easy difficulty CSS variable classes", () => {
const result = getDifficultyColor("easy");
expect(result).toContain("--difficulty-easy");
});
it("returns medium difficulty CSS variable classes", () => {
const result = getDifficultyColor("medium");
expect(result).toContain("--difficulty-medium");
});
it("returns hard difficulty CSS variable classes", () => {
const result = getDifficultyColor("hard");
expect(result).toContain("--difficulty-hard");
});
});
describe("getDifficultyLabel", () => {
it("returns accessible label for easy", () => {
expect(getDifficultyLabel("easy")).toBe("Easy difficulty");
});
it("returns accessible label for medium", () => {
expect(getDifficultyLabel("medium")).toBe("Medium difficulty");
});
it("returns accessible label for hard", () => {
expect(getDifficultyLabel("hard")).toBe("Hard difficulty");
});
});
describe("capitalize", () => {
it("capitalizes first letter", () => {
expect(capitalize("hello")).toBe("Hello");
});
it("handles already capitalized strings", () => {
expect(capitalize("Hello")).toBe("Hello");
});
it("handles single character", () => {
expect(capitalize("a")).toBe("A");
});
it("handles empty string", () => {
expect(capitalize("")).toBe("");
});
});

View File

@@ -7,11 +7,22 @@ export function cn(...classes: (string | undefined | false)[]): string {
export function getDifficultyColor(difficulty: Difficulty): string {
switch (difficulty) {
case "easy":
return "text-green-600 bg-green-100 dark:text-green-400 dark:bg-green-900/30";
return "text-[var(--difficulty-easy)] bg-[var(--difficulty-easy-bg)]";
case "medium":
return "text-yellow-600 bg-yellow-100 dark:text-yellow-400 dark:bg-yellow-900/30";
return "text-[var(--difficulty-medium)] bg-[var(--difficulty-medium-bg)]";
case "hard":
return "text-red-600 bg-red-100 dark:text-red-400 dark:bg-red-900/30";
return "text-[var(--difficulty-hard)] bg-[var(--difficulty-hard-bg)]";
}
}
export function getDifficultyLabel(difficulty: Difficulty): string {
switch (difficulty) {
case "easy":
return "Easy difficulty";
case "medium":
return "Medium difficulty";
case "hard":
return "Hard difficulty";
}
}