test: fresh-import remaining contamination-prone modules

This commit is contained in:
YeonGyu-Kim
2026-04-04 20:14:50 +09:00
parent 861ce1c161
commit 55d5ecb9fb
5 changed files with 90 additions and 47 deletions
+18 -6
View File
@@ -2,14 +2,26 @@ import { describe, expect, it, beforeEach, afterEach, mock } from "bun:test"
import { createHash, randomBytes } from "node:crypto"
import type { OAuthTokenData } from "./storage"
const {
McpOAuthProvider,
generateCodeVerifier,
generateCodeChallenge,
buildAuthorizationUrl,
} = await import(new URL("./provider.ts?real-provider-test", import.meta.url).href)
type ProviderModule = typeof import("./provider")
async function importFreshProviderModule(): Promise<ProviderModule> {
return await import(new URL(`./provider.ts?real-provider-test=${Date.now()}-${Math.random()}`, import.meta.url).href)
}
describe("McpOAuthProvider", () => {
let McpOAuthProvider: ProviderModule["McpOAuthProvider"]
let generateCodeVerifier: ProviderModule["generateCodeVerifier"]
let generateCodeChallenge: ProviderModule["generateCodeChallenge"]
let buildAuthorizationUrl: ProviderModule["buildAuthorizationUrl"]
beforeEach(async () => {
const providerModule = await importFreshProviderModule()
McpOAuthProvider = providerModule.McpOAuthProvider
generateCodeVerifier = providerModule.generateCodeVerifier
generateCodeChallenge = providerModule.generateCodeChallenge
buildAuthorizationUrl = providerModule.buildAuthorizationUrl
})
describe("generateCodeVerifier", () => {
it("returns a base64url-encoded 32-byte random string", () => {
// given
@@ -1,20 +1,22 @@
const { describe, expect, mock, test, afterAll } = require("bun:test")
mock.module("../../shared/opencode-message-dir", () => ({
getMessageDir: () => null,
}))
mock.module("../../shared/opencode-storage-detection", () => ({
isSqliteBackend: () => true,
}))
mock.module("../../shared/normalize-sdk-response", () => ({
normalizeSDKResponse: <TData>(response: { data?: TData }, fallback: TData): TData => response.data ?? fallback,
}))
afterAll(() => { mock.restore() })
const { getLastAgentFromSession } = await import("./session-last-agent")
async function importFreshSessionLastAgentModule() {
mock.module("../../shared/opencode-message-dir", () => ({
getMessageDir: () => null,
}))
mock.module("../../shared/opencode-storage-detection", () => ({
isSqliteBackend: () => true,
}))
const module = await import(`./session-last-agent?test=${Date.now()}-${Math.random()}`)
mock.restore()
return module
}
const { getLastAgentFromSession } = await importFreshSessionLastAgentModule()
function createMockClient(messages: Array<{ info?: { agent?: string } }>) {
return {
@@ -5,24 +5,25 @@ import type { MessageData } from "./types"
let sqliteBackend = false
let storedParts: Array<{ type: string; id?: string; callID?: string; [key: string]: unknown }> = []
mock.module("../../shared/opencode-storage-detection", () => ({
isSqliteBackend: () => sqliteBackend,
}))
mock.module("../../shared/normalize-sdk-response", () => ({
normalizeSDKResponse: <TData>(response: { data?: TData }, fallback: TData): TData => response.data ?? fallback,
}))
mock.module("./storage", () => ({
readParts: () => storedParts,
}))
afterAll(() => {
mock.restore()
})
const { recoverToolResultMissing } = await import("./recover-tool-result-missing")
mock.restore()
async function importFreshRecoverToolResultMissingModule() {
mock.module("../../shared/opencode-storage-detection", () => ({
isSqliteBackend: () => sqliteBackend,
}))
mock.module("./storage", () => ({
readParts: () => storedParts,
}))
const module = await import(`./recover-tool-result-missing?test=${Date.now()}-${Math.random()}`)
mock.restore()
return module
}
const { recoverToolResultMissing } = await importFreshRecoverToolResultMissingModule()
function createMockClient(messages: MessageData[] = []) {
const promptAsync = mock(() => Promise.resolve({}))
+30 -11
View File
@@ -6,11 +6,17 @@ import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync
import { tmpdir } from "node:os"
import { join } from "node:path"
const { createConnectedProvidersCacheStore, findProviderModelMetadata } = await import(
new URL("./connected-providers-cache.ts?real-connected-providers-cache-test", import.meta.url).href
)
type ConnectedProvidersCacheModule = typeof import("./connected-providers-cache")
function createTestCacheContext() {
async function importFreshConnectedProvidersCacheModule(): Promise<ConnectedProvidersCacheModule> {
return await import(
new URL(`./connected-providers-cache.ts?real-connected-providers-cache-test=${Date.now()}-${Math.random()}`, import.meta.url).href
)
}
function createTestCacheContext(
createConnectedProvidersCacheStore: ConnectedProvidersCacheModule["createConnectedProvidersCacheStore"],
) {
const fakeUserCacheRoot = mkdtempSync(join(tmpdir(), "connected-providers-user-cache-"))
const testCacheDir = join(fakeUserCacheRoot, "oh-my-opencode")
const testCacheStore = createConnectedProvidersCacheStore(() => testCacheDir)
@@ -30,7 +36,8 @@ function cleanupTestCacheContext(fakeUserCacheRoot: string): void {
describe("updateConnectedProvidersCache", () => {
test("extracts models from provider.list().all response", async () => {
const { testCacheStore, fakeUserCacheRoot } = createTestCacheContext()
const { createConnectedProvidersCacheStore } = await importFreshConnectedProvidersCacheModule()
const { testCacheStore, fakeUserCacheRoot } = createTestCacheContext(createConnectedProvidersCacheStore)
try {
//#given
@@ -87,7 +94,8 @@ describe("updateConnectedProvidersCache", () => {
})
test("writes empty models when provider has no models", async () => {
const { testCacheStore, fakeUserCacheRoot } = createTestCacheContext()
const { createConnectedProvidersCacheStore } = await importFreshConnectedProvidersCacheModule()
const { testCacheStore, fakeUserCacheRoot } = createTestCacheContext(createConnectedProvidersCacheStore)
try {
//#given
@@ -122,7 +130,8 @@ describe("updateConnectedProvidersCache", () => {
})
test("writes empty models when all field is missing", async () => {
const { testCacheStore, fakeUserCacheRoot } = createTestCacheContext()
const { createConnectedProvidersCacheStore } = await importFreshConnectedProvidersCacheModule()
const { testCacheStore, fakeUserCacheRoot } = createTestCacheContext(createConnectedProvidersCacheStore)
try {
//#given
@@ -149,7 +158,8 @@ describe("updateConnectedProvidersCache", () => {
})
test("does nothing when client.provider.list is not available", async () => {
const { testCacheStore, fakeUserCacheRoot } = createTestCacheContext()
const { createConnectedProvidersCacheStore } = await importFreshConnectedProvidersCacheModule()
const { testCacheStore, fakeUserCacheRoot } = createTestCacheContext(createConnectedProvidersCacheStore)
try {
//#given
@@ -167,7 +177,8 @@ describe("updateConnectedProvidersCache", () => {
})
test("does not remove unrelated files in the cache directory", async () => {
const { testCacheStore, fakeUserCacheRoot } = createTestCacheContext()
const { createConnectedProvidersCacheStore } = await importFreshConnectedProvidersCacheModule()
const { testCacheStore, fakeUserCacheRoot } = createTestCacheContext(createConnectedProvidersCacheStore)
//#given
const realCacheDir = join(fakeUserCacheRoot, "oh-my-opencode")
@@ -210,7 +221,11 @@ describe("updateConnectedProvidersCache", () => {
})
test("findProviderModelMetadata returns rich cached metadata", async () => {
const { testCacheStore, fakeUserCacheRoot } = createTestCacheContext()
const {
createConnectedProvidersCacheStore,
findProviderModelMetadata,
} = await importFreshConnectedProvidersCacheModule()
const { testCacheStore, fakeUserCacheRoot } = createTestCacheContext(createConnectedProvidersCacheStore)
try {
//#given
@@ -264,7 +279,11 @@ describe("updateConnectedProvidersCache", () => {
})
test("keeps normalized fallback ids when raw metadata id is not a string", async () => {
const { testCacheStore, fakeUserCacheRoot } = createTestCacheContext()
const {
createConnectedProvidersCacheStore,
findProviderModelMetadata,
} = await importFreshConnectedProvidersCacheModule()
const { testCacheStore, fakeUserCacheRoot } = createTestCacheContext(createConnectedProvidersCacheStore)
try {
const mockClient = {
@@ -1,11 +1,16 @@
declare const require: (name: string) => any
const { describe, test, expect, beforeEach, afterEach, spyOn, mock } = require("bun:test")
import { resolveSubagentExecution } from "./subagent-resolver"
import type { DelegateTaskArgs } from "./types"
import type { ExecutorContext } from "./executor-types"
import * as logger from "../../shared/logger"
import * as connectedProvidersCache from "../../shared/connected-providers-cache"
type SubagentResolverModule = typeof import("./subagent-resolver")
async function importFreshSubagentResolverModule(): Promise<SubagentResolverModule> {
return await import(`./subagent-resolver?test=${Date.now()}-${Math.random()}`)
}
function createBaseArgs(overrides?: Partial<DelegateTaskArgs>): DelegateTaskArgs {
return {
description: "Run review",
@@ -37,10 +42,12 @@ function createExecutorContext(
describe("resolveSubagentExecution", () => {
let logSpy: ReturnType<typeof spyOn> | undefined
let resolveSubagentExecution: SubagentResolverModule["resolveSubagentExecution"]
beforeEach(() => {
beforeEach(async () => {
mock.restore()
logSpy = spyOn(logger, "log").mockImplementation(() => {})
;({ resolveSubagentExecution } = await importFreshSubagentResolverModule())
})
afterEach(() => {
@@ -648,9 +655,11 @@ describe("resolveSubagentExecution", () => {
describe("resolveSubagentExecution - agent name sanitization", () => {
let logSpy: ReturnType<typeof spyOn> | undefined
let resolveSubagentExecution: SubagentResolverModule["resolveSubagentExecution"]
beforeEach(() => {
beforeEach(async () => {
logSpy = spyOn(logger, "log").mockImplementation(() => {})
;({ resolveSubagentExecution } = await importFreshSubagentResolverModule())
})
afterEach(() => {