YouYiDianNotificationCenter/examples/node/notification-client.test.mjs
2026-07-16 21:00:33 +08:00

70 lines
2.6 KiB
JavaScript

import assert from 'node:assert/strict'
import crypto from 'node:crypto'
import test from 'node:test'
import { YouYiDianNotificationClient } from './notification-client.mjs'
const secret = 'example-project-secret-at-least-24-chars'
const verifySignature = (request) => {
const url = new URL(request.url)
const timestamp = request.init.headers['x-yyd-timestamp']
const nonce = request.init.headers['x-yyd-nonce']
const bodyHash = crypto.createHash('sha256').update(request.init.body || '').digest('hex')
const canonical = [timestamp, nonce, request.init.method, url.pathname.replace('/notification-center', ''), bodyHash].join('\n')
const expected = crypto.createHmac('sha256', secret).update(canonical).digest('hex')
assert.equal(request.init.headers['x-yyd-signature'], expected)
}
test('发送通知使用业务正文原文签名并返回投递记录', async () => {
const requests = []
const client = new YouYiDianNotificationClient({
baseUrl: 'https://sc.example.com/notification-center',
projectCode: 'fixed_asset',
projectSecret: secret,
fetchImpl: async (url, init) => {
requests.push({ url, init })
return new Response(JSON.stringify({ id: 'delivery-1', status: 'pending' }), {
status: 202,
headers: { 'content-type': 'application/json' },
})
},
})
const payload = {
idempotencyKey: 'asset_disposal:53:user-1:v1',
recipientUserId: 'user-1',
title: '资产报废待审批',
content: '**申请时间:** 2026年7月16日 14:30',
actionTitle: '立即审批',
actionUrl: 'https://asset.example.com/workflows/disposals/53',
}
const delivery = await client.send(payload)
assert.deepEqual(delivery, { id: 'delivery-1', status: 'pending' })
assert.equal(requests.length, 1)
assert.equal(requests[0].url, 'https://sc.example.com/notification-center/v1/notifications')
assert.equal(requests[0].init.body, JSON.stringify(payload))
verifySignature(requests[0])
})
test('查询通知使用空正文签名', async () => {
let request
const client = new YouYiDianNotificationClient({
baseUrl: 'https://sc.example.com/notification-center',
projectCode: 'fixed_asset',
projectSecret: secret,
fetchImpl: async (url, init) => {
request = { url, init }
return new Response(JSON.stringify({ id: 'delivery-1', status: 'read' }), {
status: 200,
headers: { 'content-type': 'application/json' },
})
},
})
const delivery = await client.getDelivery('delivery-1')
assert.equal(delivery.status, 'read')
assert.equal(request.init.body, undefined)
verifySignature(request)
})