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,152 @@
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
import type { SendPacketResult } from '@snowluma/common/packet-sender';
|
||||
import { GetAdminReceiveVerify } from '../../../src/oidb-services/group-admin/get-admin-receive-verify';
|
||||
import { env, m, s, v } from '../_pb-oracle';
|
||||
|
||||
const target = { groupId: 12345, userId: 67890 };
|
||||
const uid = 'test-member-uid';
|
||||
|
||||
function member(flag?: number, memberUid = uid, uin: number | undefined = target.userId) {
|
||||
return m(2, [
|
||||
...m(1, [...s(2, memberUid), ...(uin === undefined ? [] : v(4, uin))]),
|
||||
...(flag === undefined ? [] : v(104, flag)),
|
||||
]);
|
||||
}
|
||||
|
||||
function response(members: number[], group: number | undefined = target.groupId) {
|
||||
return m(4, [...(group === undefined ? [] : v(1, group)), ...members]);
|
||||
}
|
||||
|
||||
function sender(body = response(member(0))) {
|
||||
const result: SendPacketResult = {
|
||||
success: true,
|
||||
gotResponse: true,
|
||||
errorCode: 0,
|
||||
errorMessage: '',
|
||||
responseData: Buffer.from(body),
|
||||
};
|
||||
return {
|
||||
sendRawPacket: vi.fn(async (_command: string, _bytes: Uint8Array) => result),
|
||||
resolveUserUid: vi.fn(async (_userId: number, _groupId?: number) => uid),
|
||||
};
|
||||
}
|
||||
|
||||
describe('administrator receive-verification read', () => {
|
||||
it('resolves the member once in its group and requests only the verification state', async () => {
|
||||
const deps = sender();
|
||||
await expect(GetAdminReceiveVerify.invoke(deps, target)).resolves.toBe(true);
|
||||
expect(deps.resolveUserUid).toHaveBeenCalledExactlyOnceWith(target.userId, target.groupId);
|
||||
expect(deps.sendRawPacket).toHaveBeenCalledTimes(1);
|
||||
const [command, bytes] = deps.sendRawPacket.mock.calls[0]!;
|
||||
expect(command).toBe('OidbSvcTrpcTcp.0xfe7_4');
|
||||
expect(Buffer.from(bytes).toString('hex')).toBe(
|
||||
env(
|
||||
0xfe7,
|
||||
4,
|
||||
[
|
||||
...v(1, target.groupId),
|
||||
...v(2, 3),
|
||||
...v(3, 0),
|
||||
...m(4, v(104, 1)),
|
||||
...m(5, s(2, uid)),
|
||||
],
|
||||
false,
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
it.each([
|
||||
[0, true],
|
||||
[64, false],
|
||||
[32, true],
|
||||
[96, false],
|
||||
[0x80000000, true],
|
||||
[0xffffffff, false],
|
||||
[undefined, null],
|
||||
] as const)('decodes flag %s as %s while preserving missing data', async (flag, enabled) => {
|
||||
const deps = sender(response(member(flag)));
|
||||
await expect(GetAdminReceiveVerify.invoke(deps, target)).resolves.toBe(enabled);
|
||||
});
|
||||
|
||||
it('selects the requested member even when unrelated members are returned first', async () => {
|
||||
const deps = sender(response([...member(64, 'unrelated-member', 10001), ...member(0)]));
|
||||
await expect(GetAdminReceiveVerify.invoke(deps, target)).resolves.toBe(true);
|
||||
});
|
||||
|
||||
it('accepts UID-bound responses without an optional numeric identity', async () => {
|
||||
const deps = sender(response(m(2, [...m(1, s(2, uid)), ...v(104, 64)])));
|
||||
await expect(GetAdminReceiveVerify.invoke(deps, target)).resolves.toBe(false);
|
||||
});
|
||||
|
||||
it('preserves large numeric group and member identifiers', async () => {
|
||||
const large = { groupId: 2 ** 40 + 17, userId: 2 ** 41 + 19 };
|
||||
const deps = sender(response(member(0, uid, large.userId), large.groupId));
|
||||
await expect(GetAdminReceiveVerify.invoke(deps, large)).resolves.toBe(true);
|
||||
expect(Buffer.from(deps.sendRawPacket.mock.calls[0]![1]).toString('hex')).toBe(
|
||||
env(
|
||||
0xfe7,
|
||||
4,
|
||||
[
|
||||
...v(1, large.groupId),
|
||||
...v(2, 3),
|
||||
...v(3, 0),
|
||||
...m(4, v(104, 1)),
|
||||
...m(5, s(2, uid)),
|
||||
],
|
||||
false,
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
it.each([
|
||||
['missing group', m(4, member(0)), 'missing or mismatched group'],
|
||||
['wrong group', response(member(0), 999), 'missing or mismatched group'],
|
||||
['missing member', response([]), 'exactly one matching member'],
|
||||
['wrong member', response(member(0, 'other-uid')), 'exactly one matching member'],
|
||||
[
|
||||
'missing UID',
|
||||
response(m(2, [...m(1, v(4, target.userId)), ...v(104, 0)])),
|
||||
'exactly one matching member',
|
||||
],
|
||||
[
|
||||
'duplicate member',
|
||||
response([...member(0), ...member(64)]),
|
||||
'exactly one matching member',
|
||||
],
|
||||
['conflicting numeric identity', response(member(0, uid, 999)), 'mismatched member UIN'],
|
||||
] as const)(
|
||||
'rejects %s rather than reporting a successful state',
|
||||
async (_label, body, error) => {
|
||||
const deps = sender([...body]);
|
||||
await expect(GetAdminReceiveVerify.invoke(deps, target)).rejects.toThrow(error);
|
||||
},
|
||||
);
|
||||
|
||||
it('does not send when identity resolution fails', async () => {
|
||||
const deps = sender();
|
||||
deps.resolveUserUid.mockRejectedValueOnce(new Error('identity unavailable'));
|
||||
await expect(GetAdminReceiveVerify.invoke(deps, target)).rejects.toThrow(
|
||||
'identity unavailable',
|
||||
);
|
||||
expect(deps.sendRawPacket).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('propagates server rejection even if the body contains a valid state', async () => {
|
||||
const deps = sender([...v(3, 1287), ...response(member(0))]);
|
||||
await expect(GetAdminReceiveVerify.invoke(deps, target)).rejects.toThrow('OIDB error 1287');
|
||||
});
|
||||
|
||||
it('propagates transport failures without retrying', async () => {
|
||||
const deps = sender();
|
||||
deps.sendRawPacket.mockRejectedValueOnce(new Error('transport disconnected'));
|
||||
await expect(GetAdminReceiveVerify.invoke(deps, target)).rejects.toThrow(
|
||||
'transport disconnected',
|
||||
);
|
||||
expect(deps.sendRawPacket).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('rejects truncated responses', async () => {
|
||||
const deps = sender([0x22, 0x80]);
|
||||
await expect(GetAdminReceiveVerify.invoke(deps, target)).rejects.toThrow();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user