From 414136a7bdfda70e82553e2459a5d5ecb0026783 Mon Sep 17 00:00:00 2001 From: sunlei Date: Fri, 19 Jun 2026 19:28:38 +0800 Subject: [PATCH] =?UTF-8?q?test:=20=E5=9B=BA=E5=8C=96Bilibili=E5=8D=A1?= =?UTF-8?q?=E7=89=87=E6=8F=92=E4=BB=B6=E6=9E=B6=E6=9E=84=E9=97=A8=E7=A6=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/refactor-v3/01-seed-core.sql | 69 +++++++++++++++++++ sql/refactor-v3/99-verify.sql | 11 +++ .../qqbot-current-operation-matrix.spec.ts | 24 +++++++ .../qqbot-plugin-package-boundary.spec.ts | 43 +++++++----- .../plugins/plugin-platform-migration.spec.ts | 47 +++++++++---- 5 files changed, 163 insertions(+), 31 deletions(-) diff --git a/sql/refactor-v3/01-seed-core.sql b/sql/refactor-v3/01-seed-core.sql index ca407ad..a4920d9 100644 --- a/sql/refactor-v3/01-seed-core.sql +++ b/sql/refactor-v3/01-seed-core.sql @@ -249,12 +249,81 @@ INSERT INTO qqbot_plugin ( 'Repeater', 'Built-in repeater event plugin metadata.', 'installed' + ), + ( + 1000000000000000105, + 'bilibili-card', + 'Bilibili Card', + 'Built-in Bilibili card event plugin metadata.', + 'installed' ) ON DUPLICATE KEY UPDATE plugin_name = VALUES(plugin_name), description = VALUES(description), status = VALUES(status); +INSERT INTO qqbot_plugin_version ( + id, + plugin_id, + version, + package_hash, + manifest_json +) VALUES ( + 1000000000000001105, + 1000000000000000105, + '1.0.0', + 'builtin-bilibili-card-1.0.0', + JSON_OBJECT( + 'key', 'bilibili-card', + 'name', 'Bilibili Card', + 'version', '1.0.0', + 'entry', 'src/index.ts', + 'events', JSON_ARRAY(JSON_OBJECT( + 'key', 'bilibili-card.message', + 'eventName', 'message', + 'handlerName', 'handleMessage', + 'name', 'Bilibili 卡片解析' + )) + ) +) ON DUPLICATE KEY UPDATE + package_hash = VALUES(package_hash), + manifest_json = VALUES(manifest_json); + +INSERT INTO qqbot_plugin_installation ( + id, + plugin_id, + version_id, + status, + runtime_status, + installed_path +) VALUES ( + 1000000000000001205, + 1000000000000000105, + 1000000000000001105, + 'installed', + 'idle', + 'src/modules/qqbot/plugins/bilibili-card' +) ON DUPLICATE KEY UPDATE + status = VALUES(status), + runtime_status = VALUES(runtime_status), + installed_path = VALUES(installed_path); + +INSERT INTO qqbot_plugin_event_handler ( + id, + plugin_id, + event_key, + handler_name, + enabled +) VALUES ( + 1000000000000001305, + 1000000000000000105, + 'bilibili-card.message', + 'handleMessage', + 1 +) ON DUPLICATE KEY UPDATE + handler_name = VALUES(handler_name), + enabled = VALUES(enabled); + INSERT INTO qqbot_command ( id, operation_key, diff --git a/sql/refactor-v3/99-verify.sql b/sql/refactor-v3/99-verify.sql index f61dfa9..955427b 100644 --- a/sql/refactor-v3/99-verify.sql +++ b/sql/refactor-v3/99-verify.sql @@ -36,6 +36,17 @@ FROM qqbot_plugin WHERE plugin_key = 'bangdream' AND status = 'installed'; +SELECT 'seed_qqbot_plugin_bilibili_card' AS check_name, COUNT(*) AS matched_rows +FROM qqbot_plugin +WHERE plugin_key = 'bilibili-card' + AND status = 'installed'; + +SELECT 'seed_qqbot_plugin_event_bilibili_card' AS check_name, COUNT(*) AS matched_rows +FROM qqbot_plugin_event_handler +WHERE event_key = 'bilibili-card.message' + AND handler_name = 'handleMessage' + AND enabled = 1; + SELECT 'seed_qqbot_command_bangdream_song' AS check_name, COUNT(*) AS matched_rows FROM qqbot_command WHERE command_key = 'bangdream_song' diff --git a/test/modules/qqbot/architecture/qqbot-current-operation-matrix.spec.ts b/test/modules/qqbot/architecture/qqbot-current-operation-matrix.spec.ts index c33f0e5..8047e05 100644 --- a/test/modules/qqbot/architecture/qqbot-current-operation-matrix.spec.ts +++ b/test/modules/qqbot/architecture/qqbot-current-operation-matrix.spec.ts @@ -142,6 +142,7 @@ describe('QQBot current operation matrix', () => { it('freezes built-in plugin manifests and exposed capabilities', () => { const manifests = { bangdream: readManifest('bangdream'), + bilibiliCard: readManifest('bilibili-card'), ff14: readManifest('ff14-market'), fflogs: readManifest('fflogs'), repeater: readManifest('repeater'), @@ -157,6 +158,23 @@ describe('QQBot current operation matrix', () => { })), ).toEqual(bangdreamOperations); + expect( + manifests.bilibiliCard.events.map((event) => ({ + eventName: event.eventName, + handlerName: event.handlerName, + key: event.key, + name: event.name, + })), + ).toEqual([ + { + eventName: 'message', + handlerName: 'handleMessage', + key: 'bilibili-card.message', + name: 'Bilibili 卡片解析', + }, + ]); + expect(manifests.bilibiliCard.operations).toEqual([]); + expect( manifests.ff14.operations.map((operation) => ({ aliases: operation.aliases, @@ -215,6 +233,10 @@ describe('QQBot current operation matrix', () => { it('freezes current online command seed linkage for command plugins', () => { const seedSql = readFileSync(join(repoRoot, 'sql/qqbot-init.sql'), 'utf8'); + const refactorSeedSql = readFileSync( + join(repoRoot, 'sql/refactor-v3/01-seed-core.sql'), + 'utf8', + ); for (const operation of bangdreamOperations) { expect(seedSql).toContain(`'${operation.key}'`); @@ -224,5 +246,7 @@ describe('QQBot current operation matrix', () => { expect(seedSql).toContain(`'ff14-market', 'ff14.market.price'`); expect(seedSql).toContain(`'fflogs', 'fflogs.character.summary'`); expect(seedSql).toContain(`'bangdream', 'bangdream.event.stage', 'plain'`); + expect(refactorSeedSql).toContain(`'bilibili-card'`); + expect(refactorSeedSql).toContain(`'bilibili-card.message'`); }); }); diff --git a/test/modules/qqbot/architecture/qqbot-plugin-package-boundary.spec.ts b/test/modules/qqbot/architecture/qqbot-plugin-package-boundary.spec.ts index 2fd2987..e888e7b 100644 --- a/test/modules/qqbot/architecture/qqbot-plugin-package-boundary.spec.ts +++ b/test/modules/qqbot/architecture/qqbot-plugin-package-boundary.spec.ts @@ -97,6 +97,7 @@ describe('QQBot plugin package boundary', () => { expect(pluginDirs).toEqual([ 'bangdream', + 'bilibili-card', 'ff14-market', 'fflogs', 'repeater', @@ -104,23 +105,27 @@ describe('QQBot plugin package boundary', () => { }); it('uses the same package shape for every built-in plugin', () => { - const missing = ['bangdream', 'ff14-market', 'fflogs', 'repeater'].flatMap( - (pluginKey) => { - const manifest = JSON.parse( - readFileSync(join(pluginRoot, pluginKey, 'plugin.json'), 'utf8'), - ) as { events?: unknown[]; operations?: unknown[] }; - const requiredPaths = [ - ...requiredPluginPaths, - ...((manifest.operations || []).length - ? requiredCommandPluginPaths - : []), - ...((manifest.events || []).length ? requiredEventPluginPaths : []), - ]; - return requiredPaths - .map((pathName) => `${pluginKey}/${pathName}`) - .filter((pathName) => !existsSync(join(pluginRoot, pathName))); - }, - ); + const missing = [ + 'bangdream', + 'bilibili-card', + 'ff14-market', + 'fflogs', + 'repeater', + ].flatMap((pluginKey) => { + const manifest = JSON.parse( + readFileSync(join(pluginRoot, pluginKey, 'plugin.json'), 'utf8'), + ) as { events?: unknown[]; operations?: unknown[] }; + const requiredPaths = [ + ...requiredPluginPaths, + ...((manifest.operations || []).length + ? requiredCommandPluginPaths + : []), + ...((manifest.events || []).length ? requiredEventPluginPaths : []), + ]; + return requiredPaths + .map((pathName) => `${pluginKey}/${pathName}`) + .filter((pathName) => !existsSync(join(pluginRoot, pathName))); + }); expect(missing).toEqual([]); }); @@ -128,6 +133,7 @@ describe('QQBot plugin package boundary', () => { it('does not keep third-phase package directories as empty shells', () => { const emptyRequiredDirs = [ 'bangdream', + 'bilibili-card', 'ff14-market', 'fflogs', 'repeater', @@ -242,6 +248,7 @@ describe('QQBot plugin package boundary', () => { it('keeps plugin package entrypoints limited to createPlugin', () => { const extraExports = [ 'bangdream', + 'bilibili-card', 'ff14-market', 'fflogs', 'repeater', @@ -319,7 +326,7 @@ describe('plugin platform package decoupling', () => { .join('|'), ); const forbiddenBranchPattern = - /pluginKey\s*(?:={2,3})\s*['"`](bangdream|ff14-market|fflogs|repeater)['"`]|case\s+['"`](bangdream|ff14-market|fflogs|repeater)['"`]/; + /pluginKey\s*(?:={2,3})\s*['"`](bangdream|bilibili-card|ff14-market|fflogs|repeater)['"`]|case\s+['"`](bangdream|bilibili-card|ff14-market|fflogs|repeater)['"`]/; /** * Escapes a literal token before it is placed into the architecture gate regexp. diff --git a/test/modules/qqbot/plugins/plugin-platform-migration.spec.ts b/test/modules/qqbot/plugins/plugin-platform-migration.spec.ts index 068e369..6636125 100644 --- a/test/modules/qqbot/plugins/plugin-platform-migration.spec.ts +++ b/test/modules/qqbot/plugins/plugin-platform-migration.spec.ts @@ -41,7 +41,13 @@ describe('QQBot existing plugin platform migration', () => { readdirSync(pluginRoot) .filter((name) => statSync(join(pluginRoot, name)).isDirectory()) .sort(), - ).toEqual(['bangdream', 'ff14-market', 'fflogs', 'repeater']); + ).toEqual([ + 'bangdream', + 'bilibili-card', + 'ff14-market', + 'fflogs', + 'repeater', + ]); const legacySources = collectFiles(legacyPluginRoot).filter((filePath) => filePath.endsWith('.ts'), @@ -50,21 +56,26 @@ describe('QQBot existing plugin platform migration', () => { }); it('declares parseable platform manifests for every existing plugin', () => { - const manifests = ['bangdream', 'ff14-market', 'fflogs', 'repeater'].map( - (pluginName) => { - const root = join(pluginRoot, pluginName); - const manifest = parseQqbotPluginManifest( - readJson(join(root, 'plugin.json')), - { - pluginRoot: root, - }, - ); - return manifest; - }, - ); + const manifests = [ + 'bangdream', + 'bilibili-card', + 'ff14-market', + 'fflogs', + 'repeater', + ].map((pluginName) => { + const root = join(pluginRoot, pluginName); + const manifest = parseQqbotPluginManifest( + readJson(join(root, 'plugin.json')), + { + pluginRoot: root, + }, + ); + return manifest; + }); expect(manifests.map((manifest) => manifest.pluginKey).sort()).toEqual([ 'bangdream', + 'bilibili-card', 'ff14-market', 'fflogs', 'repeater', @@ -79,6 +90,16 @@ describe('QQBot existing plugin platform migration', () => { ).toBe(true); }); + it('seeds Bilibili card plugin event metadata in refactor v3 SQL', () => { + const refactorSeedSql = readFileSync( + join(repoRoot, 'sql/refactor-v3/01-seed-core.sql'), + 'utf8', + ); + + expect(refactorSeedSql).toContain(`'bilibili-card'`); + expect(refactorSeedSql).toContain(`'bilibili-card.message'`); + }); + it('keeps BangDream manifest operations as the single metadata source', () => { const manifest = parseQqbotPluginManifest( readJson(join(pluginRoot, 'bangdream/plugin.json')),