test(features): update background agent, MCP loader, and tmux tests
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -4,7 +4,30 @@ import {
|
||||
resetAdditionalAllowedMcpEnvVars,
|
||||
setAdditionalAllowedMcpEnvVars,
|
||||
} from "./configure-allowed-env-vars"
|
||||
import { expandEnvVars, expandEnvVarsInObject } from "./env-expander"
|
||||
|
||||
type EnvExpanderModule = typeof import("./env-expander")
|
||||
|
||||
async function importFreshEnvExpanderModule(): Promise<EnvExpanderModule> {
|
||||
return await import(`./env-expander?test=${Date.now()}-${Math.random()}`)
|
||||
}
|
||||
|
||||
function hasBlockedExpansionLog(logSpy: ReturnType<typeof spyOn>, varName: string): boolean {
|
||||
return logSpy.mock.calls.some(([message, data]) => {
|
||||
if (typeof message !== "string") {
|
||||
return false
|
||||
}
|
||||
|
||||
if (!message.includes("Blocked MCP env var expansion")) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (typeof data !== "object" || data === null) {
|
||||
return false
|
||||
}
|
||||
|
||||
return "varName" in data && data.varName === varName
|
||||
})
|
||||
}
|
||||
|
||||
describe("expandEnvVars", () => {
|
||||
const originalEnv = { ...process.env }
|
||||
@@ -25,31 +48,30 @@ describe("expandEnvVars", () => {
|
||||
})
|
||||
|
||||
describe("#given a sensitive environment variable reference", () => {
|
||||
it("#when expanding the value #then it returns an empty string and logs a warning", () => {
|
||||
it("#when expanding the value #then it returns an empty string and logs a warning", async () => {
|
||||
// given
|
||||
process.env.GITHUB_TOKEN = "ghp-secret"
|
||||
const logSpy = spyOn(shared, "log").mockImplementation(() => {})
|
||||
const { expandEnvVars } = await importFreshEnvExpanderModule()
|
||||
|
||||
// when
|
||||
const expanded = expandEnvVars("${GITHUB_TOKEN}")
|
||||
|
||||
// then
|
||||
expect(expanded).toBe("")
|
||||
expect(logSpy).toHaveBeenCalledWith(
|
||||
expect.stringContaining("Blocked MCP env var expansion"),
|
||||
expect.objectContaining({ varName: "GITHUB_TOKEN" })
|
||||
)
|
||||
expect(hasBlockedExpansionLog(logSpy, "GITHUB_TOKEN")).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#given a benign environment variable in the builtin allowlist", () => {
|
||||
it("#when expanding the value #then it returns the env value", () => {
|
||||
it("#when expanding the value #then it returns the env value", async () => {
|
||||
// given
|
||||
process.env.TMPDIR = "/tmp/omo"
|
||||
process.env.TEMP = "C:\\Temp"
|
||||
process.env.USERPROFILE = "C:\\Users\\tester"
|
||||
process.env.LANG = "en_US.UTF-8"
|
||||
process.env.XDG_CONFIG_HOME = "/Users/tester/.config"
|
||||
const { expandEnvVars } = await importFreshEnvExpanderModule()
|
||||
|
||||
// when
|
||||
const expanded = expandEnvVars(
|
||||
@@ -64,27 +86,26 @@ describe("expandEnvVars", () => {
|
||||
})
|
||||
|
||||
describe("#given a blocked non-sensitive environment variable reference", () => {
|
||||
it("#when expanding the value #then it returns an empty string and logs a warning", () => {
|
||||
it("#when expanding the value #then it returns an empty string and logs a warning", async () => {
|
||||
// given
|
||||
process.env.PROJECT_ROOT = "/Users/tester/project"
|
||||
const logSpy = spyOn(shared, "log").mockImplementation(() => {})
|
||||
const { expandEnvVars } = await importFreshEnvExpanderModule()
|
||||
|
||||
// when
|
||||
const expanded = expandEnvVars("${PROJECT_ROOT}")
|
||||
|
||||
// then
|
||||
expect(expanded).toBe("")
|
||||
expect(logSpy).toHaveBeenCalledWith(
|
||||
expect.stringContaining("Blocked MCP env var expansion"),
|
||||
expect.objectContaining({ varName: "PROJECT_ROOT" })
|
||||
)
|
||||
expect(hasBlockedExpansionLog(logSpy, "PROJECT_ROOT")).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#given a blocked variable with a default value", () => {
|
||||
it("#when expanding the value #then it uses the default instead of the sensitive env var", () => {
|
||||
it("#when expanding the value #then it uses the default instead of the sensitive env var", async () => {
|
||||
// given
|
||||
process.env.SECRET_KEY = "super-secret"
|
||||
const { expandEnvVars } = await importFreshEnvExpanderModule()
|
||||
|
||||
// when
|
||||
const expanded = expandEnvVars("${SECRET_KEY:-fallback}")
|
||||
@@ -95,9 +116,10 @@ describe("expandEnvVars", () => {
|
||||
})
|
||||
|
||||
describe("#given a safe allowlisted environment variable reference", () => {
|
||||
it("#when expanding the value #then it returns the env value", () => {
|
||||
it("#when expanding the value #then it returns the env value", async () => {
|
||||
// given
|
||||
process.env.HOME = "/Users/tester"
|
||||
const { expandEnvVars } = await importFreshEnvExpanderModule()
|
||||
|
||||
// when
|
||||
const expanded = expandEnvVars("${HOME}")
|
||||
@@ -108,10 +130,11 @@ describe("expandEnvVars", () => {
|
||||
})
|
||||
|
||||
describe("#given a sensitive environment variable listed in the user allowlist", () => {
|
||||
it("#when expanding the value #then it returns the env value", () => {
|
||||
it("#when expanding the value #then it returns the env value", async () => {
|
||||
// given
|
||||
process.env.CUSTOM_API_KEY = "user-approved"
|
||||
setAdditionalAllowedMcpEnvVars(["CUSTOM_API_KEY"])
|
||||
const { expandEnvVars } = await importFreshEnvExpanderModule()
|
||||
|
||||
// when
|
||||
const expanded = expandEnvVars("${CUSTOM_API_KEY}")
|
||||
@@ -122,9 +145,10 @@ describe("expandEnvVars", () => {
|
||||
})
|
||||
|
||||
describe("#given a sensitive environment variable expanded in trusted mode", () => {
|
||||
it("#when expanding the value #then it returns the env value bypassing the allowlist", () => {
|
||||
it("#when expanding the value #then it returns the env value bypassing the allowlist", async () => {
|
||||
// given
|
||||
process.env.SLACK_USER_TOKEN = "xoxp-trusted"
|
||||
const { expandEnvVars } = await importFreshEnvExpanderModule()
|
||||
|
||||
// when
|
||||
const expanded = expandEnvVars("${SLACK_USER_TOKEN}", { trusted: true })
|
||||
@@ -135,9 +159,10 @@ describe("expandEnvVars", () => {
|
||||
})
|
||||
|
||||
describe("#given an unset env var expanded in trusted mode with a default", () => {
|
||||
it("#when expanding the value #then it returns the default value", () => {
|
||||
it("#when expanding the value #then it returns the default value", async () => {
|
||||
// given
|
||||
delete process.env.UNSET_TRUSTED_VAR
|
||||
const { expandEnvVars } = await importFreshEnvExpanderModule()
|
||||
|
||||
// when
|
||||
const expanded = expandEnvVars("${UNSET_TRUSTED_VAR:-fallback}", { trusted: true })
|
||||
@@ -167,10 +192,11 @@ describe("expandEnvVarsInObject", () => {
|
||||
})
|
||||
|
||||
describe("#given a nested MCP config object", () => {
|
||||
it("#when expanding env vars in the object #then it only expands safe values", () => {
|
||||
it("#when expanding env vars in the object #then it only expands safe values", async () => {
|
||||
// given
|
||||
process.env.HOME = "/Users/tester"
|
||||
process.env.AWS_SECRET_ACCESS_KEY = "aws-secret"
|
||||
const { expandEnvVarsInObject } = await importFreshEnvExpanderModule()
|
||||
|
||||
// when
|
||||
const expanded = expandEnvVarsInObject({
|
||||
@@ -193,10 +219,11 @@ describe("expandEnvVarsInObject", () => {
|
||||
})
|
||||
|
||||
describe("#given a trusted skill MCP config object with sensitive env vars", () => {
|
||||
it("#when expanding env vars in trusted mode #then it expands all referenced env vars", () => {
|
||||
it("#when expanding env vars in trusted mode #then it expands all referenced env vars", async () => {
|
||||
// given
|
||||
process.env.SLACK_USER_TOKEN = "xoxp-trusted-token"
|
||||
process.env.HOME = "/Users/tester"
|
||||
const { expandEnvVarsInObject } = await importFreshEnvExpanderModule()
|
||||
|
||||
// when
|
||||
const expanded = expandEnvVarsInObject(
|
||||
@@ -232,9 +259,10 @@ describe("expandEnvVarsInObject", () => {
|
||||
})
|
||||
})
|
||||
|
||||
it("#when expanding a remote http skill MCP config in trusted mode #then it expands sensitive headers", () => {
|
||||
it("#when expanding a remote http skill MCP config in trusted mode #then it expands sensitive headers", async () => {
|
||||
// given
|
||||
process.env.SLACK_USER_TOKEN = "xoxp-trusted-token"
|
||||
const { expandEnvVarsInObject } = await importFreshEnvExpanderModule()
|
||||
|
||||
// when
|
||||
const expanded = expandEnvVarsInObject(
|
||||
|
||||
Reference in New Issue
Block a user