fix: 补齐QQBot插件分页与新设备二维码
This commit is contained in:
parent
8bcb5f78a9
commit
201fa13151
@ -54,6 +54,7 @@
|
||||
"pino": "^10.3.1",
|
||||
"pino-http": "^11.0.0",
|
||||
"pino-loki": "^3.0.0",
|
||||
"qrcode": "^1.5.4",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"rehype-parse": "^9.0.1",
|
||||
"rehype-raw": "^7.0.0",
|
||||
@ -81,6 +82,7 @@
|
||||
"@types/jest": "29.2.4",
|
||||
"@types/lodash": "^4.17.24",
|
||||
"@types/node": "22.19.19",
|
||||
"@types/qrcode": "^1.5.6",
|
||||
"@types/supertest": "^2.0.16",
|
||||
"@types/ws": "^8.18.1",
|
||||
"@typescript-eslint/eslint-plugin": "^8.60.1",
|
||||
|
||||
@ -71,6 +71,9 @@ importers:
|
||||
pino-loki:
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0
|
||||
qrcode:
|
||||
specifier: ^1.5.4
|
||||
version: 1.5.4
|
||||
reflect-metadata:
|
||||
specifier: ^0.2.2
|
||||
version: 0.2.2
|
||||
@ -147,6 +150,9 @@ importers:
|
||||
'@types/node':
|
||||
specifier: 22.19.19
|
||||
version: 22.19.19
|
||||
'@types/qrcode':
|
||||
specifier: ^1.5.6
|
||||
version: 1.5.6
|
||||
'@types/supertest':
|
||||
specifier: ^2.0.16
|
||||
version: 2.0.16
|
||||
@ -1206,6 +1212,9 @@ packages:
|
||||
'@types/node@22.19.19':
|
||||
resolution: {integrity: sha512-dyh/xO2Fh5bYrfWaaqGrRQQGkNdmYw6AmaAUvYeUMNTWQtvb796ikLdmTchRmOlOiIJ1TDXfWgVx1QkUlQ6Hew==}
|
||||
|
||||
'@types/qrcode@1.5.6':
|
||||
resolution: {integrity: sha512-te7NQcV2BOvdj2b1hCAHzAoMNuj65kNBMz0KBaxM6c3VGBOhU0dURQKOtH8CFNI/dsKkwlv32p26qYQTWoB5bw==}
|
||||
|
||||
'@types/qs@6.15.1':
|
||||
resolution: {integrity: sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw==}
|
||||
|
||||
@ -1757,6 +1766,9 @@ packages:
|
||||
resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==}
|
||||
engines: {node: '>= 12'}
|
||||
|
||||
cliui@6.0.0:
|
||||
resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==}
|
||||
|
||||
cliui@8.0.1:
|
||||
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
|
||||
engines: {node: '>=12'}
|
||||
@ -1904,6 +1916,10 @@ packages:
|
||||
supports-color:
|
||||
optional: true
|
||||
|
||||
decamelize@1.2.0:
|
||||
resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
decode-named-character-reference@1.3.0:
|
||||
resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==}
|
||||
|
||||
@ -1978,6 +1994,9 @@ packages:
|
||||
resolution: {integrity: sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==}
|
||||
engines: {node: '>=0.3.1'}
|
||||
|
||||
dijkstrajs@1.0.3:
|
||||
resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==}
|
||||
|
||||
doctrine@3.0.0:
|
||||
resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
@ -3493,6 +3512,10 @@ packages:
|
||||
resolution: {integrity: sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==}
|
||||
engines: {node: '>=4.0.0'}
|
||||
|
||||
pngjs@5.0.0:
|
||||
resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
|
||||
possible-typed-array-names@1.1.0:
|
||||
resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@ -3549,6 +3572,11 @@ packages:
|
||||
pure-rand@6.1.0:
|
||||
resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==}
|
||||
|
||||
qrcode@1.5.4:
|
||||
resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
hasBin: true
|
||||
|
||||
qs@6.15.2:
|
||||
resolution: {integrity: sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==}
|
||||
engines: {node: '>=0.6'}
|
||||
@ -3644,6 +3672,9 @@ packages:
|
||||
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
require-main-filename@2.0.0:
|
||||
resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==}
|
||||
|
||||
requireindex@1.2.0:
|
||||
resolution: {integrity: sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==}
|
||||
engines: {node: '>=0.10.5'}
|
||||
@ -4392,6 +4423,9 @@ packages:
|
||||
whatwg-url@5.0.0:
|
||||
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
|
||||
|
||||
which-module@2.0.1:
|
||||
resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==}
|
||||
|
||||
which-typed-array@1.1.21:
|
||||
resolution: {integrity: sha512-zbRA8cVm6io/d5W8uIe2hblzN76/Wm3v/yiythQvr+dpBWeqhPSWIDNj4zOyHi4zKbMK6DN34Xsr9jPHJERAEw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@ -4488,6 +4522,9 @@ packages:
|
||||
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
|
||||
engines: {node: '>=0.4'}
|
||||
|
||||
y18n@4.0.3:
|
||||
resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==}
|
||||
|
||||
y18n@5.0.8:
|
||||
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
|
||||
engines: {node: '>=10'}
|
||||
@ -4498,10 +4535,18 @@ packages:
|
||||
yallist@4.0.0:
|
||||
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
|
||||
|
||||
yargs-parser@18.1.3:
|
||||
resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
yargs-parser@21.1.1:
|
||||
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
yargs@15.4.1:
|
||||
resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
yargs@17.7.2:
|
||||
resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
|
||||
engines: {node: '>=12'}
|
||||
@ -5758,6 +5803,10 @@ snapshots:
|
||||
dependencies:
|
||||
undici-types: 6.21.0
|
||||
|
||||
'@types/qrcode@1.5.6':
|
||||
dependencies:
|
||||
'@types/node': 22.19.19
|
||||
|
||||
'@types/qs@6.15.1': {}
|
||||
|
||||
'@types/range-parser@1.2.7': {}
|
||||
@ -6377,6 +6426,12 @@ snapshots:
|
||||
|
||||
cli-width@4.1.0: {}
|
||||
|
||||
cliui@6.0.0:
|
||||
dependencies:
|
||||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
wrap-ansi: 6.2.0
|
||||
|
||||
cliui@8.0.1:
|
||||
dependencies:
|
||||
string-width: 4.2.3
|
||||
@ -6498,6 +6553,8 @@ snapshots:
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
|
||||
decamelize@1.2.0: {}
|
||||
|
||||
decode-named-character-reference@1.3.0:
|
||||
dependencies:
|
||||
character-entities: 2.0.2
|
||||
@ -6551,6 +6608,8 @@ snapshots:
|
||||
|
||||
diff@4.0.4: {}
|
||||
|
||||
dijkstrajs@1.0.3: {}
|
||||
|
||||
doctrine@3.0.0:
|
||||
dependencies:
|
||||
esutils: 2.0.3
|
||||
@ -8568,6 +8627,8 @@ snapshots:
|
||||
|
||||
pngjs@3.4.0: {}
|
||||
|
||||
pngjs@5.0.0: {}
|
||||
|
||||
possible-typed-array-names@1.1.0: {}
|
||||
|
||||
prelude-ls@1.2.1: {}
|
||||
@ -8613,6 +8674,12 @@ snapshots:
|
||||
|
||||
pure-rand@6.1.0: {}
|
||||
|
||||
qrcode@1.5.4:
|
||||
dependencies:
|
||||
dijkstrajs: 1.0.3
|
||||
pngjs: 5.0.0
|
||||
yargs: 15.4.1
|
||||
|
||||
qs@6.15.2:
|
||||
dependencies:
|
||||
side-channel: 1.1.0
|
||||
@ -8743,6 +8810,8 @@ snapshots:
|
||||
|
||||
require-from-string@2.0.2: {}
|
||||
|
||||
require-main-filename@2.0.0: {}
|
||||
|
||||
requireindex@1.2.0: {}
|
||||
|
||||
resolve-cwd@3.0.0:
|
||||
@ -9496,6 +9565,8 @@ snapshots:
|
||||
tr46: 0.0.3
|
||||
webidl-conversions: 3.0.1
|
||||
|
||||
which-module@2.0.1: {}
|
||||
|
||||
which-typed-array@1.1.21:
|
||||
dependencies:
|
||||
available-typed-arrays: 1.0.7
|
||||
@ -9606,14 +9677,35 @@ snapshots:
|
||||
|
||||
xtend@4.0.2: {}
|
||||
|
||||
y18n@4.0.3: {}
|
||||
|
||||
y18n@5.0.8: {}
|
||||
|
||||
yallist@3.1.1: {}
|
||||
|
||||
yallist@4.0.0: {}
|
||||
|
||||
yargs-parser@18.1.3:
|
||||
dependencies:
|
||||
camelcase: 5.3.1
|
||||
decamelize: 1.2.0
|
||||
|
||||
yargs-parser@21.1.1: {}
|
||||
|
||||
yargs@15.4.1:
|
||||
dependencies:
|
||||
cliui: 6.0.0
|
||||
decamelize: 1.2.0
|
||||
find-up: 4.1.0
|
||||
get-caller-file: 2.0.5
|
||||
require-directory: 2.1.1
|
||||
require-main-filename: 2.0.0
|
||||
set-blocking: 2.0.0
|
||||
string-width: 4.2.3
|
||||
which-module: 2.0.1
|
||||
y18n: 4.0.3
|
||||
yargs-parser: 18.1.3
|
||||
|
||||
yargs@17.7.2:
|
||||
dependencies:
|
||||
cliui: 8.0.1
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import * as QRCode from 'qrcode';
|
||||
|
||||
export type NewDeviceQrStatus =
|
||||
| 'confirming'
|
||||
| 'expired'
|
||||
@ -7,6 +9,7 @@ export type NewDeviceQrStatus =
|
||||
| 'verified';
|
||||
|
||||
export type NewDeviceQrCode = {
|
||||
deviceVerifyUrl?: string;
|
||||
pullQrCodeSig?: string;
|
||||
qrcodeUrl: string;
|
||||
sessionId: string;
|
||||
@ -44,13 +47,16 @@ export class NapcatLoginApiClient {
|
||||
data.qrcode,
|
||||
data.url,
|
||||
);
|
||||
if (!qrcodeUrl) {
|
||||
const jumpUrl = this.pickString(data.jumpUrl, data.verifyUrl);
|
||||
const newDeviceQrcodeUrl = qrcodeUrl || (await this.createQrcode(jumpUrl));
|
||||
if (!newDeviceQrcodeUrl) {
|
||||
throw new Error('NapCat 未返回新设备验证二维码');
|
||||
}
|
||||
|
||||
return {
|
||||
deviceVerifyUrl: jumpUrl || undefined,
|
||||
pullQrCodeSig: this.pickString(data.newDevicePullQrCodeSig, data.sig),
|
||||
qrcodeUrl,
|
||||
qrcodeUrl: newDeviceQrcodeUrl,
|
||||
sessionId,
|
||||
status: 'qr-pending',
|
||||
};
|
||||
@ -106,4 +112,14 @@ export class NapcatLoginApiClient {
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
private async createQrcode(text: string) {
|
||||
if (!text) return '';
|
||||
return QRCode.toDataURL(text, {
|
||||
errorCorrectionLevel: 'M',
|
||||
margin: 1,
|
||||
scale: 6,
|
||||
type: 'image/png',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,10 +9,20 @@ import {
|
||||
} from '@nestjs/common';
|
||||
import { ApiOperation, ApiQuery, ApiTags } from '@nestjs/swagger';
|
||||
import { JwtAuthGuard } from '@/modules/admin/identity/auth/jwt-auth.guard';
|
||||
import { vbenSuccess } from '@/common';
|
||||
import { ToolsService, vbenSuccess } from '@/common';
|
||||
import { QqbotEventPluginRegistryService } from './registry/qqbot-event-plugin-registry.service';
|
||||
import { QqbotPluginRegistryService } from './registry/qqbot-plugin-registry.service';
|
||||
import type { QqbotPluginTriggerMode } from '@/modules/qqbot/core/contract/qqbot.types';
|
||||
import type {
|
||||
QqbotPluginOperationSummary,
|
||||
QqbotPluginTriggerMode,
|
||||
} from '@/modules/qqbot/core/contract/qqbot.types';
|
||||
|
||||
type QqbotPluginOperationPageQuery = {
|
||||
pageNo?: number | string;
|
||||
pageSize?: number | string;
|
||||
pluginKey?: string;
|
||||
triggerMode?: QqbotPluginTriggerMode;
|
||||
};
|
||||
|
||||
@ApiTags('QQBot - 插件能力')
|
||||
@Controller('qqbot/plugin')
|
||||
@ -21,6 +31,7 @@ export class QqbotPluginController {
|
||||
constructor(
|
||||
private readonly eventPluginRegistry: QqbotEventPluginRegistryService,
|
||||
private readonly pluginRegistry: QqbotPluginRegistryService,
|
||||
private readonly toolsService: ToolsService,
|
||||
) {}
|
||||
|
||||
@Get('list')
|
||||
@ -60,14 +71,29 @@ export class QqbotPluginController {
|
||||
@Query('pluginKey') pluginKey?: string,
|
||||
@Query('triggerMode') triggerMode?: QqbotPluginTriggerMode,
|
||||
) {
|
||||
return vbenSuccess([
|
||||
...(this.includesTriggerMode('command', triggerMode)
|
||||
? this.pluginRegistry.listOperations(pluginKey)
|
||||
: []),
|
||||
...(this.includesTriggerMode('event', triggerMode)
|
||||
? this.eventPluginRegistry.listOperations(pluginKey)
|
||||
: []),
|
||||
]);
|
||||
return vbenSuccess(this.listOperations(pluginKey, triggerMode));
|
||||
}
|
||||
|
||||
@Get('operation/page')
|
||||
@ApiOperation({ summary: 'QQBot 插件能力分页列表' })
|
||||
@ApiQuery({ name: 'pageNo', required: false, type: Number })
|
||||
@ApiQuery({ name: 'pageSize', required: false, type: Number })
|
||||
@ApiQuery({ name: 'pluginKey', required: false, type: String })
|
||||
@ApiQuery({
|
||||
enum: ['command', 'event'],
|
||||
name: 'triggerMode',
|
||||
required: false,
|
||||
})
|
||||
async operationPage(@Query() query: QqbotPluginOperationPageQuery) {
|
||||
const { pageNo, pageSize, skip } = this.toolsService.getPageParams(query);
|
||||
const operations = this.listOperations(query.pluginKey, query.triggerMode);
|
||||
|
||||
return vbenSuccess({
|
||||
list: operations.slice(skip, skip + pageSize),
|
||||
pageNo,
|
||||
pageSize,
|
||||
total: operations.length,
|
||||
});
|
||||
}
|
||||
|
||||
@Get('health')
|
||||
@ -132,4 +158,18 @@ export class QqbotPluginController {
|
||||
) {
|
||||
return !triggerMode || triggerMode === target;
|
||||
}
|
||||
|
||||
private listOperations(
|
||||
pluginKey?: string,
|
||||
triggerMode?: QqbotPluginTriggerMode,
|
||||
): QqbotPluginOperationSummary[] {
|
||||
return [
|
||||
...(this.includesTriggerMode('command', triggerMode)
|
||||
? this.pluginRegistry.listOperations(pluginKey)
|
||||
: []),
|
||||
...(this.includesTriggerMode('event', triggerMode)
|
||||
? this.eventPluginRegistry.listOperations(pluginKey)
|
||||
: []),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,7 +110,8 @@ const initialLoadPromise = loadMainAPI(true).then(() => {
|
||||
loadMainAPI();
|
||||
});
|
||||
|
||||
setInterval(loadMainAPI, 1000 * 60 * 5); //5分钟更新一次
|
||||
const refreshTimer = setInterval(loadMainAPI, 1000 * 60 * 5); //5分钟更新一次
|
||||
refreshTimer.unref?.();
|
||||
|
||||
/**
|
||||
* 等待 BangDream 主数据完成首次加载。
|
||||
|
||||
@ -64,7 +64,7 @@ describe('NapCat new-device flow API client', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('normalizes waiting, expired, and failed poll responses without exposing jumpUrl as the completion mechanism', async () => {
|
||||
it('encodes jumpUrl as a QR image before polling new-device verification', async () => {
|
||||
const client = new NapcatLoginApiClient({
|
||||
post: jest
|
||||
.fn()
|
||||
@ -74,9 +74,15 @@ describe('NapCat new-device flow API client', () => {
|
||||
.mockResolvedValueOnce({ status: 'failed', message: 'denied' }),
|
||||
});
|
||||
|
||||
await expect(client.getNewDeviceQRCode('session-2')).rejects.toThrow(
|
||||
'NapCat 未返回新设备验证二维码',
|
||||
);
|
||||
const qr = await client.getNewDeviceQRCode('session-2');
|
||||
|
||||
expect(qr).toMatchObject({
|
||||
deviceVerifyUrl: 'https://qq.example/new-device',
|
||||
sessionId: 'session-2',
|
||||
status: 'qr-pending',
|
||||
});
|
||||
expect(qr.qrcodeUrl).toMatch(/^data:image\/png;base64,/);
|
||||
expect(qr.qrcodeUrl).not.toBe('https://qq.example/new-device');
|
||||
await expect(client.pollNewDeviceQR('session-2')).resolves.toEqual({
|
||||
message: undefined,
|
||||
sessionId: 'session-2',
|
||||
|
||||
@ -21,6 +21,7 @@ jest.mock('@/modules/qqbot/plugins/fflogs/qqbot-fflogs.plugin', () => ({
|
||||
import type { INestApplication } from '@nestjs/common';
|
||||
import { Test } from '@nestjs/testing';
|
||||
import * as request from 'supertest';
|
||||
import { ToolsService } from '../../../../src/common';
|
||||
import { QqbotBangDreamPluginService } from '../../../../src/modules/qqbot/plugins/bangDream/qqbot-bangdream.plugin';
|
||||
import { QqbotFf14MarketPluginService } from '../../../../src/modules/qqbot/plugins/ff14Market/qqbot-ff14-market.plugin';
|
||||
import { QqbotFflogsPluginService } from '../../../../src/modules/qqbot/plugins/fflogs/qqbot-fflogs.plugin';
|
||||
@ -53,6 +54,7 @@ describe('QQBot plugin controller local HTTP smoke', () => {
|
||||
const moduleRef = await Test.createTestingModule({
|
||||
controllers: [QqbotPluginController],
|
||||
providers: [
|
||||
ToolsService,
|
||||
QqbotPluginRegistryService,
|
||||
{
|
||||
provide: QqbotBangDreamPluginService,
|
||||
@ -115,4 +117,24 @@ describe('QQBot plugin controller local HTTP smoke', () => {
|
||||
triggerMode: 'command',
|
||||
});
|
||||
});
|
||||
|
||||
it('returns paged plugin operations for KtTable pagination', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.get('/qqbot/plugin/operation/page')
|
||||
.query({ pageNo: 2, pageSize: 1, triggerMode: 'command' })
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.data).toMatchObject({
|
||||
pageNo: 2,
|
||||
pageSize: 1,
|
||||
total: 3,
|
||||
});
|
||||
expect(response.body.data.list).toEqual([
|
||||
expect.objectContaining({
|
||||
key: 'ff14-market.operation',
|
||||
pluginKey: 'ff14-market',
|
||||
triggerMode: 'command',
|
||||
}),
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user