-
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: added tests for data fetching (#228)
## PR Checklist - [x] Addresses an existing open issue: fixes #227 - [x] That issue was marked as [`status: accepting prs`](https://github.com/JoshuaKGoldberg/refined-saved-replies/issues?q=is%3Aopen+is%3Aissue+label%3A%22status%3A+accepting+prs%22) - [x] Steps in [CONTRIBUTING.md](https://github.com/JoshuaKGoldberg/refined-saved-replies/blob/main/.github/CONTRIBUTING.md) were taken ## Overview Extracts and adds unit tests for data fetching helpers in `content-script.ts`. The rest of the file is mostly DOM creation, so it wasn't very unit testable. Ah well.
- Loading branch information
1 parent
40fb754
commit 3533ed1
Showing
5 changed files
with
175 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { beforeEach, describe, expect, it, vi } from "vitest"; | ||
|
||
import { fetchRepliesConfiguration } from "./fetchRepliesConfiguration.js"; | ||
|
||
const mockFetch = vi.fn(); | ||
const mockError = vi.fn(); | ||
|
||
describe("fetchRepliesConfiguration", () => { | ||
beforeEach(() => { | ||
globalThis.fetch = mockFetch; | ||
globalThis.console.error = mockError; | ||
}); | ||
|
||
it("returns undefined and console errors when the fetch is not ok and status is not 404", async () => { | ||
const statusText = "Oh no!"; | ||
|
||
mockFetch.mockResolvedValue({ ok: false, status: 500, statusText }); | ||
|
||
const actual = await fetchRepliesConfiguration("", ""); | ||
|
||
expect(actual).toBeUndefined(); | ||
expect(mockError).toHaveBeenCalledWith( | ||
"Non-ok response fetching replies:", | ||
statusText, | ||
); | ||
}); | ||
|
||
it("returns undefined and does not console error when the fetch is not ok and status is 404", async () => { | ||
mockFetch.mockResolvedValue({ ok: false, status: 404 }); | ||
|
||
const actual = await fetchRepliesConfiguration("", ""); | ||
|
||
expect(actual).toBeUndefined(); | ||
expect(mockError).not.toHaveBeenCalled(); | ||
}); | ||
|
||
it("returns undefined and console errors when the fetch retrieves an invalid configuration", async () => { | ||
mockFetch.mockResolvedValue({ ok: true, text: () => "" }); | ||
|
||
const actual = await fetchRepliesConfiguration("", ""); | ||
|
||
expect(actual).toBeUndefined(); | ||
expect(mockError).toHaveBeenCalledWith("Invalid saved replies:", undefined); | ||
}); | ||
|
||
it("returns the configuration when fetch retrieves a valid configuration", async () => { | ||
const configuration = { replies: [] }; | ||
mockFetch.mockResolvedValue({ | ||
ok: true, | ||
text: () => JSON.stringify(configuration), | ||
}); | ||
|
||
const actual = await fetchRepliesConfiguration("", ""); | ||
|
||
expect(actual).toEqual(configuration); | ||
expect(mockError).not.toHaveBeenCalled(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import * as yaml from "js-yaml"; | ||
|
||
import { isBodyWithReplies } from "./validations.js"; | ||
|
||
export async function fetchRepliesConfiguration( | ||
defaultBranch: string, | ||
locator: string, | ||
) { | ||
const repliesResponse = await fetch( | ||
`https://raw.githubusercontent.com/${locator}/${defaultBranch}/.github/replies.yml`, | ||
); | ||
|
||
if (!repliesResponse.ok) { | ||
if (repliesResponse.status !== 404) { | ||
console.error( | ||
"Non-ok response fetching replies:", | ||
repliesResponse.statusText, | ||
); | ||
} | ||
|
||
return; | ||
} | ||
|
||
const repliesBody = await repliesResponse.text(); | ||
|
||
const repliesConfiguration = yaml.load(repliesBody); | ||
|
||
if (!isBodyWithReplies(repliesConfiguration)) { | ||
console.error("Invalid saved replies:", repliesConfiguration); | ||
return; | ||
} | ||
|
||
return repliesConfiguration; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { beforeEach, describe, expect, it, vi } from "vitest"; | ||
|
||
import { fetchSettings } from "./fetchSettings.js"; | ||
|
||
const mockFetchAsJson = vi.fn(); | ||
|
||
vi.mock("./fetchAsJson.js", () => ({ | ||
get fetchAsJson() { | ||
return mockFetchAsJson; | ||
}, | ||
})); | ||
|
||
const mockError = vi.fn(); | ||
|
||
describe("fetchSettings", () => { | ||
beforeEach(() => { | ||
globalThis.console.error = mockError; | ||
}); | ||
|
||
it("returns undefined and console errors when the repository settings are invalid", async () => { | ||
const repositorySettings = { invalid: true }; | ||
|
||
mockFetchAsJson | ||
.mockResolvedValueOnce({}) | ||
.mockResolvedValueOnce(repositorySettings); | ||
|
||
const actual = await fetchSettings("", ""); | ||
|
||
expect(actual).toBeUndefined(); | ||
expect(mockError).toHaveBeenCalledWith( | ||
"Invalid repository details:", | ||
repositorySettings, | ||
); | ||
}); | ||
|
||
it("returns the default branch and item details when the repository settings are valid", async () => { | ||
const defaultBranch = "some-branch"; | ||
const itemDetails = { item: "details" }; | ||
const repositorySettings = { default_branch: defaultBranch }; | ||
|
||
mockFetchAsJson | ||
.mockResolvedValueOnce(itemDetails) | ||
.mockResolvedValueOnce(repositorySettings); | ||
|
||
const actual = await fetchSettings("", ""); | ||
|
||
expect(actual).toEqual({ defaultBranch, itemDetails }); | ||
expect(mockError).not.toHaveBeenCalled(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { fetchAsJson } from "./fetchAsJson.js"; | ||
import { isRepositorySettings } from "./validations.js"; | ||
|
||
export async function fetchSettings(issueOrPR: string, locator: string) { | ||
const [itemDetails, repositorySettings] = await Promise.all([ | ||
fetchAsJson(`https://api.github.com/repos/${locator}/issues/${issueOrPR}`), | ||
fetchAsJson(`https://api.github.com/repos/${locator}`), | ||
]); | ||
|
||
if (!isRepositorySettings(repositorySettings)) { | ||
console.error("Invalid repository details:", repositorySettings); | ||
return; | ||
} | ||
|
||
const { default_branch: defaultBranch } = repositorySettings; | ||
|
||
return { defaultBranch, itemDetails }; | ||
} |