Dev Build / cleanup (push) Waiting to run
Dev Build / typecheck (push) Waiting to run
Publish MCP to npm / Build, test, and publish MCP (push) Waiting to run
Publish SDK to npm / Build, test, and publish SDK (push) Waiting to run
Sync action catalog to docs / sync (push) Waiting to run
Publish UI to npm / Build and publish UI (push) Waiting to run
Build and Release / preflight (push) Waiting to run
100 lines
4.1 KiB
TypeScript
100 lines
4.1 KiB
TypeScript
import { describe, expect, it, vi } from 'vitest';
|
|
import { ApiHandler, type ApiActionContext } from '../src/api-handler';
|
|
import { ACTION_REGISTRY } from '../src/actions';
|
|
import { RETCODE, type JsonObject } from '../src/types';
|
|
|
|
function setup() {
|
|
const getGroupShareLink = vi.fn().mockResolvedValue('https://qm.qq.com/q/example');
|
|
const api = new ApiHandler({
|
|
bridge: { apis: { contacts: { getGroupShareLink } } },
|
|
} as unknown as ApiActionContext);
|
|
return { api, getGroupShareLink };
|
|
}
|
|
|
|
describe('get_group_share_link', () => {
|
|
it('returns the requested result shape with the documented defaults', async () => {
|
|
const { api, getGroupShareLink } = setup();
|
|
const response = await api.handle('get_group_share_link', { group_id: 12345 });
|
|
|
|
expect(response).toMatchObject({
|
|
status: 'ok',
|
|
retcode: 0,
|
|
data: { url: 'https://qm.qq.com/q/example' },
|
|
});
|
|
expect(getGroupShareLink).toHaveBeenCalledExactlyOnceWith(12345, true, 73, '');
|
|
});
|
|
|
|
it('accepts numeric strings and preserves explicit false, zero, and additional parameters', async () => {
|
|
const { api, getGroupShareLink } = setup();
|
|
const response = await api.handle('get_group_share_link', {
|
|
group_id: '12345',
|
|
need_short_url: 'false',
|
|
src_id: '0',
|
|
additional_param: 'source=二维码&test=1',
|
|
});
|
|
|
|
expect(response.status).toBe('ok');
|
|
expect(getGroupShareLink).toHaveBeenCalledExactlyOnceWith(
|
|
12345,
|
|
false,
|
|
0,
|
|
'source=二维码&test=1',
|
|
);
|
|
});
|
|
|
|
it.each<{ field: string; params: JsonObject }>([
|
|
{ field: 'group_id', params: {} },
|
|
{ field: 'group_id', params: { group_id: 0 } },
|
|
{ field: 'group_id', params: { group_id: -1 } },
|
|
{ field: 'group_id', params: { group_id: 'invalid' } },
|
|
{ field: 'need_short_url', params: { group_id: 12345, need_short_url: 'invalid' } },
|
|
{ field: 'src_id', params: { group_id: 12345, src_id: -1 } },
|
|
{ field: 'src_id', params: { group_id: 12345, src_id: 0x100000000 } },
|
|
{ field: 'src_id', params: { group_id: 12345, src_id: 'invalid' } },
|
|
{ field: 'additional_param', params: { group_id: 12345, additional_param: {} } },
|
|
])('rejects invalid $field before requesting a link', async ({ field, params }) => {
|
|
const { api, getGroupShareLink } = setup();
|
|
const response = await api.handle('get_group_share_link', params);
|
|
|
|
expect(response).toMatchObject({ status: 'failed', retcode: RETCODE.BAD_REQUEST });
|
|
expect(response.wording).toContain(field);
|
|
expect(getGroupShareLink).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('surfaces the failure through the shared action error handler', async () => {
|
|
const { api, getGroupShareLink } = setup();
|
|
getGroupShareLink.mockRejectedValue(new Error('group share link unavailable'));
|
|
|
|
await expect(
|
|
api.handle('get_group_share_link', { group_id: 12345 }),
|
|
).resolves.toMatchObject({
|
|
status: 'failed',
|
|
retcode: RETCODE.ACTION_FAILED,
|
|
data: null,
|
|
wording: 'group share link unavailable',
|
|
});
|
|
});
|
|
|
|
it('publishes its complete parameter and result contract', () => {
|
|
const action = ACTION_REGISTRY.actions.find(
|
|
(entry) => entry.canonical === 'get_group_share_link',
|
|
);
|
|
expect(action).toBeDefined();
|
|
const doc = action!.spec.describe();
|
|
|
|
expect(doc.readOnly).toBe(true);
|
|
expect(doc.params).toEqual(
|
|
expect.arrayContaining([
|
|
expect.objectContaining({ name: 'group_id', required: true }),
|
|
expect.objectContaining({ name: 'need_short_url', default: true }),
|
|
expect.objectContaining({ name: 'src_id', default: 73 }),
|
|
expect.objectContaining({ name: 'additional_param', default: '' }),
|
|
]),
|
|
);
|
|
expect(doc.returnsSchema).toMatchObject({
|
|
properties: { url: { type: 'string' } },
|
|
required: ['url'],
|
|
});
|
|
});
|
|
});
|