SnowLuma v2.4.2 source snapshot
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
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
This commit is contained in:
commit
fa9c73363d
1367 files changed
+355735
No files matched your search
@@ -0,0 +1,97 @@
|
||||
import { describe, it, expect, vi } from 'vitest';
|
||||
import { OneBotNetworkManager } from '../src/network/network-manager';
|
||||
import type { ApiActionContext } from '../src/api-handler';
|
||||
import { createCompiledTestHandler, testAction } from './helpers/compiled-action-handler';
|
||||
|
||||
// ApiHandler's register* only define handlers (closures) at construction — they
|
||||
// don't touch ctx — so a throwing proxy is a safe minimal context.
|
||||
function fakeCtx(): ApiActionContext {
|
||||
return new Proxy({} as ApiActionContext, {
|
||||
get(_t, prop) {
|
||||
throw new Error(`ctx.${String(prop)} not stubbed`);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
describe('OneBotNetworkManager.subscribeDebug', () => {
|
||||
it('notifies debug subscribers on emitEvent even with no active adapters', async () => {
|
||||
const nm = new OneBotNetworkManager();
|
||||
const seen: unknown[] = [];
|
||||
nm.subscribeDebug((e) => seen.push(e));
|
||||
await nm.emitEvent({ post_type: 'meta_event', x: 1 });
|
||||
expect(seen).toEqual([{ post_type: 'meta_event', x: 1 }]);
|
||||
});
|
||||
|
||||
it('stops notifying after unsubscribe', async () => {
|
||||
const nm = new OneBotNetworkManager();
|
||||
const cb = vi.fn();
|
||||
const off = nm.subscribeDebug(cb);
|
||||
await nm.emitEvent({ a: 1 });
|
||||
off();
|
||||
await nm.emitEvent({ a: 2 });
|
||||
expect(cb).toHaveBeenCalledTimes(1);
|
||||
expect(cb).toHaveBeenCalledWith({ a: 1 });
|
||||
});
|
||||
|
||||
it('a throwing subscriber does not break emitEvent', async () => {
|
||||
const nm = new OneBotNetworkManager();
|
||||
nm.subscribeDebug(() => {
|
||||
throw new Error('boom');
|
||||
});
|
||||
await expect(nm.emitEvent({ a: 1 })).resolves.toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('ApiHandler.setObserver', () => {
|
||||
it('fires after a successful action with {action, params, response, ms}', async () => {
|
||||
const h = createCompiledTestHandler(fakeCtx(), [
|
||||
testAction('ping', async () => ({ status: 'ok', retcode: 0, data: 'pong' })),
|
||||
]);
|
||||
const recs: Array<{ action: string; response: { status: string } }> = [];
|
||||
h.setObserver((r) => recs.push(r as any));
|
||||
const res = await h.handle('ping', { x: 1 });
|
||||
expect(res).toMatchObject({ status: 'ok', data: 'pong' });
|
||||
expect(recs).toHaveLength(1);
|
||||
expect(recs[0]).toMatchObject({
|
||||
action: 'ping',
|
||||
params: { x: 1 },
|
||||
response: { status: 'ok' },
|
||||
});
|
||||
expect(typeof (recs[0] as any).ms).toBe('number');
|
||||
});
|
||||
|
||||
it('fires on a thrown action with the failure response', async () => {
|
||||
const h = createCompiledTestHandler(fakeCtx(), [
|
||||
testAction('boom', async () => {
|
||||
throw new Error('kaboom');
|
||||
}),
|
||||
]);
|
||||
const recs: any[] = [];
|
||||
h.setObserver((r) => recs.push(r));
|
||||
await h.handle('boom', {});
|
||||
expect(recs).toHaveLength(1);
|
||||
expect(recs[0].response.status).toBe('failed');
|
||||
});
|
||||
|
||||
it('unsubscribe stops observation', async () => {
|
||||
const h = createCompiledTestHandler(fakeCtx(), [
|
||||
testAction('ping', async () => ({ status: 'ok', retcode: 0 })),
|
||||
]);
|
||||
const cb = vi.fn();
|
||||
const off = h.setObserver(cb);
|
||||
await h.handle('ping', {});
|
||||
off();
|
||||
await h.handle('ping', {});
|
||||
expect(cb).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('a throwing observer does not break handle', async () => {
|
||||
const h = createCompiledTestHandler(fakeCtx(), [
|
||||
testAction('ping', async () => ({ status: 'ok', retcode: 0 })),
|
||||
]);
|
||||
h.setObserver(() => {
|
||||
throw new Error('observer boom');
|
||||
});
|
||||
await expect(h.handle('ping', {})).resolves.toMatchObject({ status: 'ok' });
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user