Repository: JoshuaKGoldberg/template-typescript-node-package
Pull request #536 (2023-06-14 19:55:23)

test: added a few new test files
## PR Checklist

- [x] Addresses an existing open issue: makes progress on #471
- [x] That issue was marked as [`status: accepting prs`](https://github.com/JoshuaKGoldberg/template-typescript-node-package/issues?q=is%3Aopen+is%3Aissue+label%3A%22status%3A+accepting+prs%22)
- [x] Steps in [CONTRIBUTING.md](https://github.com/JoshuaKGoldberg/template-typescript-node-package/blob/main/.github/CONTRIBUTING.md) were taken

## Overview

Adds a trio of test files. Doesn't exhaustively increase coverage (I want to leave that open to future contributors!), but hopefully gets us to a nicer green coverage badge in the README.md


Patch:
diff --git a/src/shared/defaults.ts b/src/shared/getDefaultSettings.ts
similarity index 100%
rename from src/shared/defaults.ts
rename to src/shared/getDefaultSettings.ts
diff --git a/src/shared/inputs.ts b/src/shared/inputs.ts
index b031ae4..e8c2ed3 100644
--- a/src/shared/inputs.ts
+++ b/src/shared/inputs.ts
@@ -3,8 +3,8 @@ import { Octokit } from "octokit";
 import { titleCase } from "title-case";
 
 import { PrefillPrompter } from "./PrefillPrompter.js";
-import { getDefaultSettings } from "./defaults.js";
 import { ensureRepositoryExists } from "./ensureRepositoryExists.js";
+import { getDefaultSettings } from "./getDefaultSettings.js";
 import { getOctokit } from "./getOctokit.js";
 import { optionalDefault } from "./optionalDefault.js";
 


Test patch:
diff --git a/src/setup/steps/hydrateBranchProtectionSettings.test.ts b/src/setup/steps/hydrateBranchProtectionSettings.test.ts
new file mode 100644
index 0000000..0471d32
--- /dev/null
+++ b/src/setup/steps/hydrateBranchProtectionSettings.test.ts
@@ -0,0 +1,36 @@
+import { Octokit } from "octokit";
+import { SpyInstance, describe, expect, it, vi } from "vitest";
+
+import { hydrateBranchProtectionSettings } from "./hydrateBranchProtectionSettings.js";
+
+const createMockOctokit = (request: SpyInstance) =>
+	({
+		request,
+	} as unknown as Octokit);
+
+const stubValues = { owner: "", repository: "" };
+
+describe("hydrateBranchProtectionSettings", () => {
+	it("returns false when the request receives a 403 response", async () => {
+		const mockRequest = vi.fn().mockRejectedValue({ status: 403 });
+
+		const actual = await hydrateBranchProtectionSettings(
+			createMockOctokit(mockRequest),
+			stubValues
+		);
+
+		expect(actual).toBe(false);
+	});
+
+	it("throws the error when the request throws with a non-403 response", async () => {
+		const error = { status: 404 };
+		const mockRequest = vi.fn().mockRejectedValue(error);
+
+		await expect(() =>
+			hydrateBranchProtectionSettings(
+				createMockOctokit(mockRequest),
+				stubValues
+			)
+		).rejects.toBe(error);
+	});
+});
diff --git a/src/setup/steps/labels/hydrateRepositoryLabels.test.ts b/src/setup/steps/labels/hydrateRepositoryLabels.test.ts
new file mode 100644
index 0000000..a0d12d7
--- /dev/null
+++ b/src/setup/steps/labels/hydrateRepositoryLabels.test.ts
@@ -0,0 +1,111 @@
+import { describe, expect, it, vi } from "vitest";
+
+import { hydrateRepositoryLabels } from "./hydrateRepositoryLabels.js";
+
+const mock$ = vi.fn();
+
+vi.mock("execa", () => ({
+	get $() {
+		return mock$;
+	},
+}));
+
+const mockReadFileAsJson = vi.fn().mockResolvedValue([
+	{
+		color: "000000",
+		description: "def ghi",
+		name: "abc",
+	},
+]);
+
+vi.mock("../../../shared/readFileAsJson.js", () => ({
+	get readFileAsJson() {
+		return mockReadFileAsJson;
+	},
+}));
+
+describe("hydrateRepositoryLabels", () => {
+	it("creates a setup label when it doesn't already exist", async () => {
+		mock$.mockResolvedValue({
+			stdout: JSON.stringify([
+				{
+					color: "000000",
+					description: "def ghi",
+					name: "other",
+				},
+			]),
+		});
+
+		await hydrateRepositoryLabels();
+
+		expect(mock$).toHaveBeenCalledWith(
+			["gh label ", " ", " --color ", " --description ", ""],
+			"create",
+			"abc",
+			"000000",
+			"def ghi"
+		);
+	});
+
+	it("edits a setup label when it already exists", async () => {
+		mock$.mockResolvedValue({
+			stdout: JSON.stringify([
+				{
+					color: "000000",
+					description: "def ghi",
+					name: "abc",
+				},
+			]),
+		});
+
+		await hydrateRepositoryLabels();
+
+		expect(mock$).toHaveBeenCalledWith(
+			["gh label ", " ", " --color ", " --description ", ""],
+			"edit",
+			"abc",
+			"000000",
+			"def ghi"
+		);
+	});
+
+	it("deletes a pre-existing label when it isn't a setup label", async () => {
+		mock$.mockResolvedValue({
+			stdout: JSON.stringify([
+				{
+					color: "000000",
+					description: "def ghi",
+					name: "unknown",
+				},
+			]),
+		});
+
+		await hydrateRepositoryLabels();
+
+		expect(mock$).toHaveBeenCalledWith(
+			["gh label delete ", " --yes"],
+			"unknown"
+		);
+		expect(mock$).toHaveBeenCalledTimes(3);
+	});
+
+	it("doesn't delete a pre-existing label when it isn't a setup label", async () => {
+		mock$.mockResolvedValue({
+			stdout: JSON.stringify([
+				{
+					color: "000000",
+					description: "def ghi",
+					name: "abc",
+				},
+			]),
+		});
+
+		await hydrateRepositoryLabels();
+
+		expect(mock$).not.toHaveBeenCalledWith(
+			["gh label delete ", " --yes"],
+			"abc"
+		);
+		expect(mock$).toHaveBeenCalledTimes(2);
+	});
+});
diff --git a/src/shared/getDefaultSettings.test.ts b/src/shared/getDefaultSettings.test.ts
new file mode 100644
index 0000000..9248bc6
--- /dev/null
+++ b/src/shared/getDefaultSettings.test.ts
@@ -0,0 +1,34 @@
+import { describe, expect, it, vi } from "vitest";
+
+import { getDefaultSettings } from "./getDefaultSettings.js";
+
+vi.mock("./cli/lines.js");
+
+const mockGitRemoteOriginUrl = vi.fn();
+
+vi.mock("git-remote-origin-url", () => ({
+	get default() {
+		return mockGitRemoteOriginUrl;
+	},
+}));
+
+describe("getDefaultSettings", () => {
+	it("returns the retrieved owner and repository when gitRemoteOriginUrl succeeds", async () => {
+		mockGitRemoteOriginUrl.mockResolvedValue("https://github.com/abc/def");
+
+		const settings = await getDefaultSettings();
+
+		expect(settings).toEqual({ defaultOwner: "abc", defaultRepository: "def" });
+	});
+
+	it("returns arbitrary owner and repository defaults when gitRemoteOriginUrl rejects", async () => {
+		mockGitRemoteOriginUrl.mockRejectedValue(new Error("Oh no!"));
+
+		const settings = await getDefaultSettings();
+
+		expect(settings).toEqual({
+			defaultOwner: "UserName",
+			defaultRepository: "my-lovely-repository",
+		});
+	});
+});