feat: document all products, write tests #12

Merged
naomi merged 4 commits from feat/many-docs into main 2025-10-29 18:55:40 -07:00
6 changed files with 99 additions and 17 deletions
Showing only changes of commit f540fe9581 - Show all commits
+17 -13
View File
@@ -27,7 +27,7 @@ export const navigation = [
label: "Mentorship Programme Terms and Conditions", label: "Mentorship Programme Terms and Conditions",
link: "/about/mentorship", link: "/about/mentorship",
}, },
], ].sort((a, b) => a.label.localeCompare(b.label)),
}, },
{ {
label: "Legal Information", label: "Legal Information",
@@ -46,7 +46,7 @@ export const navigation = [
link: "/legal/privacy", link: "/legal/privacy",
}, },
{ {
label: "Naomi's Public License", label: "Naomi's Public Licence",
link: "/legal/license", link: "/legal/license",
}, },
{ {
@@ -93,7 +93,7 @@ export const navigation = [
label: "Crisis and Mental Health Management Policy", label: "Crisis and Mental Health Management Policy",
link: "/legal/crisis-mental-health", link: "/legal/crisis-mental-health",
}, },
], ].sort((a, b) => a.label.localeCompare(b.label)),
}, },
{ {
label: "Community Policies", label: "Community Policies",
@@ -123,14 +123,14 @@ export const navigation = [
label: "Community Feedback and Participation Policy", label: "Community Feedback and Participation Policy",
link: "/community/feedback", link: "/community/feedback",
}, },
], ].sort((a, b) => a.label.localeCompare(b.label)),
}, },
{ {
label: "Development Documentation", label: "Development Documentation",
collapsed: true, collapsed: true,
items: [ items: [
{ {
label: "Contributing Guide", label: "Contributing Documentation",
link: "/dev/contributing", link: "/dev/contributing",
}, },
{ {
@@ -154,10 +154,14 @@ export const navigation = [
link: "/dev/servers", link: "/dev/servers",
}, },
{ {
label: "VTubing Setup", label: "Naomi's VTubing Setup",
link: "/dev/vtubing", link: "/dev/vtubing",
}, },
], {
label: "Security Hall of Fame",
link: "/dev/hall-of-fame",
}
].sort((a, b) => a.label.localeCompare(b.label)),
}, },
{ {
label: "Project Documentation", label: "Project Documentation",
@@ -224,7 +228,7 @@ export const navigation = [
badge: { text: "v0.0.0", variant: "danger" }, badge: { text: "v0.0.0", variant: "danger" },
}, },
{ {
label: "NHCarrigan Portfolio", label: "Portfolio",
link: "/projects/portfolio", link: "/projects/portfolio",
badge: { text: "unversioned", variant: "success" }, badge: { text: "unversioned", variant: "success" },
}, },
@@ -304,7 +308,7 @@ export const navigation = [
badge: { text: "v1.0.0", variant: "tip" }, badge: { text: "v1.0.0", variant: "tip" },
}, },
{ {
label: "Documentation Site", label: "NHCarrigan Documentation",
link: "/projects/docs", link: "/projects/docs",
badge: { text: "v1.0.0", variant: "tip" }, badge: { text: "v1.0.0", variant: "tip" },
}, },
@@ -519,7 +523,7 @@ export const navigation = [
badge: { text: "v1.0.0", variant: "tip" }, badge: { text: "v1.0.0", variant: "tip" },
}, },
{ {
label: "Art4Palestine Bot", label: "Artists4Palestine Bot",
link: "/projects/a4p-bot", link: "/projects/a4p-bot",
badge: { text: "v1.0.0", variant: "tip" }, badge: { text: "v1.0.0", variant: "tip" },
}, },
@@ -624,13 +628,13 @@ export const navigation = [
label: "Technical Contributor Training for Staff", label: "Technical Contributor Training for Staff",
link: "/staff/training/technical-contributor", link: "/staff/training/technical-contributor",
}, },
], ].sort((a, b) => a.label.localeCompare(b.label)),
}, },
{ {
label: "Staff Policy Self-Assessment", label: "Staff Policy Self-Assessment",
link: "/staff/policy-self-assessment", link: "/staff/policy-self-assessment",
}, },
], ].sort((a, b) => a.label.localeCompare(b.label)),
}, },
{ {
label: "Miscellaneous Documents", label: "Miscellaneous Documents",
@@ -640,7 +644,7 @@ export const navigation = [
label: "Managing Local Music", label: "Managing Local Music",
link: "/misc/music", link: "/misc/music",
}, },
], ].sort((a, b) => a.label.localeCompare(b.label)),
}, },
{ {
label: "Sitemap", label: "Sitemap",
+1 -1
View File
@@ -1,5 +1,5 @@
--- ---
title: nhcarrigan Contributor Covenant title: Contributor Covenant
--- ---
Copyright (C) 2024 nhcarrigan and its contributors. Copyright (C) 2024 nhcarrigan and its contributors.
+1 -1
View File
@@ -1,5 +1,5 @@
--- ---
title: Labels title: "Issue/PR Labels"
--- ---
We use very specific labels to help categorise our issues. This page explains what each label means. We use very specific labels to help categorise our issues. This page explains what each label means.
+1 -1
View File
@@ -1,5 +1,5 @@
--- ---
title: Downloading and Editing Music title: Managing Local Music
--- ---
This serves as our documentation for how we manage our local music libraries on Linux. This serves as our documentation for how we manage our local music libraries on Linux.
+79
View File
@@ -0,0 +1,79 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { readFile } from "node:fs/promises";
import { readdir } from "node:fs/promises";
import { join } from "node:path";
import { describe, expect, it } from "vitest";
import { navigation } from "../src/components/navigation.ts";
import matter from "gray-matter";
type Navigation = typeof navigation;
type NavigationItem = Array<{
label: string
link: string
items?: Array<{
label: string
link: string
}>
}>
const excludedFiles = ["intro.mdx", "projects/_template.md"];
// this should recursively walk the specified directory and return a list of all files, prefixing them with nested paths.
// For example, calling walkDirectory() should return "/about/contact.md", "/about/mission.md", "/about/sustainability.md", etc.
const walkDirectory = async (directory = join(__dirname, "..", "src", "content", "docs"), prefix = ""): Promise<Array<string>> => {
const filesAndDirectories = await readdir(directory, { withFileTypes: true });
const pages = [];
for (const fileOrDirectory of filesAndDirectories) {
if (fileOrDirectory.isDirectory()) {
pages.push(...(await walkDirectory(join(directory, fileOrDirectory.name), join(prefix, fileOrDirectory.name))));
} else {
pages.push(join(prefix, fileOrDirectory.name));
}
}
return pages;
}
const flattenNavigation = (navigation: Navigation | NavigationItem): Array<{ label: string; link: string }> => {
const items: Array<{ label: string; link: string }> = [];
for (const item of navigation) {
if ("items" in item && item.items) {
items.push(...flattenNavigation(item.items as NavigationItem));
} else {
items.push({ label: item.label, link: item.link });
}
}
return items;
}
describe("navigation", () => {
it("should include all pages", async () => {
expect.hasAssertions();
let pages = await walkDirectory();
pages = pages.filter((page) => !excludedFiles.includes(page));
const flattenedNavigation = flattenNavigation(navigation);
for (const page of pages) {
const pageName = page.split(".")[0];
const navItem = flattenedNavigation.find((item) => item.link === `/${pageName}`);
expect(navItem, `Navigation item not found for page ${page}`).toBeDefined();
}
});
it("should use page titles as navigation item labels", async () => {
expect.hasAssertions();
let pages = await walkDirectory();
pages = pages.filter((page) => !excludedFiles.includes(page));
const flattenedNavigation = flattenNavigation(navigation);
for (const page of pages) {
const pageName = page.split(".")[0];
const navItem = flattenedNavigation.find((item) => item.link === `/${pageName}`);
const pageContent = await readFile(join(__dirname, "..", "src", "content", "docs", page), "utf-8");
const { data } = matter(pageContent);
expect(navItem?.label, `Navigation item label for ${pageName} is not correct`).toBe(data.title);
}
});
});
-1
View File
@@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/naming-convention -- We are dealing with repository names, which are in kebab-case */
/** /**
* @copyright NHCarrigan * @copyright NHCarrigan
* @license Naomi's Public License * @license Naomi's Public License