367 lines
6.5 KiB
JavaScript
367 lines
6.5 KiB
JavaScript
/**
|
|
* 钉钉 API 响应数据夹具
|
|
* 包含各种钉钉 API 响应用于测试
|
|
*/
|
|
|
|
// 成功响应
|
|
export const successResponses = {
|
|
// 标准成功响应
|
|
standard: {
|
|
errcode: 0,
|
|
errmsg: 'ok',
|
|
},
|
|
|
|
// 带消息 ID 的成功响应
|
|
withMessageId: {
|
|
errcode: 0,
|
|
errmsg: 'ok',
|
|
message_id: 'msg789012',
|
|
},
|
|
};
|
|
|
|
// 错误响应
|
|
export const errorResponses = {
|
|
// 无效的 access_token
|
|
invalidToken: {
|
|
errcode: 310000,
|
|
errmsg: 'keywords not in content',
|
|
},
|
|
|
|
// 消息内容中不包含任何关键词
|
|
noKeywords: {
|
|
errcode: 310000,
|
|
errmsg: 'keywords not in content',
|
|
},
|
|
|
|
// 消息发送频率超过限制
|
|
rateLimited: {
|
|
errcode: 130101,
|
|
errmsg: 'send too fast',
|
|
},
|
|
|
|
// 机器人被停用
|
|
robotDisabled: {
|
|
errcode: 300001,
|
|
errmsg: 'robot is disabled',
|
|
},
|
|
|
|
// 签名验证失败
|
|
signatureError: {
|
|
errcode: 310000,
|
|
errmsg: 'sign not match',
|
|
},
|
|
|
|
// IP 地址不在白名单中
|
|
ipNotAllowed: {
|
|
errcode: 310000,
|
|
errmsg: 'ip not allow',
|
|
},
|
|
|
|
// 消息格式错误
|
|
invalidFormat: {
|
|
errcode: 300002,
|
|
errmsg: 'param is invalid',
|
|
},
|
|
|
|
// 消息内容为空
|
|
emptyContent: {
|
|
errcode: 300003,
|
|
errmsg: 'content is empty',
|
|
},
|
|
|
|
// 消息长度超过限制
|
|
contentTooLong: {
|
|
errcode: 300004,
|
|
errmsg: 'content too long',
|
|
},
|
|
|
|
// @ 的手机号格式错误
|
|
invalidMobile: {
|
|
errcode: 300005,
|
|
errmsg: 'mobile format error',
|
|
},
|
|
|
|
// ActionCard 按钮数量超过限制
|
|
tooManyButtons: {
|
|
errcode: 300006,
|
|
errmsg: 'too many buttons',
|
|
},
|
|
|
|
// FeedCard 链接数量超过限制
|
|
tooManyLinks: {
|
|
errcode: 300007,
|
|
errmsg: 'too many links',
|
|
},
|
|
|
|
// 服务器内部错误
|
|
internalError: {
|
|
errcode: 500000,
|
|
errmsg: 'internal server error',
|
|
},
|
|
|
|
// 服务不可用
|
|
serviceUnavailable: {
|
|
errcode: 503000,
|
|
errmsg: 'service unavailable',
|
|
},
|
|
};
|
|
|
|
// HTTP 状态码响应
|
|
export const httpStatusResponses = {
|
|
// 200 OK
|
|
ok: {
|
|
statusCode: 200,
|
|
data: successResponses.standard,
|
|
},
|
|
|
|
// 400 Bad Request
|
|
badRequest: {
|
|
statusCode: 400,
|
|
data: {
|
|
errcode: 400000,
|
|
errmsg: 'bad request',
|
|
},
|
|
},
|
|
|
|
// 401 Unauthorized
|
|
unauthorized: {
|
|
statusCode: 401,
|
|
data: {
|
|
errcode: 401000,
|
|
errmsg: 'unauthorized',
|
|
},
|
|
},
|
|
|
|
// 403 Forbidden
|
|
forbidden: {
|
|
statusCode: 403,
|
|
data: {
|
|
errcode: 403000,
|
|
errmsg: 'forbidden',
|
|
},
|
|
},
|
|
|
|
// 404 Not Found
|
|
notFound: {
|
|
statusCode: 404,
|
|
data: {
|
|
errcode: 404000,
|
|
errmsg: 'not found',
|
|
},
|
|
},
|
|
|
|
// 429 Too Many Requests
|
|
tooManyRequests: {
|
|
statusCode: 429,
|
|
data: errorResponses.rateLimited,
|
|
},
|
|
|
|
// 500 Internal Server Error
|
|
internalServerError: {
|
|
statusCode: 500,
|
|
data: errorResponses.internalError,
|
|
},
|
|
|
|
// 502 Bad Gateway
|
|
badGateway: {
|
|
statusCode: 502,
|
|
data: {
|
|
errcode: 502000,
|
|
errmsg: 'bad gateway',
|
|
},
|
|
},
|
|
|
|
// 503 Service Unavailable
|
|
serviceUnavailable: {
|
|
statusCode: 503,
|
|
data: errorResponses.serviceUnavailable,
|
|
},
|
|
|
|
// 504 Gateway Timeout
|
|
gatewayTimeout: {
|
|
statusCode: 504,
|
|
data: {
|
|
errcode: 504000,
|
|
errmsg: 'gateway timeout',
|
|
},
|
|
},
|
|
};
|
|
|
|
// 网络错误响应
|
|
export const networkErrors = {
|
|
// 连接被拒绝
|
|
connectionRefused: {
|
|
code: 'ECONNREFUSED',
|
|
message: 'connect ECONNREFUSED 127.0.0.1:443',
|
|
},
|
|
|
|
// 连接超时
|
|
connectionTimeout: {
|
|
code: 'ETIMEDOUT',
|
|
message: 'connect ETIMEDOUT',
|
|
},
|
|
|
|
// DNS 解析失败
|
|
dnsError: {
|
|
code: 'ENOTFOUND',
|
|
message: 'getaddrinfo ENOTFOUND oapi.dingtalk.com',
|
|
},
|
|
|
|
// 网络不可达
|
|
networkUnreachable: {
|
|
code: 'ENETUNREACH',
|
|
message: 'network is unreachable',
|
|
},
|
|
|
|
// 连接被重置
|
|
connectionReset: {
|
|
code: 'ECONNRESET',
|
|
message: 'socket hang up',
|
|
},
|
|
|
|
// SSL/TLS 错误
|
|
sslError: {
|
|
code: 'DEPTH_ZERO_SELF_SIGNED_CERT',
|
|
message: 'self signed certificate',
|
|
},
|
|
};
|
|
|
|
// 特殊响应场景
|
|
export const specialResponses = {
|
|
// 空响应体
|
|
emptyBody: {
|
|
statusCode: 200,
|
|
data: '',
|
|
},
|
|
|
|
// 非 JSON 响应
|
|
nonJsonResponse: {
|
|
statusCode: 200,
|
|
data: 'This is not JSON',
|
|
},
|
|
|
|
// 格式错误的 JSON
|
|
malformedJson: {
|
|
statusCode: 200,
|
|
data: '{"errcode": 0, "errmsg": "ok"',
|
|
},
|
|
|
|
// 缺少必需字段的响应
|
|
missingFields: {
|
|
statusCode: 200,
|
|
data: {
|
|
errcode: 0,
|
|
// 缺少 errmsg
|
|
},
|
|
},
|
|
|
|
// 字段类型错误的响应
|
|
wrongFieldTypes: {
|
|
statusCode: 200,
|
|
data: {
|
|
errcode: '0', // 应该是数字
|
|
errmsg: 123, // 应该是字符串
|
|
},
|
|
},
|
|
};
|
|
|
|
// 响应时间模拟
|
|
export const responseTimings = {
|
|
// 快速响应 (< 100ms)
|
|
fast: 50,
|
|
|
|
// 正常响应 (100-500ms)
|
|
normal: 200,
|
|
|
|
// 慢响应 (500-2000ms)
|
|
slow: 1000,
|
|
|
|
// 非常慢的响应 (> 2000ms)
|
|
verySlow: 3000,
|
|
|
|
// 超时响应 (> 5000ms)
|
|
timeout: 6000,
|
|
};
|
|
|
|
// 批量响应场景
|
|
export const batchResponses = {
|
|
// 全部成功
|
|
allSuccess: [
|
|
successResponses.standard,
|
|
successResponses.withMessageId,
|
|
successResponses.standard,
|
|
],
|
|
|
|
// 部分失败
|
|
partialFailure: [
|
|
successResponses.standard,
|
|
errorResponses.rateLimited,
|
|
successResponses.standard,
|
|
],
|
|
|
|
// 全部失败
|
|
allFailure: [
|
|
errorResponses.invalidToken,
|
|
errorResponses.rateLimited,
|
|
errorResponses.robotDisabled,
|
|
],
|
|
};
|
|
|
|
// 用于测试的完整响应对象
|
|
export const fullResponses = {
|
|
textSuccess: {
|
|
request: {
|
|
msgtype: 'text',
|
|
text: {
|
|
content: 'Hello, World!',
|
|
},
|
|
at: {
|
|
atMobiles: [],
|
|
atUserIds: [],
|
|
isAtAll: false,
|
|
},
|
|
},
|
|
response: successResponses.standard,
|
|
},
|
|
|
|
markdownSuccess: {
|
|
request: {
|
|
msgtype: 'markdown',
|
|
markdown: {
|
|
title: 'Markdown 标题',
|
|
text: '## 标题\n这是一个 **Markdown** 消息',
|
|
},
|
|
at: {
|
|
atMobiles: [],
|
|
atUserIds: [],
|
|
isAtAll: false,
|
|
},
|
|
},
|
|
response: successResponses.withMessageId,
|
|
},
|
|
|
|
actionCardError: {
|
|
request: {
|
|
msgtype: 'actionCard',
|
|
actionCard: {
|
|
title: 'ActionCard 标题',
|
|
text: 'ActionCard 内容',
|
|
singleTitle: '查看详情',
|
|
singleURL: 'https://example.com',
|
|
},
|
|
},
|
|
response: errorResponses.noKeywords,
|
|
},
|
|
};
|
|
|
|
export const dingTalkResponses = {
|
|
success: successResponses,
|
|
error: errorResponses,
|
|
httpStatus: httpStatusResponses,
|
|
network: networkErrors,
|
|
special: specialResponses,
|
|
timing: responseTimings,
|
|
batch: batchResponses,
|
|
full: fullResponses,
|
|
};
|