feat: Implement Keycloak authentication and a basic CMS
Integrates Keycloak for secure administrator authentication using Arctic. Introduces a full CMS dashboard for managing CV content, supporting multi-language editing for profile, experience, and education sections. Refactors application routes for modularity and adds initial unit tests for database queries. Also includes minor UI/UX refinements, animation setup, and local Keycloak docker-compose configuration. Fixes: - Corrected KeyCloak import. - Restored missing getEducation function. - Ensured proper HTTP redirects. - Fixed PKCE code verifier length.
This commit is contained in:
53
tests/db.test.ts
Normal file
53
tests/db.test.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { describe, expect, it, beforeAll } from "bun:test";
|
||||
import { getAllData, getProfile, getExperience } from "../src/db/queries";
|
||||
import { initDB, db } from "../src/db/schema";
|
||||
import { seedDB } from "../src/db/seed";
|
||||
|
||||
// Use an in-memory DB or a separate test DB file for isolation
|
||||
// For simplicity in this specific setup, we are testing against the existing file
|
||||
// or re-seeding it. In a CI env, we'd use ':memory:'.
|
||||
// Let's ensure the DB is seeded before testing.
|
||||
beforeAll(() => {
|
||||
seedDB();
|
||||
});
|
||||
|
||||
describe("Database Queries", () => {
|
||||
it("should fetch English profile data correctly", () => {
|
||||
const profile = getProfile("en");
|
||||
expect(profile).not.toBeNull();
|
||||
expect(profile?.name).toBe("John Doe");
|
||||
expect(profile?.job_title).toBe("Full Stack Developer");
|
||||
});
|
||||
|
||||
it("should fetch German profile data correctly", () => {
|
||||
const profile = getProfile("de");
|
||||
expect(profile).not.toBeNull();
|
||||
expect(profile?.name).toBe("John Doe");
|
||||
expect(profile?.job_title).toBe("Full Stack Entwickler"); // Translation check
|
||||
});
|
||||
|
||||
it("should fetch experience sorted by order", () => {
|
||||
const experience = getExperience("en");
|
||||
expect(Array.isArray(experience)).toBe(true);
|
||||
if (experience.length > 0) {
|
||||
expect(experience[0]).toHaveProperty("company_name");
|
||||
expect(experience[0]).toHaveProperty("role");
|
||||
}
|
||||
});
|
||||
|
||||
it("getAllData should return all sections", () => {
|
||||
const data = getAllData("en");
|
||||
expect(data).toHaveProperty("profile");
|
||||
expect(data).toHaveProperty("experience");
|
||||
expect(data).toHaveProperty("education");
|
||||
expect(data).toHaveProperty("skills");
|
||||
});
|
||||
|
||||
it("should return null/empty for non-existent language", () => {
|
||||
// Our query logic returns null if the join fails usually,
|
||||
// but let's see how the current implementation behaves with invalid input.
|
||||
const profile = getProfile("fr");
|
||||
// Depending on implementation, this might be null or undefined
|
||||
expect(profile).toBeNull();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user