gongxiangp2/lib/__tests__/dingtalk-client.test.ts
2026-07-07 09:31:46 +08:00

124 lines
4.6 KiB
TypeScript

/** @jest-environment node */
describe('dingtalk client', () => {
const originalEnv = process.env
beforeEach(() => {
jest.resetModules()
process.env = { ...originalEnv }
delete process.env.DINGTALK_CLIENT_ID
delete process.env.DINGTALK_CLIENT_SECRET
delete process.env.DINGTALK_WORK_NOTICE_CLIENT_ID
delete process.env.DINGTALK_WORK_NOTICE_CLIENT_SECRET
delete process.env.DINGTALK_WORK_NOTICE_AGENT_ID
delete process.env.DINGTALK_WORK_NOTICE_CORP_ID
delete process.env.DINGTALK_CORP_ID
delete process.env.DINGTALK_CORPID
delete process.env.NEXT_PUBLIC_DINGTALK_CORP_ID
global.fetch = jest.fn()
})
afterEach(() => {
process.env = originalEnv
jest.restoreAllMocks()
})
test('工作通知优先使用独立应用凭证获取 token', async () => {
process.env.DINGTALK_CLIENT_ID = 'login-client-id'
process.env.DINGTALK_CLIENT_SECRET = 'login-client-secret'
process.env.DINGTALK_WORK_NOTICE_CLIENT_ID = 'notice-client-id'
process.env.DINGTALK_WORK_NOTICE_CLIENT_SECRET = 'notice-client-secret'
process.env.DINGTALK_WORK_NOTICE_AGENT_ID = '4279191869'
;(global.fetch as jest.Mock)
.mockResolvedValueOnce({
ok: true,
json: async () => ({ errcode: 0, access_token: 'notice-token', expires_in: 7200 }),
})
.mockResolvedValueOnce({
ok: true,
json: async () => ({ errcode: 0, task_id: 123, request_id: 'request-1' }),
})
const { sendDingtalkWorkNotice } = await import('@/lib/dingtalk-client')
await sendDingtalkWorkNotice({
userIds: ['ding-user-1'],
title: '测试通知',
text: '这是一条测试通知',
})
expect(global.fetch).toHaveBeenNthCalledWith(
1,
expect.stringContaining('appkey=notice-client-id'),
)
expect(global.fetch).toHaveBeenNthCalledWith(
1,
expect.not.stringContaining('appkey=login-client-id'),
)
const [, sendOptions] = (global.fetch as jest.Mock).mock.calls[1]
expect(JSON.parse(sendOptions.body)).toEqual(expect.objectContaining({
agent_id: 4279191869,
userid_list: 'ding-user-1',
}))
})
test('工作通知未配置独立凭证时仍可复用登录应用凭证', async () => {
process.env.DINGTALK_CLIENT_ID = 'login-client-id'
process.env.DINGTALK_CLIENT_SECRET = 'login-client-secret'
process.env.DINGTALK_WORK_NOTICE_AGENT_ID = '123'
const { getDingtalkWorkNoticeConfigStatus } = await import('@/lib/dingtalk-client')
expect(getDingtalkWorkNoticeConfigStatus()).toEqual(expect.objectContaining({
ready: true,
appSource: 'login',
}))
})
test('工作通知免登入口优先使用工作通知应用 clientId', async () => {
process.env.DINGTALK_CLIENT_ID = 'login-client-id'
process.env.DINGTALK_CLIENT_SECRET = 'login-client-secret'
process.env.DINGTALK_WORK_NOTICE_CLIENT_ID = 'notice-client-id'
process.env.DINGTALK_WORK_NOTICE_CLIENT_SECRET = 'notice-client-secret'
const { getDingtalkWorkNoticeClientId } = await import('@/lib/dingtalk-client')
expect(getDingtalkWorkNoticeClientId()).toBe('notice-client-id')
})
test('带跳转地址的工作通知优先使用钉钉应用内打开链接', async () => {
process.env.DINGTALK_CLIENT_ID = 'login-client-id'
process.env.DINGTALK_CLIENT_SECRET = 'login-client-secret'
process.env.DINGTALK_WORK_NOTICE_AGENT_ID = '4279191869'
process.env.DINGTALK_CORP_ID = 'ding-test-corp'
;(global.fetch as jest.Mock)
.mockResolvedValueOnce({
ok: true,
json: async () => ({ errcode: 0, access_token: 'notice-token', expires_in: 7200 }),
})
.mockResolvedValueOnce({
ok: true,
json: async () => ({ errcode: 0, task_id: 123, request_id: 'request-1' }),
})
const { sendDingtalkWorkNotice } = await import('@/lib/dingtalk-client')
await sendDingtalkWorkNotice({
userIds: ['ding-user-1'],
title: '测试通知',
text: '这是一条测试通知',
actionUrl: 'https://sc.jiansun.vip/dingtalk-entry?redirect=%2Fperformance-survey',
})
const [, sendOptions] = (global.fetch as jest.Mock).mock.calls[1]
const body = JSON.parse(sendOptions.body)
expect(body.msg.msgtype).toBe('action_card')
expect(body.msg.action_card.single_url).toContain('dingtalk://dingtalkclient/action/openapp')
expect(body.msg.action_card.single_url).toContain('corpid=ding-test-corp')
expect(body.msg.action_card.single_url).toContain('app_id=0_4279191869')
expect(body.msg.action_card.single_url).toContain(encodeURIComponent('https://sc.jiansun.vip/dingtalk-entry?redirect=%2Fperformance-survey'))
})
})