Remove the "AI 连接配置" page under 扩展&增强 together with the theme's own OpenAI-compatible provider path. AI generation (SEO, summary, tags) now runs solely on the WordPress AI Client (wp_ai_client_prompt), with connections configured through WordPress AI Connectors. - AI.php keeps only the WP AI Client path: no provider config storage, no theme fallback, no rate limiting - Drop /ai/status, /ai/settings and legacy /ai/seo-suggest routes plus their handlers - Remove dead compat code: AISEO::suggest, AIPrompt::build_seo_prompt and the front-submit AI assist flow (its buttons were never rendered and its endpoints were never registered) - Update SEO schema/meta-box guidance that pointed at the deleted page - Add ai-config-removal contract test and refresh the toast and user-features contracts affected by the cleanup
92 lines
3.7 KiB
JavaScript
92 lines
3.7 KiB
JavaScript
'use strict';
|
|
|
|
/** AI 连接配置页已移除:主题只走 WordPress AI Connectors,生成能力与入口保留。 */
|
|
|
|
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
const test = require('node:test');
|
|
|
|
const root = path.resolve(__dirname, '..', '..');
|
|
|
|
const read = (rel) => fs.readFileSync(path.join(root, rel), 'utf8');
|
|
|
|
const ai = read('src/Ai/AI.php');
|
|
const controller = read('src/Admin/AIController.php');
|
|
const seoSchema = read('assets/admin/src/schema/sections/global/seo.js');
|
|
const extensionsMenu = read('assets/admin/src/constants/sections/extensions.js');
|
|
const apiModule = read('assets/admin/src/api/modules/extensions.js');
|
|
const frontSubmit = read('assets/js/front-submit.js');
|
|
const submitContext = read('templates/parts/submit/context.php');
|
|
const submitPage = read('templates/pages/page-submit.php');
|
|
|
|
const removed = [
|
|
'aksrt_ai_settings',
|
|
'AI 连接配置',
|
|
'AI连接配置',
|
|
'ExtensionAI',
|
|
'extensions-ai',
|
|
'/ai/settings',
|
|
'/ai/status',
|
|
'ai-assist-btn',
|
|
'扩展 → AI',
|
|
];
|
|
|
|
const walk = (dir) => fs.readdirSync(dir, { withFileTypes: true }).flatMap((entry) => {
|
|
const full = path.join(dir, entry.name);
|
|
if (entry.isDirectory()) {
|
|
return ['node_modules', 'build', 'dist'].includes(entry.name) ? [] : walk(full);
|
|
}
|
|
return [full];
|
|
});
|
|
|
|
const sources = ['src', 'assets/admin/src', 'templates', 'assets/js', 'inc']
|
|
.flatMap((dir) => walk(path.join(root, dir)));
|
|
|
|
test('后台菜单、路由与 API 中不再有 AI 连接配置页', () => {
|
|
assert.doesNotMatch(extensionsMenu, /extensions-ai|ExtensionAI|AI 连接配置/);
|
|
assert.doesNotMatch(apiModule, /getAiStatus|updateAiSettings|generateSeo|suggestSummary|suggestTags/);
|
|
assert.ok(!fs.existsSync(path.join(root, 'assets/admin/src/pages/extensions/ExtensionAI.vue')));
|
|
assert.ok(!fs.existsSync(path.join(root, 'assets/admin/src/router/component-loaders/extensions.js')));
|
|
});
|
|
|
|
test('AI.php 只保留 WP AI Client 单路出口', () => {
|
|
assert.doesNotMatch(ai, /PROVIDER_OPENAI|PROVIDER_NONE/);
|
|
assert.doesNotMatch(ai, /get_config|update_config/);
|
|
assert.doesNotMatch(ai, /generate_via_theme|normalize_api_base/);
|
|
assert.doesNotMatch(ai, /is_theme_provider_available|resolve_backend/);
|
|
assert.doesNotMatch(ai, /check_rate_limit|record_call/);
|
|
assert.match(ai, /wp_ai_client_prompt/);
|
|
assert.match(ai, /function is_wp_ai_available/);
|
|
assert.match(ai, /function is_available/);
|
|
});
|
|
|
|
test('生成路由保留,连接配置与旧草稿兼容路由移除', () => {
|
|
assert.match(controller, /\/ai\/seo-generate/);
|
|
assert.match(controller, /\/ai\/summary-suggest/);
|
|
assert.match(controller, /\/ai\/tags-suggest/);
|
|
assert.doesNotMatch(controller, /\/ai\/seo-suggest/);
|
|
assert.doesNotMatch(controller, /function get_status|function update_settings|function seo_suggest/);
|
|
});
|
|
|
|
test('残留文案不再指向已删除的配置页', () => {
|
|
for (const [name, source] of [['AI.php', ai], ['AIController.php', controller], ['seo.js', seoSchema]]) {
|
|
assert.doesNotMatch(source, /AI 连接配置/, `${name} 仍引用 AI 连接配置页`);
|
|
assert.doesNotMatch(source, /扩展 → AI/, `${name} 仍引导到扩展菜单`);
|
|
}
|
|
});
|
|
|
|
test('前台投稿 AI 辅助死代码已清理', () => {
|
|
assert.doesNotMatch(frontSubmit, /bindAi|ai-assist-btn|cfg\.ai/);
|
|
assert.doesNotMatch(submitContext, /ai_available/);
|
|
assert.doesNotMatch(submitPage, /'ai'\s*=>|aiGenerating|aiFailed|aiFilled|needContent/);
|
|
});
|
|
|
|
test('全仓源码不再引用已删除的 AI 连接配置', () => {
|
|
const offenders = sources.filter((file) => {
|
|
const text = fs.readFileSync(file, 'utf8');
|
|
return removed.some((pattern) => text.includes(pattern));
|
|
});
|
|
assert.deepEqual(offenders.map((file) => path.relative(root, file)), []);
|
|
});
|