Files
memind_adm/server/app.image-make.test.mjs

150 lines
5.6 KiB
JavaScript

import assert from 'node:assert/strict';
import test from 'node:test';
import { createAdminApp } from './app.mjs';
function createServices({ role = 'admin', imageMakeAdminConfigService } = {}) {
return {
ready: Promise.resolve(),
parseCookies: () => ({ adm_session: 'test-token' }),
USER_COOKIE: 'adm_session',
userLoginCookies: () => ['adm_session=test-token; Path=/; HttpOnly'],
clearUserSessionCookie: () => ['adm_session=; Path=/; Max-Age=0'],
resolveCookieDomainForRequest: () => null,
userAuth: {
getMe: async () => ({ id: 'admin-user-id', username: 'admin', role }),
},
imageMakeAdminConfigService,
};
}
async function withServer(services, callback) {
const app = createAdminApp(services);
const server = await new Promise((resolve) => {
const instance = app.listen(0, '127.0.0.1', () => resolve(instance));
});
const address = server.address();
const baseUrl = `http://127.0.0.1:${address.port}`;
try {
await callback(baseUrl);
} finally {
await new Promise((resolve, reject) => server.close((error) => (error ? reject(error) : resolve())));
}
}
const adminHeaders = {
cookie: 'adm_session=test-token',
'content-type': 'application/json',
};
test('image_make admin routes read and update config with the admin identity', async () => {
let updateCall = null;
const service = {
getAdminConfig: async () => ({
source: 'default',
config: {
defaultProvider: 'mock',
jobDefaultTimeoutSeconds: 120,
providers: { mock: { enabled: true }, aliyun_bailian: { enabled: false }, comfyui: { enabled: false } },
},
}),
updateAdminConfig: async (patch, context) => {
updateCall = { patch, context };
return { ok: true, source: 'admin-db', config: patch };
},
getRuntimeConfig: async () => ({
ok: true,
fingerprint: '1234567890abcdef',
defaultProvider: 'aliyun_bailian',
jobDefaultTimeoutSeconds: 120,
providers: {
mock: { enabled: true },
aliyun_bailian: {
enabled: true,
model: 'qwen-image-plus',
apiBase: 'https://dashscope.aliyuncs.com/api/v1',
apiKey: 'must-not-leak',
},
comfyui: { enabled: false },
},
}),
};
await withServer(createServices({ imageMakeAdminConfigService: service }), async (baseUrl) => {
const configResponse = await fetch(`${baseUrl}/admin-api/image-make/config`, { headers: adminHeaders });
assert.equal(configResponse.status, 200);
assert.equal((await configResponse.json()).config.defaultProvider, 'mock');
const patch = { defaultProvider: 'mock', jobDefaultTimeoutSeconds: 180 };
const updateResponse = await fetch(`${baseUrl}/admin-api/image-make/config`, {
method: 'PATCH',
headers: adminHeaders,
body: JSON.stringify(patch),
});
assert.equal(updateResponse.status, 200);
assert.deepEqual(updateCall, { patch, context: { updatedBy: 'admin-user-id' } });
const runtimeResponse = await fetch(`${baseUrl}/admin-api/image-make/runtime`, { headers: adminHeaders });
assert.equal(runtimeResponse.status, 200);
const runtime = await runtimeResponse.json();
assert.equal(runtime.providers.aliyun_bailian.apiKeyConfigured, true);
assert.equal('apiKey' in runtime.providers.aliyun_bailian, false);
assert.equal(JSON.stringify(runtime).includes('must-not-leak'), false);
});
});
test('image_make admin config validation failures are returned as 400', async () => {
const service = {
updateAdminConfig: async () => ({ ok: false, message: '默认 Provider 必须处于启用状态' }),
};
await withServer(createServices({ imageMakeAdminConfigService: service }), async (baseUrl) => {
const response = await fetch(`${baseUrl}/admin-api/image-make/config`, {
method: 'PATCH',
headers: adminHeaders,
body: JSON.stringify({ defaultProvider: 'comfyui' }),
});
assert.equal(response.status, 400);
assert.equal((await response.json()).message, '默认 Provider 必须处于启用状态');
});
});
test('image_make admin routes require an admin user and an enabled service', async () => {
await withServer(createServices({ role: 'user', imageMakeAdminConfigService: {} }), async (baseUrl) => {
const forbidden = await fetch(`${baseUrl}/admin-api/image-make/config`, { headers: adminHeaders });
assert.equal(forbidden.status, 403);
});
await withServer(createServices({ imageMakeAdminConfigService: {} }), async (baseUrl) => {
const unavailable = await fetch(`${baseUrl}/admin-api/image-make/config`, { headers: adminHeaders });
assert.equal(unavailable.status, 503);
});
});
test('gray read-only mode blocks admin writes while keeping reads available', async () => {
let updateCalled = false;
const service = {
getAdminConfig: async () => ({ config: { defaultProvider: 'mock', providers: {} } }),
updateAdminConfig: async () => {
updateCalled = true;
return { ok: true };
},
};
const services = {
...createServices({ imageMakeAdminConfigService: service }),
readOnlyMode: true,
};
await withServer(services, async (baseUrl) => {
const readResponse = await fetch(`${baseUrl}/admin-api/image-make/config`, { headers: adminHeaders });
assert.equal(readResponse.status, 200);
const writeResponse = await fetch(`${baseUrl}/admin-api/image-make/config`, {
method: 'PATCH',
headers: adminHeaders,
body: JSON.stringify({ defaultProvider: 'mock' }),
});
assert.equal(writeResponse.status, 423);
assert.match((await writeResponse.json()).message, /灰度只读模式/);
assert.equal(updateCalled, false);
});
});