Files
metapi/src/server/services/defaultSiteSeedService.test.ts
T
cita 23922a5965 feat: Add normalized types and utility functions for handling chat formats
- Introduced `NormalizedContentBlock`, `NormalizedUsage`, and related types for structured data handling.
- Implemented utility functions for creating and merging normalized usage statistics.
- Added a new module for shared transformers to manage chat formats.

feat: Implement app local state management

- Created functions to clear application installation state and manage local storage keys.
- Added constants for theme and user profile storage keys.

test: Add tests for BrandIcon component rendering

- Implemented tests to ensure BrandIcon does not force a colored background for recognized brands.

test: Enhance ModelAnalysisPanel tests

- Added tests for rendering token summaries with compact units in ModelAnalysisPanel.

test: Add tests for ModernSelect component

- Implemented tests to verify icon rendering for selected options in ModernSelect.

test: Add number formatting tests

- Created tests for `formatCompactTokenMetric` to validate token formatting logic.

feat: Implement account creation intent handling

- Added logic to handle session and API key creation intents in the Accounts page.

test: Add tests for dashboard performance card

- Implemented tests to verify rendering of performance metrics in the dashboard.

feat: Implement default connection segment resolution

- Added logic to determine initial connection segments based on platform types.

test: Add tests for settings factory reset functionality

- Implemented tests to verify the factory reset process and local state clearing.

test: Add tests for site creation redirect logic

- Implemented tests to verify redirection based on site capabilities during creation.

test: Add tests for token routes refresh decision action

- Implemented tests to verify refresh decision actions in TokenRoutes.

test: Add tests for token routes snapshot load

- Implemented tests to verify loading of cached snapshot data in TokenRoutes.
2026-03-08 12:08:57 +08:00

130 lines
4.0 KiB
TypeScript

import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'vitest';
import { mkdtempSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { eq } from 'drizzle-orm';
type DbModule = typeof import('../db/index.js');
type SeedModule = typeof import('./defaultSiteSeedService.js');
describe('defaultSiteSeedService', () => {
let db: DbModule['db'];
let schema: DbModule['schema'];
let ensureDefaultSitesSeeded: SeedModule['ensureDefaultSitesSeeded'];
let DEFAULT_SITE_SEED_SETTING_KEY: SeedModule['DEFAULT_SITE_SEED_SETTING_KEY'];
let dataDir = '';
beforeAll(async () => {
dataDir = mkdtempSync(join(tmpdir(), 'metapi-default-site-seed-'));
process.env.DATA_DIR = dataDir;
await import('../db/migrate.js');
const dbModule = await import('../db/index.js');
const seedModule = await import('./defaultSiteSeedService.js');
db = dbModule.db;
schema = dbModule.schema;
ensureDefaultSitesSeeded = seedModule.ensureDefaultSitesSeeded;
DEFAULT_SITE_SEED_SETTING_KEY = seedModule.DEFAULT_SITE_SEED_SETTING_KEY;
});
beforeEach(async () => {
await db.delete(schema.settings).run();
await db.delete(schema.sites).run();
});
afterAll(() => {
delete process.env.DATA_DIR;
});
it('seeds default official sites once when no site exists yet', async () => {
await ensureDefaultSitesSeeded();
const sites = await db.select().from(schema.sites).all();
const sorted = [...sites].sort((left, right) => (left.sortOrder || 0) - (right.sortOrder || 0));
expect(sorted.map((site) => ({
name: site.name,
url: site.url,
platform: site.platform,
status: site.status,
useSystemProxy: site.useSystemProxy,
isPinned: site.isPinned,
globalWeight: site.globalWeight,
sortOrder: site.sortOrder,
}))).toEqual([
{
name: 'OpenAI 官方',
url: 'https://api.openai.com',
platform: 'openai',
status: 'active',
useSystemProxy: false,
isPinned: false,
globalWeight: 1,
sortOrder: 0,
},
{
name: 'Claude 官方',
url: 'https://api.anthropic.com',
platform: 'claude',
status: 'active',
useSystemProxy: false,
isPinned: false,
globalWeight: 1,
sortOrder: 1,
},
{
name: 'Gemini 官方',
url: 'https://generativelanguage.googleapis.com',
platform: 'gemini',
status: 'active',
useSystemProxy: false,
isPinned: false,
globalWeight: 1,
sortOrder: 2,
},
{
name: 'CLIProxyAPI',
url: 'http://127.0.0.1:8317',
platform: 'cliproxyapi',
status: 'active',
useSystemProxy: false,
isPinned: false,
globalWeight: 1,
sortOrder: 3,
},
]);
const setting = await db.select().from(schema.settings).where(eq(schema.settings.key, DEFAULT_SITE_SEED_SETTING_KEY)).get();
expect(JSON.parse(setting?.value || 'false')).toBe(true);
});
it('marks first-run evaluation without seeding when sites already exist', async () => {
await db.insert(schema.sites).values({
name: 'Existing Site',
url: 'https://existing.example.com',
platform: 'new-api',
}).run();
await ensureDefaultSitesSeeded();
const sites = await db.select().from(schema.sites).all();
expect(sites).toHaveLength(1);
expect(sites[0]?.name).toBe('Existing Site');
const setting = await db.select().from(schema.settings).where(eq(schema.settings.key, DEFAULT_SITE_SEED_SETTING_KEY)).get();
expect(JSON.parse(setting?.value || 'false')).toBe(true);
});
it('does not seed again after the evaluation marker exists', async () => {
await db.insert(schema.settings).values({
key: DEFAULT_SITE_SEED_SETTING_KEY,
value: JSON.stringify(true),
}).run();
await ensureDefaultSitesSeeded();
const sites = await db.select().from(schema.sites).all();
expect(sites).toHaveLength(0);
});
});