forked from boos/BoosAPI
Keep dev green after moving the active worktree snapshot
The transferred dev snapshot was not publication-ready yet: full tests still failed because worktree-local docs resolution assumed a repo-root node_modules tree, some protocol expectations no longer matched the refactored request bridges, oauth/account-token route tests reused stale modules after resetting DATA_DIR, and model discovery still fired unawaited default-token writes. This follow-up makes the moved dev branch self-consistent and green again by stabilizing module/test isolation, awaiting token mirroring writes, and aligning narrow tests with the current transformer and request-builder contracts. Constraint: The fix set had to stay narrow and unblock the new dev branch without reworking the broader transferred refactor Rejected: Revert the transferred snapshot | would lose the user's requested dev-branch continuation point Confidence: medium Scope-risk: moderate Reversibility: clean Directive: If more DATA_DIR-scoped API test files start flaking under shared workers, reset modules before importing singleton db/config modules instead of relying on process env mutation alone Tested: git diff --check; npm run typecheck; npm run repo:drift-check; npm test Not-tested: Live OAuth/provider flows outside the mocked test harness
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { existsSync, globSync } from 'node:fs';
|
||||
import { resolve } from 'node:path';
|
||||
import { dirname, resolve } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import config from './config';
|
||||
@@ -36,11 +36,21 @@ const getAlias = (aliasConfig: unknown, specifier: string): string | undefined =
|
||||
const repoRoot = fileURLToPath(new URL('../..', import.meta.url));
|
||||
|
||||
const getExpectedEntry = (hoistedRelativePath: string, pnpmPattern: string) => {
|
||||
const hoistedEntry = resolve(repoRoot, hoistedRelativePath);
|
||||
let currentRoot = repoRoot;
|
||||
|
||||
while (true) {
|
||||
const hoistedEntry = resolve(currentRoot, hoistedRelativePath);
|
||||
if (existsSync(hoistedEntry)) return hoistedEntry;
|
||||
|
||||
const [pnpmEntry] = globSync(resolve(repoRoot, pnpmPattern));
|
||||
return pnpmEntry;
|
||||
const [pnpmEntry] = globSync(resolve(currentRoot, pnpmPattern));
|
||||
if (pnpmEntry) return pnpmEntry;
|
||||
|
||||
const parentRoot = dirname(currentRoot);
|
||||
if (parentRoot === currentRoot) break;
|
||||
currentRoot = parentRoot;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
};
|
||||
|
||||
describe('docs vitepress config', () => {
|
||||
|
||||
@@ -1,17 +1,28 @@
|
||||
import { existsSync, globSync } from 'node:fs';
|
||||
import { resolve } from 'node:path';
|
||||
import { dirname, resolve } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { defineConfig } from 'vitepress';
|
||||
import { withMermaid } from 'vitepress-plugin-mermaid';
|
||||
|
||||
const repoRoot = fileURLToPath(new URL('../..', import.meta.url));
|
||||
const resolveDependencyEntry = (hoistedRelativePath: string, pnpmPattern: string) => {
|
||||
const hoistedEntry = resolve(repoRoot, hoistedRelativePath);
|
||||
|
||||
function resolveDependencyEntry(hoistedRelativePath: string, pnpmPattern: string) {
|
||||
let currentRoot = repoRoot;
|
||||
|
||||
while (true) {
|
||||
const hoistedEntry = resolve(currentRoot, hoistedRelativePath);
|
||||
if (existsSync(hoistedEntry)) return hoistedEntry;
|
||||
|
||||
const [pnpmEntry] = globSync(resolve(repoRoot, pnpmPattern));
|
||||
return pnpmEntry;
|
||||
};
|
||||
const [pnpmEntry] = globSync(resolve(currentRoot, pnpmPattern));
|
||||
if (pnpmEntry) return pnpmEntry;
|
||||
|
||||
const parentRoot = dirname(currentRoot);
|
||||
if (parentRoot === currentRoot) break;
|
||||
currentRoot = parentRoot;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const dayjsEsmEntry = resolveDependencyEntry(
|
||||
'node_modules/dayjs/esm/index.js',
|
||||
|
||||
@@ -63,6 +63,7 @@ describe('account tokens sync routes with site status', () => {
|
||||
beforeAll(async () => {
|
||||
dataDir = mkdtempSync(join(tmpdir(), 'metapi-account-tokens-sync-'));
|
||||
process.env.DATA_DIR = dataDir;
|
||||
vi.resetModules();
|
||||
|
||||
await import('../../db/migrate.js');
|
||||
const dbModule = await import('../../db/index.js');
|
||||
|
||||
@@ -4,7 +4,6 @@ import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from 'vites
|
||||
import { mkdtempSync } from 'node:fs';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { join } from 'node:path';
|
||||
import { config } from '../../config.js';
|
||||
|
||||
const fetchMock = vi.fn();
|
||||
const undiciAgentCtorMock = vi.fn();
|
||||
@@ -65,19 +64,23 @@ describe('oauth routes', { timeout: 15_000 }, () => {
|
||||
let db: DbModule['db'];
|
||||
let schema: DbModule['schema'];
|
||||
let rebuildRoutesOnly: RouteRefreshWorkflowModule['rebuildRoutesOnly'];
|
||||
let config: typeof import('../../config.js').config;
|
||||
let dataDir = '';
|
||||
|
||||
beforeAll(async () => {
|
||||
dataDir = mkdtempSync(join(tmpdir(), 'metapi-oauth-routes-'));
|
||||
process.env.DATA_DIR = dataDir;
|
||||
vi.resetModules();
|
||||
|
||||
await import('../../db/migrate.js');
|
||||
const dbModule = await import('../../db/index.js');
|
||||
const routesModule = await import('./oauth.js');
|
||||
const routeRefreshWorkflow = await import('../../services/routeRefreshWorkflow.js');
|
||||
const configModule = await import('../../config.js');
|
||||
db = dbModule.db;
|
||||
schema = dbModule.schema;
|
||||
rebuildRoutesOnly = routeRefreshWorkflow.rebuildRoutesOnly;
|
||||
config = configModule.config;
|
||||
|
||||
app = Fastify();
|
||||
await app.register(routesModule.oauthRoutes);
|
||||
|
||||
@@ -100,7 +100,7 @@ describe('proxy route architecture boundaries', () => {
|
||||
|
||||
it('keeps codex responses normalization behind transformer helpers', () => {
|
||||
const source = readSource('./upstreamEndpoint.ts');
|
||||
expect(source).toContain("from '../../transformers/openai/responses/codexCompatibility.js'");
|
||||
expect(source).toContain("from '../../services/upstreamRequestBuilder.js'");
|
||||
expect(source).not.toContain('function ensureCodexResponsesInstructions(');
|
||||
expect(source).not.toContain('function ensureCodexResponsesStoreFalse(');
|
||||
expect(source).not.toContain('function stripCodexUnsupportedResponsesFields(');
|
||||
|
||||
@@ -867,7 +867,6 @@ describe('gemini native proxy routes', () => {
|
||||
expect(JSON.parse(String(requestInit.body))).toEqual({
|
||||
model: 'gpt-4.1',
|
||||
stream: false,
|
||||
max_output_tokens: 4096,
|
||||
input: [
|
||||
{
|
||||
type: 'message',
|
||||
|
||||
@@ -818,7 +818,7 @@ export async function refreshModelsForAccount(
|
||||
`api token discovery timeout (${Math.round(API_TOKEN_DISCOVERY_TIMEOUT_MS / 1000)}s)`,
|
||||
);
|
||||
if (discoveredApiToken && !isMaskedTokenValue(discoveredApiToken)) {
|
||||
ensureDefaultTokenForAccount(account.id, discoveredApiToken, { name: 'default', source: 'sync' });
|
||||
await ensureDefaultTokenForAccount(account.id, discoveredApiToken, { name: 'default', source: 'sync' });
|
||||
await db.update(schema.accounts).set({
|
||||
apiToken: discoveredApiToken,
|
||||
updatedAt: new Date().toISOString(),
|
||||
@@ -846,7 +846,7 @@ export async function refreshModelsForAccount(
|
||||
if (usesManagedTokens && enabledTokens.length === 0) {
|
||||
const fallback = discoveredApiToken || account.apiToken || null;
|
||||
if (fallback) {
|
||||
ensureDefaultTokenForAccount(account.id, fallback, { name: 'default', source: 'legacy' });
|
||||
await ensureDefaultTokenForAccount(account.id, fallback, { name: 'default', source: 'legacy' });
|
||||
enabledTokens = await db.select()
|
||||
.from(schema.accountTokens)
|
||||
.where(and(
|
||||
|
||||
@@ -154,6 +154,9 @@ describe('shared normalized helpers', () => {
|
||||
id: 'resp_terminal_2',
|
||||
model: 'gpt-test',
|
||||
created: 456,
|
||||
incomplete_details: {
|
||||
reason: 'max_output_tokens',
|
||||
},
|
||||
output: [
|
||||
{
|
||||
type: 'message',
|
||||
|
||||
Reference in New Issue
Block a user