generated from nhcarrigan/template
191 lines
6.2 KiB
TypeScript
191 lines
6.2 KiB
TypeScript
/* eslint-disable @typescript-eslint/naming-convention -- We are dealing with repository names, which are in kebab-case */
|
|
/**
|
|
* @copyright NHCarrigan
|
|
* @license Naomi's Public License
|
|
* @author Naomi Carrigan
|
|
*/
|
|
|
|
import { readFile } from "node:fs/promises";
|
|
import { join } from "node:path";
|
|
import { describe, expect, it } from "vitest";
|
|
import { parse } from "yaml";
|
|
import type { Projects } from "../src/interfaces/projects.js";
|
|
|
|
interface Repository {
|
|
id: number;
|
|
owner: {
|
|
id: number;
|
|
login: string;
|
|
login_name: string;
|
|
source_id: number;
|
|
full_name: string;
|
|
email: string;
|
|
avatar_url: string;
|
|
html_url: string;
|
|
language: string;
|
|
is_admin: boolean;
|
|
last_login: string;
|
|
created: string;
|
|
restricted: boolean;
|
|
active: boolean;
|
|
prohibit_login: boolean;
|
|
location: string;
|
|
website: string;
|
|
description: string;
|
|
visibility: string;
|
|
followers_count: number;
|
|
following_count: number;
|
|
starred_repos_count: number;
|
|
username: string;
|
|
};
|
|
name: string;
|
|
full_name: string;
|
|
description: string;
|
|
empty: boolean;
|
|
private: boolean;
|
|
fork: boolean;
|
|
template: boolean;
|
|
mirror: boolean;
|
|
size: number;
|
|
language: string;
|
|
languages_url: string;
|
|
html_url: string;
|
|
url: string;
|
|
link: string;
|
|
ssh_url: string;
|
|
clone_url: string;
|
|
original_url: string;
|
|
website: string;
|
|
stars_count: number;
|
|
forks_count: number;
|
|
watchers_count: number;
|
|
open_issues_count: number;
|
|
open_pr_counter: number;
|
|
release_counter: number;
|
|
default_branch: string;
|
|
archived: boolean;
|
|
created_at: string;
|
|
updated_at: string;
|
|
archived_at: string;
|
|
permissions: {
|
|
admin: boolean;
|
|
push: boolean;
|
|
pull: boolean;
|
|
};
|
|
has_issues: boolean;
|
|
internal_tracker: {
|
|
enable_time_tracker: boolean;
|
|
allow_only_contributors_to_track_time: boolean;
|
|
enable_issue_dependencies: boolean;
|
|
};
|
|
has_wiki: boolean;
|
|
has_pull_requests: boolean;
|
|
has_projects: boolean;
|
|
projects_mode: string;
|
|
has_releases: boolean;
|
|
has_packages: boolean;
|
|
has_actions: boolean;
|
|
ignore_whitespace_conflicts: boolean;
|
|
allow_merge_commits: boolean;
|
|
allow_rebase: boolean;
|
|
allow_rebase_explicit: boolean;
|
|
allow_squash_merge: boolean;
|
|
allow_fast_forward_only_merge: boolean;
|
|
allow_rebase_update: boolean;
|
|
default_delete_branch_after_merge: boolean;
|
|
default_merge_style: string;
|
|
default_allow_maintainer_edit: boolean;
|
|
avatar_url: string;
|
|
internal: boolean;
|
|
mirror_interval: string;
|
|
object_format_name: string;
|
|
mirror_updated: string;
|
|
topics: Array<unknown>;
|
|
licenses: Array<unknown>;
|
|
}
|
|
const getRepositories = async(): Promise<Array<Repository>> => {
|
|
const repos: Array<Repository> = [];
|
|
const orgs = [
|
|
"nhcarrigan",
|
|
"nhcarrigan-games",
|
|
];
|
|
for (const org of orgs) {
|
|
const response = await fetch(`https://git.nhcarrigan.com/api/v1/orgs/${org}/repos?limit=50`);
|
|
const data = await response.json();
|
|
repos.push(...data);
|
|
if (data.length === 50) {
|
|
let page = 2;
|
|
while (true) {
|
|
const responseInner = await fetch(`https://git.nhcarrigan.com/api/v1/orgs/${org}/repos?limit=50&page=${page}`);
|
|
const dataInner = await responseInner.json();
|
|
repos.push(...dataInner);
|
|
if (dataInner.length < 50) {
|
|
break;
|
|
}
|
|
page = page + 1;
|
|
}
|
|
}
|
|
}
|
|
return repos;
|
|
};
|
|
|
|
const repoNameMap = {
|
|
"a4p-bot": "Artists4Palestine Bot",
|
|
"beccalia-origins": "Beccalia: Origins",
|
|
"beccalia-prologue": "Beccalia: Prologue",
|
|
"blog": "Naomi's Blog",
|
|
"data": "Data API",
|
|
"docs": "NHCarrigan Documentation",
|
|
"eslint-config": "ESLint Config",
|
|
"fcc-review-generator": "freeCodeCamp Review Generator",
|
|
"life-of-a-naomi": "Life of a Naomi",
|
|
"naomis-adventure-1": "Naomi's Adventure I: An Isekai Story",
|
|
"ruu-goblin-quest": "Ruu's Goblin Quest",
|
|
"typescript-config": "TypeScript Config",
|
|
"vscode-themes": "Naomi's VSCode Themes",
|
|
};
|
|
|
|
const excludedRepos = new Set<string>([
|
|
"template",
|
|
"espanso",
|
|
"rig-task-bot",
|
|
"security",
|
|
"nginx-configs",
|
|
".profile",
|
|
".gitea",
|
|
"womp-womp",
|
|
"sakura",
|
|
]);
|
|
|
|
const convertKebabCaseToTitleCase = (string_: string): string => {
|
|
return string_.replaceAll("-", " ").replaceAll(/\b\w/g, (char) => {
|
|
return char.toUpperCase();
|
|
});
|
|
};
|
|
|
|
describe("projects data", () => {
|
|
it("should include all repositories", async() => {
|
|
expect.hasAssertions();
|
|
const repos = await getRepositories();
|
|
const data = await readFile(
|
|
join(import.meta.dirname, "..", "data", "projects.yml"),
|
|
"utf8",
|
|
);
|
|
const parsed = parse(data) as Projects;
|
|
expect(parsed, `Parsed projects data should be defined`).toBeDefined();
|
|
expect(Array.isArray(parsed), `Parsed projects data should be an array`).toBeTruthy();
|
|
expect(parsed.length, `There should be at least one project`).toBeGreaterThan(0);
|
|
for (const repo of repos) {
|
|
if (excludedRepos.has(repo.name)) {
|
|
continue;
|
|
}
|
|
const project = parsed.find((p) => {
|
|
return repo.name in repoNameMap
|
|
? p.name === repoNameMap[repo.name]
|
|
: p.name === convertKebabCaseToTitleCase(repo.name);
|
|
});
|
|
expect(project, `Project should be defined for repository ${convertKebabCaseToTitleCase(repo.name)}`).toBeDefined();
|
|
}
|
|
});
|
|
});
|