feat(theme-2): sync inbox/announcements/presence/deposit from main

This commit is contained in:
2026-06-18 09:38:33 +08:00
parent ec51b675e3
commit e56029225e
86 changed files with 6828 additions and 928 deletions

View File

@@ -0,0 +1,70 @@
import { PresenceService } from './presence.service';
describe('PresenceService', () => {
const pipeline = {
exists: jest.fn().mockReturnThis(),
exec: jest.fn(),
};
const redis = {
set: jest.fn(),
exists: jest.fn(),
raw: {
scan: jest.fn(),
pipeline: jest.fn(() => pipeline),
},
};
let service: PresenceService;
beforeEach(() => {
jest.clearAllMocks();
service = new PresenceService(redis as never);
});
it('touches player key with 120s TTL', async () => {
await service.touch(42n);
expect(redis.set).toHaveBeenCalledWith('presence:player:42', '1', 120);
});
it('checks single player online status', async () => {
redis.exists.mockResolvedValue(true);
await expect(service.isOnline(7n)).resolves.toBe(true);
expect(redis.exists).toHaveBeenCalledWith('presence:player:7');
});
it('counts online keys via SCAN', async () => {
redis.raw.scan
.mockResolvedValueOnce(['1', ['presence:player:1', 'presence:player:2']])
.mockResolvedValueOnce(['0', ['presence:player:3']]);
await expect(service.getOnlineCount()).resolves.toBe(3);
expect(redis.raw.scan).toHaveBeenCalledWith(
'0',
'MATCH',
'presence:player:*',
'COUNT',
200,
);
});
it('filters online ids with pipeline exists', async () => {
pipeline.exec.mockResolvedValue([
[null, 1],
[null, 0],
[null, 1],
]);
const result = await service.filterOnlineIds([10n, 20n, 30n]);
expect(result).toEqual(new Set(['10', '30']));
expect(pipeline.exists).toHaveBeenCalledTimes(3);
expect(pipeline.exists).toHaveBeenNthCalledWith(1, 'presence:player:10');
expect(pipeline.exists).toHaveBeenNthCalledWith(2, 'presence:player:20');
expect(pipeline.exists).toHaveBeenNthCalledWith(3, 'presence:player:30');
});
it('returns empty set when no ids provided', async () => {
await expect(service.filterOnlineIds([])).resolves.toEqual(new Set());
expect(redis.raw.pipeline).not.toHaveBeenCalled();
});
});