feat: 初始化 Gitea Action 发送钉钉机器人消息项目
This commit is contained in:
407
tests/fixtures/configs/invalid-configs.js
vendored
Normal file
407
tests/fixtures/configs/invalid-configs.js
vendored
Normal file
@@ -0,0 +1,407 @@
|
||||
/**
|
||||
* 无效配置数据夹具
|
||||
* 包含各种无效的配置组合用于测试错误处理
|
||||
*/
|
||||
|
||||
export const invalidConfigs = {
|
||||
// 环境变量格式的无效配置
|
||||
envVars: {
|
||||
missingWebhook: {
|
||||
INPUT_WEBHOOK_URL: '',
|
||||
INPUT_MESSAGE_TYPE: 'text',
|
||||
INPUT_CONTENT: 'Hello World',
|
||||
INPUT_TITLE: '',
|
||||
INPUT_AT_MOBILES: '',
|
||||
INPUT_AT_ALL: 'false',
|
||||
INPUT_LINK_URL: '',
|
||||
INPUT_PIC_URL: '',
|
||||
INPUT_BTN_ORIENTATION: '0',
|
||||
INPUT_SINGLE_TITLE: '',
|
||||
INPUT_SINGLE_URL: '',
|
||||
INPUT_BUTTONS: '',
|
||||
INPUT_FEED_LINKS: ''
|
||||
},
|
||||
|
||||
invalidWebhook: {
|
||||
INPUT_WEBHOOK_URL: 'not-a-valid-url',
|
||||
INPUT_MESSAGE_TYPE: 'text',
|
||||
INPUT_CONTENT: 'Hello World',
|
||||
INPUT_TITLE: '',
|
||||
INPUT_AT_MOBILES: '',
|
||||
INPUT_AT_ALL: 'false',
|
||||
INPUT_LINK_URL: '',
|
||||
INPUT_PIC_URL: '',
|
||||
INPUT_BTN_ORIENTATION: '0',
|
||||
INPUT_SINGLE_TITLE: '',
|
||||
INPUT_SINGLE_URL: '',
|
||||
INPUT_BUTTONS: '',
|
||||
INPUT_FEED_LINKS: ''
|
||||
},
|
||||
|
||||
emptyContent: {
|
||||
INPUT_WEBHOOK_URL: 'https://oapi.dingtalk.com/robot/send?access_token=test123',
|
||||
INPUT_MESSAGE_TYPE: 'text',
|
||||
INPUT_CONTENT: '',
|
||||
INPUT_TITLE: '',
|
||||
INPUT_AT_MOBILES: '',
|
||||
INPUT_AT_ALL: 'false',
|
||||
INPUT_LINK_URL: '',
|
||||
INPUT_PIC_URL: '',
|
||||
INPUT_BTN_ORIENTATION: '0',
|
||||
INPUT_SINGLE_TITLE: '',
|
||||
INPUT_SINGLE_URL: '',
|
||||
INPUT_BUTTONS: '',
|
||||
INPUT_FEED_LINKS: ''
|
||||
}
|
||||
},
|
||||
|
||||
// 缺少 webhook_url
|
||||
missingWebhookUrl: {
|
||||
webhook_url: '',
|
||||
message_type: 'text',
|
||||
content: 'Hello, World!',
|
||||
title: '',
|
||||
at_mobiles: '',
|
||||
at_all: false,
|
||||
link_url: '',
|
||||
pic_url: '',
|
||||
btn_orientation: '0',
|
||||
single_title: '',
|
||||
single_url: '',
|
||||
buttons: '',
|
||||
feed_links: ''
|
||||
},
|
||||
|
||||
// 无效的 webhook_url
|
||||
invalidWebhookUrl: {
|
||||
webhook_url: 'not-a-valid-url',
|
||||
message_type: 'text',
|
||||
content: 'Hello, World!',
|
||||
title: '',
|
||||
at_mobiles: '',
|
||||
at_all: false,
|
||||
link_url: '',
|
||||
pic_url: '',
|
||||
btn_orientation: '0',
|
||||
single_title: '',
|
||||
single_url: '',
|
||||
buttons: '',
|
||||
feed_links: ''
|
||||
},
|
||||
|
||||
// 不支持的消息类型
|
||||
unsupportedMessageType: {
|
||||
webhook_url: 'https://oapi.dingtalk.com/robot/send?access_token=test123',
|
||||
message_type: 'unsupported',
|
||||
content: 'Hello, World!',
|
||||
title: '',
|
||||
at_mobiles: '',
|
||||
at_all: false,
|
||||
link_url: '',
|
||||
pic_url: '',
|
||||
btn_orientation: '0',
|
||||
single_title: '',
|
||||
single_url: '',
|
||||
buttons: '',
|
||||
feed_links: ''
|
||||
},
|
||||
|
||||
// 空的消息内容
|
||||
emptyContent: {
|
||||
webhook_url: 'https://oapi.dingtalk.com/robot/send?access_token=test123',
|
||||
message_type: 'text',
|
||||
content: '',
|
||||
title: '',
|
||||
at_mobiles: '',
|
||||
at_all: false,
|
||||
link_url: '',
|
||||
pic_url: '',
|
||||
btn_orientation: '0',
|
||||
single_title: '',
|
||||
single_url: '',
|
||||
buttons: '',
|
||||
feed_links: ''
|
||||
},
|
||||
|
||||
// Markdown 消息缺少标题
|
||||
markdownMissingTitle: {
|
||||
webhook_url: 'https://oapi.dingtalk.com/robot/send?access_token=test123',
|
||||
message_type: 'markdown',
|
||||
content: '## 内容',
|
||||
title: '',
|
||||
at_mobiles: '',
|
||||
at_all: false,
|
||||
link_url: '',
|
||||
pic_url: '',
|
||||
btn_orientation: '0',
|
||||
single_title: '',
|
||||
single_url: '',
|
||||
buttons: '',
|
||||
feed_links: ''
|
||||
},
|
||||
|
||||
// Link 消息缺少 URL
|
||||
linkMissingUrl: {
|
||||
webhook_url: 'https://oapi.dingtalk.com/robot/send?access_token=test123',
|
||||
message_type: 'link',
|
||||
content: '链接描述',
|
||||
title: '链接标题',
|
||||
at_mobiles: '',
|
||||
at_all: false,
|
||||
link_url: '',
|
||||
pic_url: '',
|
||||
btn_orientation: '0',
|
||||
single_title: '',
|
||||
single_url: '',
|
||||
buttons: '',
|
||||
feed_links: ''
|
||||
},
|
||||
|
||||
// Link 消息无效的 URL
|
||||
linkInvalidUrl: {
|
||||
webhook_url: 'https://oapi.dingtalk.com/robot/send?access_token=test123',
|
||||
message_type: 'link',
|
||||
content: '链接描述',
|
||||
title: '链接标题',
|
||||
at_mobiles: '',
|
||||
at_all: false,
|
||||
link_url: 'not-a-valid-url',
|
||||
pic_url: '',
|
||||
btn_orientation: '0',
|
||||
single_title: '',
|
||||
single_url: '',
|
||||
buttons: '',
|
||||
feed_links: ''
|
||||
},
|
||||
|
||||
// ActionCard 缺少标题
|
||||
actionCardMissingTitle: {
|
||||
webhook_url: 'https://oapi.dingtalk.com/robot/send?access_token=test123',
|
||||
message_type: 'actionCard',
|
||||
content: 'ActionCard 内容',
|
||||
title: '',
|
||||
at_mobiles: '',
|
||||
at_all: false,
|
||||
link_url: '',
|
||||
pic_url: '',
|
||||
btn_orientation: '0',
|
||||
single_title: '按钮',
|
||||
single_url: 'https://example.com',
|
||||
buttons: '',
|
||||
feed_links: ''
|
||||
},
|
||||
|
||||
// ActionCard 既没有单按钮也没有多按钮
|
||||
actionCardNoButtons: {
|
||||
webhook_url: 'https://oapi.dingtalk.com/robot/send?access_token=test123',
|
||||
message_type: 'actionCard',
|
||||
content: 'ActionCard 内容',
|
||||
title: 'ActionCard 标题',
|
||||
at_mobiles: '',
|
||||
at_all: false,
|
||||
link_url: '',
|
||||
pic_url: '',
|
||||
btn_orientation: '0',
|
||||
single_title: '',
|
||||
single_url: '',
|
||||
buttons: '',
|
||||
feed_links: ''
|
||||
},
|
||||
|
||||
// ActionCard 单按钮缺少 URL
|
||||
actionCardSingleMissingUrl: {
|
||||
webhook_url: 'https://oapi.dingtalk.com/robot/send?access_token=test123',
|
||||
message_type: 'actionCard',
|
||||
content: 'ActionCard 内容',
|
||||
title: 'ActionCard 标题',
|
||||
at_mobiles: '',
|
||||
at_all: false,
|
||||
link_url: '',
|
||||
pic_url: '',
|
||||
btn_orientation: '0',
|
||||
single_title: '按钮',
|
||||
single_url: '',
|
||||
buttons: '',
|
||||
feed_links: ''
|
||||
},
|
||||
|
||||
// ActionCard 多按钮格式错误
|
||||
actionCardInvalidButtons: {
|
||||
webhook_url: 'https://oapi.dingtalk.com/robot/send?access_token=test123',
|
||||
message_type: 'actionCard',
|
||||
content: 'ActionCard 内容',
|
||||
title: 'ActionCard 标题',
|
||||
at_mobiles: '',
|
||||
at_all: false,
|
||||
link_url: '',
|
||||
pic_url: '',
|
||||
btn_orientation: '0',
|
||||
single_title: '',
|
||||
single_url: '',
|
||||
buttons: 'invalid-json',
|
||||
feed_links: ''
|
||||
},
|
||||
|
||||
// ActionCard 多按钮为空数组
|
||||
actionCardEmptyButtons: {
|
||||
webhook_url: 'https://oapi.dingtalk.com/robot/send?access_token=test123',
|
||||
message_type: 'actionCard',
|
||||
content: 'ActionCard 内容',
|
||||
title: 'ActionCard 标题',
|
||||
at_mobiles: '',
|
||||
at_all: false,
|
||||
link_url: '',
|
||||
pic_url: '',
|
||||
btn_orientation: '0',
|
||||
single_title: '',
|
||||
single_url: '',
|
||||
buttons: '[]',
|
||||
feed_links: ''
|
||||
},
|
||||
|
||||
// ActionCard 按钮缺少必需字段
|
||||
actionCardButtonMissingFields: {
|
||||
webhook_url: 'https://oapi.dingtalk.com/robot/send?access_token=test123',
|
||||
message_type: 'actionCard',
|
||||
content: 'ActionCard 内容',
|
||||
title: 'ActionCard 标题',
|
||||
at_mobiles: '',
|
||||
at_all: false,
|
||||
link_url: '',
|
||||
pic_url: '',
|
||||
btn_orientation: '0',
|
||||
single_title: '',
|
||||
single_url: '',
|
||||
buttons: JSON.stringify([
|
||||
{ title: '按钮1' }, // 缺少 actionURL
|
||||
{ actionURL: 'https://example.com' } // 缺少 title
|
||||
]),
|
||||
feed_links: ''
|
||||
},
|
||||
|
||||
// FeedCard 缺少链接
|
||||
feedCardMissingLinks: {
|
||||
webhook_url: 'https://oapi.dingtalk.com/robot/send?access_token=test123',
|
||||
message_type: 'feedCard',
|
||||
content: '',
|
||||
title: '',
|
||||
at_mobiles: '',
|
||||
at_all: false,
|
||||
link_url: '',
|
||||
pic_url: '',
|
||||
btn_orientation: '0',
|
||||
single_title: '',
|
||||
single_url: '',
|
||||
buttons: '',
|
||||
feed_links: ''
|
||||
},
|
||||
|
||||
// FeedCard 链接格式错误
|
||||
feedCardInvalidLinks: {
|
||||
webhook_url: 'https://oapi.dingtalk.com/robot/send?access_token=test123',
|
||||
message_type: 'feedCard',
|
||||
content: '',
|
||||
title: '',
|
||||
at_mobiles: '',
|
||||
at_all: false,
|
||||
link_url: '',
|
||||
pic_url: '',
|
||||
btn_orientation: '0',
|
||||
single_title: '',
|
||||
single_url: '',
|
||||
buttons: '',
|
||||
feed_links: 'invalid-json'
|
||||
},
|
||||
|
||||
// FeedCard 空链接数组
|
||||
feedCardEmptyLinks: {
|
||||
webhook_url: 'https://oapi.dingtalk.com/robot/send?access_token=test123',
|
||||
message_type: 'feedCard',
|
||||
content: '',
|
||||
title: '',
|
||||
at_mobiles: '',
|
||||
at_all: false,
|
||||
link_url: '',
|
||||
pic_url: '',
|
||||
btn_orientation: '0',
|
||||
single_title: '',
|
||||
single_url: '',
|
||||
buttons: '',
|
||||
feed_links: '[]'
|
||||
},
|
||||
|
||||
// FeedCard 链接缺少必需字段
|
||||
feedCardLinkMissingFields: {
|
||||
webhook_url: 'https://oapi.dingtalk.com/robot/send?access_token=test123',
|
||||
message_type: 'feedCard',
|
||||
content: '',
|
||||
title: '',
|
||||
at_mobiles: '',
|
||||
at_all: false,
|
||||
link_url: '',
|
||||
pic_url: '',
|
||||
btn_orientation: '0',
|
||||
single_title: '',
|
||||
single_url: '',
|
||||
buttons: '',
|
||||
feed_links: JSON.stringify([
|
||||
{ title: '链接1' }, // 缺少 messageURL
|
||||
{ messageURL: 'https://example.com' } // 缺少 title
|
||||
])
|
||||
},
|
||||
|
||||
// 无效的手机号格式
|
||||
invalidMobileFormat: {
|
||||
webhook_url: 'https://oapi.dingtalk.com/robot/send?access_token=test123',
|
||||
message_type: 'text',
|
||||
content: 'Hello, World!',
|
||||
title: '',
|
||||
at_mobiles: 'invalid-mobile',
|
||||
at_all: false,
|
||||
link_url: '',
|
||||
pic_url: '',
|
||||
btn_orientation: '0',
|
||||
single_title: '',
|
||||
single_url: '',
|
||||
buttons: '',
|
||||
feed_links: ''
|
||||
},
|
||||
|
||||
// 无效的按钮方向
|
||||
invalidBtnOrientation: {
|
||||
webhook_url: 'https://oapi.dingtalk.com/robot/send?access_token=test123',
|
||||
message_type: 'actionCard',
|
||||
content: 'ActionCard 内容',
|
||||
title: 'ActionCard 标题',
|
||||
at_mobiles: '',
|
||||
at_all: false,
|
||||
link_url: '',
|
||||
pic_url: '',
|
||||
btn_orientation: '2', // 只支持 0 和 1
|
||||
single_title: '按钮',
|
||||
single_url: 'https://example.com',
|
||||
buttons: '',
|
||||
feed_links: ''
|
||||
}
|
||||
};
|
||||
|
||||
// 环境变量格式的无效配置
|
||||
export const invalidEnvConfigs = {
|
||||
missingWebhookUrl: {
|
||||
INPUT_WEBHOOK_URL: '',
|
||||
INPUT_MESSAGE_TYPE: 'text',
|
||||
INPUT_CONTENT: 'Hello, World!'
|
||||
},
|
||||
|
||||
unsupportedMessageType: {
|
||||
INPUT_WEBHOOK_URL: 'https://oapi.dingtalk.com/robot/send?access_token=test123',
|
||||
INPUT_MESSAGE_TYPE: 'unsupported',
|
||||
INPUT_CONTENT: 'Hello, World!'
|
||||
},
|
||||
|
||||
emptyContent: {
|
||||
INPUT_WEBHOOK_URL: 'https://oapi.dingtalk.com/robot/send?access_token=test123',
|
||||
INPUT_MESSAGE_TYPE: 'text',
|
||||
INPUT_CONTENT: ''
|
||||
}
|
||||
};
|
||||
378
tests/fixtures/configs/valid-configs.js
vendored
Normal file
378
tests/fixtures/configs/valid-configs.js
vendored
Normal file
@@ -0,0 +1,378 @@
|
||||
/**
|
||||
* 有效配置数据夹具
|
||||
* 包含各种有效的配置组合用于测试
|
||||
*/
|
||||
|
||||
export const validConfigs = {
|
||||
// 环境变量格式的配置
|
||||
envVars: {
|
||||
text: {
|
||||
INPUT_WEBHOOK_URL: 'https://oapi.dingtalk.com/robot/send?access_token=test123',
|
||||
INPUT_MESSAGE_TYPE: 'text',
|
||||
INPUT_CONTENT: 'Hello World',
|
||||
INPUT_TITLE: '',
|
||||
INPUT_AT_MOBILES: '',
|
||||
INPUT_AT_ALL: 'false',
|
||||
INPUT_LINK_URL: '',
|
||||
INPUT_PIC_URL: '',
|
||||
INPUT_BTN_ORIENTATION: '0',
|
||||
INPUT_SINGLE_TITLE: '',
|
||||
INPUT_SINGLE_URL: '',
|
||||
INPUT_BUTTONS: '',
|
||||
INPUT_FEED_LINKS: '',
|
||||
},
|
||||
|
||||
markdown: {
|
||||
INPUT_WEBHOOK_URL: 'https://oapi.dingtalk.com/robot/send?access_token=test456',
|
||||
INPUT_MESSAGE_TYPE: 'markdown',
|
||||
INPUT_CONTENT: '# Hello\n\nThis is **markdown** content.',
|
||||
INPUT_TITLE: 'Test Title',
|
||||
INPUT_AT_MOBILES: '',
|
||||
INPUT_AT_ALL: 'false',
|
||||
INPUT_LINK_URL: '',
|
||||
INPUT_PIC_URL: '',
|
||||
INPUT_BTN_ORIENTATION: '0',
|
||||
INPUT_SINGLE_TITLE: '',
|
||||
INPUT_SINGLE_URL: '',
|
||||
INPUT_BUTTONS: '',
|
||||
INPUT_FEED_LINKS: '',
|
||||
},
|
||||
|
||||
link: {
|
||||
INPUT_WEBHOOK_URL: 'https://oapi.dingtalk.com/robot/send?access_token=test789',
|
||||
INPUT_MESSAGE_TYPE: 'link',
|
||||
INPUT_CONTENT: 'This is a test link',
|
||||
INPUT_TITLE: 'Test Link',
|
||||
INPUT_AT_MOBILES: '',
|
||||
INPUT_AT_ALL: 'false',
|
||||
INPUT_LINK_URL: 'https://example.com',
|
||||
INPUT_PIC_URL: '',
|
||||
INPUT_BTN_ORIENTATION: '0',
|
||||
INPUT_SINGLE_TITLE: '',
|
||||
INPUT_SINGLE_URL: '',
|
||||
INPUT_BUTTONS: '',
|
||||
INPUT_FEED_LINKS: '',
|
||||
},
|
||||
|
||||
actionCard: {
|
||||
INPUT_WEBHOOK_URL: 'https://oapi.dingtalk.com/robot/send?access_token=test101',
|
||||
INPUT_MESSAGE_TYPE: 'actionCard',
|
||||
INPUT_CONTENT: 'Action card content',
|
||||
INPUT_TITLE: 'Action Card Title',
|
||||
INPUT_AT_MOBILES: '',
|
||||
INPUT_AT_ALL: 'false',
|
||||
INPUT_LINK_URL: '',
|
||||
INPUT_PIC_URL: '',
|
||||
INPUT_BTN_ORIENTATION: '0',
|
||||
INPUT_SINGLE_TITLE: '',
|
||||
INPUT_SINGLE_URL: '',
|
||||
INPUT_BUTTONS: JSON.stringify([{ title: 'Button 1', actionURL: 'https://example.com/1' }]),
|
||||
INPUT_FEED_LINKS: '',
|
||||
},
|
||||
|
||||
feedCard: {
|
||||
INPUT_WEBHOOK_URL: 'https://oapi.dingtalk.com/robot/send?access_token=test103',
|
||||
INPUT_MESSAGE_TYPE: 'feedCard',
|
||||
INPUT_CONTENT: '',
|
||||
INPUT_TITLE: '',
|
||||
INPUT_AT_MOBILES: '',
|
||||
INPUT_AT_ALL: 'false',
|
||||
INPUT_LINK_URL: '',
|
||||
INPUT_PIC_URL: '',
|
||||
INPUT_BTN_ORIENTATION: '0',
|
||||
INPUT_SINGLE_TITLE: '',
|
||||
INPUT_SINGLE_URL: '',
|
||||
INPUT_BUTTONS: '',
|
||||
INPUT_FEED_LINKS: JSON.stringify([
|
||||
{
|
||||
title: '新闻1',
|
||||
messageURL: 'https://example.com/news1',
|
||||
picURL: 'https://example.com/pic1.jpg',
|
||||
},
|
||||
]),
|
||||
},
|
||||
},
|
||||
|
||||
// 基础文本消息配置
|
||||
basicText: {
|
||||
webhook_url: 'https://oapi.dingtalk.com/robot/send?access_token=test123',
|
||||
message_type: 'text',
|
||||
content: 'Hello, World!',
|
||||
title: '',
|
||||
at_mobiles: '',
|
||||
at_all: false,
|
||||
link_url: '',
|
||||
pic_url: '',
|
||||
btn_orientation: '0',
|
||||
single_title: '',
|
||||
single_url: '',
|
||||
buttons: '',
|
||||
feed_links: '',
|
||||
},
|
||||
|
||||
// Markdown 消息配置
|
||||
markdown: {
|
||||
webhook_url: 'https://oapi.dingtalk.com/robot/send?access_token=test456',
|
||||
message_type: 'markdown',
|
||||
content: '## 标题\n这是一个 **Markdown** 消息',
|
||||
title: 'Markdown 标题',
|
||||
at_mobiles: '',
|
||||
at_all: false,
|
||||
link_url: '',
|
||||
pic_url: '',
|
||||
btn_orientation: '0',
|
||||
single_title: '',
|
||||
single_url: '',
|
||||
buttons: '',
|
||||
feed_links: '',
|
||||
},
|
||||
|
||||
// 链接消息配置
|
||||
link: {
|
||||
webhook_url: 'https://oapi.dingtalk.com/robot/send?access_token=test789',
|
||||
message_type: 'link',
|
||||
content: '这是一个链接消息的描述',
|
||||
title: '链接标题',
|
||||
at_mobiles: '',
|
||||
at_all: false,
|
||||
link_url: 'https://example.com',
|
||||
pic_url: 'https://example.com/image.jpg',
|
||||
btn_orientation: '0',
|
||||
single_title: '',
|
||||
single_url: '',
|
||||
buttons: '',
|
||||
feed_links: '',
|
||||
},
|
||||
|
||||
// 单按钮 ActionCard 配置
|
||||
singleActionCard: {
|
||||
webhook_url: 'https://oapi.dingtalk.com/robot/send?access_token=test101',
|
||||
message_type: 'actionCard',
|
||||
content: '这是一个单按钮 ActionCard',
|
||||
title: 'ActionCard 标题',
|
||||
at_mobiles: '',
|
||||
at_all: false,
|
||||
link_url: '',
|
||||
pic_url: '',
|
||||
btn_orientation: '0',
|
||||
single_title: '查看详情',
|
||||
single_url: 'https://example.com/detail',
|
||||
buttons: '',
|
||||
feed_links: '',
|
||||
},
|
||||
|
||||
// 多按钮 ActionCard 配置
|
||||
multiActionCard: {
|
||||
webhook_url: 'https://oapi.dingtalk.com/robot/send?access_token=test102',
|
||||
message_type: 'actionCard',
|
||||
content: '这是一个多按钮 ActionCard',
|
||||
title: 'ActionCard 标题',
|
||||
at_mobiles: '',
|
||||
at_all: false,
|
||||
link_url: '',
|
||||
pic_url: '',
|
||||
btn_orientation: '1',
|
||||
single_title: '',
|
||||
single_url: '',
|
||||
buttons: JSON.stringify([
|
||||
{ title: '按钮1', actionURL: 'https://example.com/action1' },
|
||||
{ title: '按钮2', actionURL: 'https://example.com/action2' },
|
||||
]),
|
||||
feed_links: '',
|
||||
},
|
||||
|
||||
// FeedCard 配置
|
||||
feedCard: {
|
||||
webhook_url: 'https://oapi.dingtalk.com/robot/send?access_token=test103',
|
||||
message_type: 'feedCard',
|
||||
content: '',
|
||||
title: '',
|
||||
at_mobiles: '',
|
||||
at_all: false,
|
||||
link_url: '',
|
||||
pic_url: '',
|
||||
btn_orientation: '0',
|
||||
single_title: '',
|
||||
single_url: '',
|
||||
buttons: '',
|
||||
feed_links: JSON.stringify([
|
||||
{
|
||||
title: '新闻1',
|
||||
messageURL: 'https://example.com/news1',
|
||||
picURL: 'https://example.com/pic1.jpg',
|
||||
},
|
||||
{
|
||||
title: '新闻2',
|
||||
messageURL: 'https://example.com/news2',
|
||||
picURL: 'https://example.com/pic2.jpg',
|
||||
},
|
||||
]),
|
||||
},
|
||||
|
||||
// 带 @ 功能的文本消息
|
||||
textWithAt: {
|
||||
webhook_url: 'https://oapi.dingtalk.com/robot/send?access_token=test104',
|
||||
message_type: 'text',
|
||||
content: '这是一个带 @ 功能的消息',
|
||||
title: '',
|
||||
at_mobiles: '13800138000,13900139000',
|
||||
at_all: false,
|
||||
link_url: '',
|
||||
pic_url: '',
|
||||
btn_orientation: '0',
|
||||
single_title: '',
|
||||
single_url: '',
|
||||
buttons: '',
|
||||
feed_links: '',
|
||||
},
|
||||
|
||||
// @ 所有人的消息
|
||||
textWithAtAll: {
|
||||
webhook_url: 'https://oapi.dingtalk.com/robot/send?access_token=test105',
|
||||
message_type: 'text',
|
||||
content: '这是一个 @ 所有人的消息',
|
||||
title: '',
|
||||
at_mobiles: '',
|
||||
at_all: true,
|
||||
link_url: '',
|
||||
pic_url: '',
|
||||
btn_orientation: '0',
|
||||
single_title: '',
|
||||
single_url: '',
|
||||
buttons: '',
|
||||
feed_links: '',
|
||||
},
|
||||
|
||||
// 复杂的 Markdown 消息
|
||||
complexMarkdown: {
|
||||
webhook_url: 'https://oapi.dingtalk.com/robot/send?access_token=test106',
|
||||
message_type: 'markdown',
|
||||
content: `# 构建报告
|
||||
## 构建状态: ✅ 成功
|
||||
- **项目**: dingtalk-bot
|
||||
- **分支**: main
|
||||
- **提交**: abc123
|
||||
- **时间**: 2024-01-01 12:00:00
|
||||
|
||||
### 测试结果
|
||||
- 单元测试: 100% 通过
|
||||
- 覆盖率: 95%
|
||||
|
||||
[查看详细报告](https://example.com/report)`,
|
||||
title: '构建报告',
|
||||
at_mobiles: '13800138000',
|
||||
at_all: false,
|
||||
link_url: '',
|
||||
pic_url: '',
|
||||
btn_orientation: '0',
|
||||
single_title: '',
|
||||
single_url: '',
|
||||
buttons: '',
|
||||
feed_links: '',
|
||||
},
|
||||
|
||||
// 垂直排列的多按钮 ActionCard
|
||||
verticalActionCard: {
|
||||
webhook_url: 'https://oapi.dingtalk.com/robot/send?access_token=test107',
|
||||
message_type: 'actionCard',
|
||||
content: '请选择操作',
|
||||
title: '操作选择',
|
||||
at_mobiles: '',
|
||||
at_all: false,
|
||||
link_url: '',
|
||||
pic_url: '',
|
||||
btn_orientation: '1',
|
||||
single_title: '',
|
||||
single_url: '',
|
||||
buttons: JSON.stringify([
|
||||
{ title: '同意', actionURL: 'https://example.com/approve' },
|
||||
{ title: '拒绝', actionURL: 'https://example.com/reject' },
|
||||
{ title: '查看详情', actionURL: 'https://example.com/detail' },
|
||||
]),
|
||||
feed_links: '',
|
||||
},
|
||||
|
||||
// 多链接 FeedCard
|
||||
multiFeedCard: {
|
||||
webhook_url: 'https://oapi.dingtalk.com/robot/send?access_token=test108',
|
||||
message_type: 'feedCard',
|
||||
content: '',
|
||||
title: '',
|
||||
at_mobiles: '',
|
||||
at_all: false,
|
||||
link_url: '',
|
||||
pic_url: '',
|
||||
btn_orientation: '0',
|
||||
single_title: '',
|
||||
single_url: '',
|
||||
buttons: '',
|
||||
feed_links: JSON.stringify([
|
||||
{
|
||||
title: '技术文档',
|
||||
messageURL: 'https://docs.example.com',
|
||||
picURL: 'https://example.com/doc.jpg',
|
||||
},
|
||||
{
|
||||
title: 'API 参考',
|
||||
messageURL: 'https://api.example.com',
|
||||
picURL: 'https://example.com/api.jpg',
|
||||
},
|
||||
{
|
||||
title: '示例代码',
|
||||
messageURL: 'https://github.com/example',
|
||||
picURL: 'https://example.com/code.jpg',
|
||||
},
|
||||
]),
|
||||
},
|
||||
};
|
||||
|
||||
// 环境变量格式的配置(用于测试 config.js)
|
||||
export const envConfigs = {
|
||||
basicText: {
|
||||
INPUT_WEBHOOK_URL: 'https://oapi.dingtalk.com/robot/send?access_token=test123',
|
||||
INPUT_MESSAGE_TYPE: 'text',
|
||||
INPUT_CONTENT: 'Hello, World!',
|
||||
INPUT_TITLE: '',
|
||||
INPUT_AT_MOBILES: '',
|
||||
INPUT_AT_ALL: 'false',
|
||||
INPUT_LINK_URL: '',
|
||||
INPUT_PIC_URL: '',
|
||||
INPUT_BTN_ORIENTATION: '0',
|
||||
INPUT_SINGLE_TITLE: '',
|
||||
INPUT_SINGLE_URL: '',
|
||||
INPUT_BUTTONS: '',
|
||||
INPUT_FEED_LINKS: '',
|
||||
},
|
||||
|
||||
markdown: {
|
||||
INPUT_WEBHOOK_URL: 'https://oapi.dingtalk.com/robot/send?access_token=test456',
|
||||
INPUT_MESSAGE_TYPE: 'markdown',
|
||||
INPUT_CONTENT: '## 标题\n这是一个 **Markdown** 消息',
|
||||
INPUT_TITLE: 'Markdown 标题',
|
||||
INPUT_AT_MOBILES: '',
|
||||
INPUT_AT_ALL: 'false',
|
||||
INPUT_LINK_URL: '',
|
||||
INPUT_PIC_URL: '',
|
||||
INPUT_BTN_ORIENTATION: '0',
|
||||
INPUT_SINGLE_TITLE: '',
|
||||
INPUT_SINGLE_URL: '',
|
||||
INPUT_BUTTONS: '',
|
||||
INPUT_FEED_LINKS: '',
|
||||
},
|
||||
|
||||
textWithAtAll: {
|
||||
INPUT_WEBHOOK_URL: 'https://oapi.dingtalk.com/robot/send?access_token=test105',
|
||||
INPUT_MESSAGE_TYPE: 'text',
|
||||
INPUT_CONTENT: '这是一个 @ 所有人的消息',
|
||||
INPUT_TITLE: '',
|
||||
INPUT_AT_MOBILES: '',
|
||||
INPUT_AT_ALL: 'true',
|
||||
INPUT_LINK_URL: '',
|
||||
INPUT_PIC_URL: '',
|
||||
INPUT_BTN_ORIENTATION: '0',
|
||||
INPUT_SINGLE_TITLE: '',
|
||||
INPUT_SINGLE_URL: '',
|
||||
INPUT_BUTTONS: '',
|
||||
INPUT_FEED_LINKS: '',
|
||||
},
|
||||
};
|
||||
366
tests/fixtures/responses/dingtalk-responses.js
vendored
Normal file
366
tests/fixtures/responses/dingtalk-responses.js
vendored
Normal file
@@ -0,0 +1,366 @@
|
||||
/**
|
||||
* 钉钉 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,
|
||||
};
|
||||
Reference in New Issue
Block a user