Restructure background update checker tests
Collapse duplicate no-op scenarios into a state table and assert user-visible update outcomes instead of narrow call plumbing. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -51,11 +51,21 @@ mock.module("../../../shared/logger", () => ({ log: () => {} }))
|
|||||||
const modulePath = "./background-update-check?test"
|
const modulePath = "./background-update-check?test"
|
||||||
const { runBackgroundUpdateCheck } = await import(modulePath)
|
const { runBackgroundUpdateCheck } = await import(modulePath)
|
||||||
|
|
||||||
describe("runBackgroundUpdateCheck", () => {
|
async function runCheck(autoUpdate = true): Promise<void> {
|
||||||
const mockCtx = { directory: "/test" } as PluginInput
|
const mockContext = { directory: "/test" } as PluginInput
|
||||||
const getToastMessage: ToastMessageGetter = (isUpdate, version) =>
|
const getToastMessage: ToastMessageGetter = (isUpdate, version) =>
|
||||||
isUpdate ? `Update to ${version}` : "Up to date"
|
isUpdate ? `Update to ${version}` : "Up to date"
|
||||||
|
|
||||||
|
await runBackgroundUpdateCheck(mockContext, autoUpdate, getToastMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
function expectNoUpdateEffects(): void {
|
||||||
|
expect(mockShowUpdateAvailableToast).not.toHaveBeenCalled()
|
||||||
|
expect(mockShowAutoUpdatedToast).not.toHaveBeenCalled()
|
||||||
|
expect(mockRunBunInstall).not.toHaveBeenCalled()
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("runBackgroundUpdateCheck", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mockFindPluginEntry.mockReset()
|
mockFindPluginEntry.mockReset()
|
||||||
mockGetCachedVersion.mockReset()
|
mockGetCachedVersion.mockReset()
|
||||||
@@ -73,61 +83,42 @@ describe("runBackgroundUpdateCheck", () => {
|
|||||||
mockRunBunInstall.mockResolvedValue(true)
|
mockRunBunInstall.mockResolvedValue(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("#given no plugin entry found", () => {
|
describe("#given no-op scenarios", () => {
|
||||||
it("returns early without showing any toast", async () => {
|
it.each([
|
||||||
|
{
|
||||||
|
name: "plugin entry is missing",
|
||||||
|
setup: () => {
|
||||||
|
mockFindPluginEntry.mockReturnValue(null)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no cached or pinned version exists",
|
||||||
|
setup: () => {
|
||||||
|
mockFindPluginEntry.mockReturnValue(createPluginEntry({ entry: "oh-my-opencode" }))
|
||||||
|
mockGetCachedVersion.mockReturnValue(null)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "latest version lookup fails",
|
||||||
|
setup: () => {
|
||||||
|
mockGetLatestVersion.mockResolvedValue(null)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "current version is already latest",
|
||||||
|
setup: () => {
|
||||||
|
mockGetLatestVersion.mockResolvedValue("3.4.0")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])("returns without user-visible update effects when $name", async ({ setup }) => {
|
||||||
//#given
|
//#given
|
||||||
mockFindPluginEntry.mockReturnValue(null)
|
setup()
|
||||||
//#when
|
|
||||||
await runBackgroundUpdateCheck(mockCtx, true, getToastMessage)
|
|
||||||
//#then
|
|
||||||
expect(mockFindPluginEntry).toHaveBeenCalledTimes(1)
|
|
||||||
expect(mockShowUpdateAvailableToast).not.toHaveBeenCalled()
|
|
||||||
expect(mockShowAutoUpdatedToast).not.toHaveBeenCalled()
|
|
||||||
expect(mockRunBunInstall).not.toHaveBeenCalled()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe("#given no version available", () => {
|
|
||||||
it("returns early when neither cached nor pinned version exists", async () => {
|
|
||||||
//#given
|
|
||||||
mockFindPluginEntry.mockReturnValue(createPluginEntry({ entry: "oh-my-opencode" }))
|
|
||||||
mockGetCachedVersion.mockReturnValue(null)
|
|
||||||
//#when
|
//#when
|
||||||
await runBackgroundUpdateCheck(mockCtx, true, getToastMessage)
|
await runCheck()
|
||||||
//#then
|
|
||||||
expect(mockGetCachedVersion).toHaveBeenCalledTimes(1)
|
|
||||||
expect(mockGetLatestVersion).not.toHaveBeenCalled()
|
|
||||||
expect(mockShowUpdateAvailableToast).not.toHaveBeenCalled()
|
|
||||||
expect(mockShowAutoUpdatedToast).not.toHaveBeenCalled()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe("#given latest version fetch fails", () => {
|
|
||||||
it("returns early without toasts", async () => {
|
|
||||||
//#given
|
|
||||||
mockGetLatestVersion.mockResolvedValue(null)
|
|
||||||
//#when
|
|
||||||
await runBackgroundUpdateCheck(mockCtx, true, getToastMessage)
|
|
||||||
//#then
|
//#then
|
||||||
expect(mockGetLatestVersion).toHaveBeenCalledWith("latest")
|
expectNoUpdateEffects()
|
||||||
expect(mockRunBunInstall).not.toHaveBeenCalled()
|
|
||||||
expect(mockShowUpdateAvailableToast).not.toHaveBeenCalled()
|
|
||||||
expect(mockShowAutoUpdatedToast).not.toHaveBeenCalled()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe("#given already on latest version", () => {
|
|
||||||
it("returns early without any action", async () => {
|
|
||||||
//#given
|
|
||||||
mockGetCachedVersion.mockReturnValue("3.4.0")
|
|
||||||
mockGetLatestVersion.mockResolvedValue("3.4.0")
|
|
||||||
//#when
|
|
||||||
await runBackgroundUpdateCheck(mockCtx, true, getToastMessage)
|
|
||||||
//#then
|
|
||||||
expect(mockGetLatestVersion).toHaveBeenCalledTimes(1)
|
|
||||||
expect(mockRunBunInstall).not.toHaveBeenCalled()
|
|
||||||
expect(mockShowUpdateAvailableToast).not.toHaveBeenCalled()
|
|
||||||
expect(mockShowAutoUpdatedToast).not.toHaveBeenCalled()
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -136,9 +127,13 @@ describe("runBackgroundUpdateCheck", () => {
|
|||||||
//#given
|
//#given
|
||||||
const autoUpdate = false
|
const autoUpdate = false
|
||||||
//#when
|
//#when
|
||||||
await runBackgroundUpdateCheck(mockCtx, autoUpdate, getToastMessage)
|
await runCheck(autoUpdate)
|
||||||
//#then
|
//#then
|
||||||
expect(mockShowUpdateAvailableToast).toHaveBeenCalledWith(mockCtx, "3.5.0", getToastMessage)
|
expect(mockShowUpdateAvailableToast).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({ directory: "/test" }),
|
||||||
|
"3.5.0",
|
||||||
|
expect.any(Function)
|
||||||
|
)
|
||||||
expect(mockRunBunInstall).not.toHaveBeenCalled()
|
expect(mockRunBunInstall).not.toHaveBeenCalled()
|
||||||
expect(mockShowAutoUpdatedToast).not.toHaveBeenCalled()
|
expect(mockShowAutoUpdatedToast).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
@@ -149,7 +144,7 @@ describe("runBackgroundUpdateCheck", () => {
|
|||||||
//#given
|
//#given
|
||||||
mockFindPluginEntry.mockReturnValue(createPluginEntry({ isPinned: true, pinnedVersion: "3.4.0" }))
|
mockFindPluginEntry.mockReturnValue(createPluginEntry({ isPinned: true, pinnedVersion: "3.4.0" }))
|
||||||
//#when
|
//#when
|
||||||
await runBackgroundUpdateCheck(mockCtx, true, getToastMessage)
|
await runCheck()
|
||||||
//#then
|
//#then
|
||||||
expect(mockShowUpdateAvailableToast).toHaveBeenCalledTimes(1)
|
expect(mockShowUpdateAvailableToast).toHaveBeenCalledTimes(1)
|
||||||
expect(mockRunBunInstall).not.toHaveBeenCalled()
|
expect(mockRunBunInstall).not.toHaveBeenCalled()
|
||||||
@@ -166,7 +161,7 @@ describe("runBackgroundUpdateCheck", () => {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
//#when
|
//#when
|
||||||
await runBackgroundUpdateCheck(mockCtx, true, getToastMessage)
|
await runCheck()
|
||||||
//#then
|
//#then
|
||||||
expect(mockShowUpdateAvailableToast).toHaveBeenCalledTimes(1)
|
expect(mockShowUpdateAvailableToast).toHaveBeenCalledTimes(1)
|
||||||
expect(capturedToastMessage).toBeDefined()
|
expect(capturedToastMessage).toBeDefined()
|
||||||
@@ -184,11 +179,15 @@ describe("runBackgroundUpdateCheck", () => {
|
|||||||
//#given
|
//#given
|
||||||
mockRunBunInstall.mockResolvedValue(true)
|
mockRunBunInstall.mockResolvedValue(true)
|
||||||
//#when
|
//#when
|
||||||
await runBackgroundUpdateCheck(mockCtx, true, getToastMessage)
|
await runCheck()
|
||||||
//#then
|
//#then
|
||||||
expect(mockInvalidatePackage).toHaveBeenCalledTimes(1)
|
expect(mockInvalidatePackage).toHaveBeenCalledTimes(1)
|
||||||
expect(mockRunBunInstall).toHaveBeenCalledTimes(1)
|
expect(mockRunBunInstall).toHaveBeenCalledTimes(1)
|
||||||
expect(mockShowAutoUpdatedToast).toHaveBeenCalledWith(mockCtx, "3.4.0", "3.5.0")
|
expect(mockShowAutoUpdatedToast).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({ directory: "/test" }),
|
||||||
|
"3.4.0",
|
||||||
|
"3.5.0"
|
||||||
|
)
|
||||||
expect(mockShowUpdateAvailableToast).not.toHaveBeenCalled()
|
expect(mockShowUpdateAvailableToast).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -198,10 +197,14 @@ describe("runBackgroundUpdateCheck", () => {
|
|||||||
//#given
|
//#given
|
||||||
mockRunBunInstall.mockResolvedValue(false)
|
mockRunBunInstall.mockResolvedValue(false)
|
||||||
//#when
|
//#when
|
||||||
await runBackgroundUpdateCheck(mockCtx, true, getToastMessage)
|
await runCheck()
|
||||||
//#then
|
//#then
|
||||||
expect(mockRunBunInstall).toHaveBeenCalledTimes(1)
|
expect(mockRunBunInstall).toHaveBeenCalledTimes(1)
|
||||||
expect(mockShowUpdateAvailableToast).toHaveBeenCalledWith(mockCtx, "3.5.0", getToastMessage)
|
expect(mockShowUpdateAvailableToast).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({ directory: "/test" }),
|
||||||
|
"3.5.0",
|
||||||
|
expect.any(Function)
|
||||||
|
)
|
||||||
expect(mockShowAutoUpdatedToast).not.toHaveBeenCalled()
|
expect(mockShowAutoUpdatedToast).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user