forked from wangziqi/gongxue-base
98 lines
3.0 KiB
TypeScript
98 lines
3.0 KiB
TypeScript
import { DingTalkService } from '../integration/dingtalk.service';
|
|
|
|
|
|
describe('DingTalkService — attendance records', () => {
|
|
const originalAppKey = process.env.DINGTALK_APP_KEY;
|
|
const originalAppSecret = process.env.DINGTALK_APP_SECRET;
|
|
let service: DingTalkService;
|
|
|
|
beforeEach(() => {
|
|
process.env.DINGTALK_APP_KEY = 'test-app-key';
|
|
process.env.DINGTALK_APP_SECRET = 'test-app-secret';
|
|
service = new DingTalkService({} as never, {} as never);
|
|
Object.assign(service, {
|
|
accessToken: 'test-token',
|
|
accessTokenCredentialKey: 'test-app-key:test-app-secret',
|
|
tokenExpiresAt: Date.now() + 3_600_000,
|
|
});
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.restoreAllMocks();
|
|
global.fetch = undefined as unknown as typeof fetch;
|
|
});
|
|
|
|
afterAll(() => {
|
|
if (originalAppKey === undefined) delete process.env.DINGTALK_APP_KEY;
|
|
else process.env.DINGTALK_APP_KEY = originalAppKey;
|
|
if (originalAppSecret === undefined) delete process.env.DINGTALK_APP_SECRET;
|
|
else process.env.DINGTALK_APP_SECRET = originalAppSecret;
|
|
});
|
|
|
|
it('sends the required userIds and does not send unsupported offset/limit fields', async () => {
|
|
global.fetch = jest.fn().mockResolvedValue({
|
|
json: jest.fn().mockResolvedValue({ errcode: 0, errmsg: 'ok', recordresult: [] }),
|
|
}) as jest.MockedFunction<typeof fetch>;
|
|
|
|
await service.fetchAttendanceResults({
|
|
startDate: '2026-07-01',
|
|
endDate: '2026-07-07',
|
|
userIds: ['ding-1', 'ding-2'],
|
|
});
|
|
|
|
expect(JSON.parse((global.fetch as jest.Mock).mock.calls[0][1].body)).toEqual({
|
|
checkDateFrom: '2026-07-01 00:00:00',
|
|
checkDateTo: '2026-07-07 23:59:59',
|
|
userIds: ['ding-1', 'ding-2'],
|
|
});
|
|
});
|
|
|
|
it('rejects missing userIds before calling DingTalk', async () => {
|
|
await expect(
|
|
service.fetchAttendanceResults({
|
|
startDate: '2026-07-01',
|
|
endDate: '2026-07-01',
|
|
}),
|
|
).rejects.toThrow('userIds');
|
|
expect(global.fetch).toBeUndefined();
|
|
});
|
|
|
|
it('keeps DingTalk work dates in China local time', async () => {
|
|
global.fetch = jest.fn().mockResolvedValue({
|
|
json: jest.fn().mockResolvedValue({
|
|
errcode: 0,
|
|
errmsg: 'ok',
|
|
recordresult: [
|
|
{
|
|
id: 1,
|
|
userId: 'ding-1',
|
|
workDate: Date.parse('2026-07-12T00:00:00+08:00'),
|
|
userCheckTime: Date.parse('2026-07-12T21:05:00+08:00'),
|
|
sourceType: 'ATM',
|
|
checkType: 'OnDuty',
|
|
deviceName: '东门考勤机',
|
|
deviceId: 'ATM-01',
|
|
timeResult: 'Normal',
|
|
},
|
|
],
|
|
}),
|
|
}) as jest.MockedFunction<typeof fetch>;
|
|
|
|
const [record] = await service.fetchAttendanceResults({
|
|
startDate: '2026-07-12',
|
|
endDate: '2026-07-12',
|
|
userIds: ['ding-1'],
|
|
});
|
|
|
|
expect(record.workDate).toBe('2026-07-12');
|
|
expect(record).toEqual(
|
|
expect.objectContaining({
|
|
checkType: 'OnDuty',
|
|
sourceType: 'ATM',
|
|
deviceName: '东门考勤机',
|
|
deviceId: 'ATM-01',
|
|
}),
|
|
);
|
|
});
|
|
});
|