From 614291b374f928c902fa0dae2755e1a6aafefb74 Mon Sep 17 00:00:00 2001 From: filesite Date: Mon, 8 Apr 2024 12:27:47 +0800 Subject: [PATCH] api onboard ready --- common.mjs | 30 ++++++++++++++++++++++ heroUnion.mjs | 4 +-- router_api.mjs | 55 ++++++++++++++++++++++++++++++++++++++++- test/heroUnion.test.mjs | 38 ++++++++++++++++++++++++++++ 4 files changed, 124 insertions(+), 3 deletions(-) create mode 100644 test/heroUnion.test.mjs diff --git a/common.mjs b/common.mjs index 2d5963e..64d40c3 100644 --- a/common.mjs +++ b/common.mjs @@ -76,6 +76,36 @@ class Common { return data; } + //判断语言代码是否符合国际标准 + isIosLangCode(lang) { + return /^[a-z]{2}$/i.test(lang); + } + + //判断国家代码是否符合国际标准 + isIosCountryCode(country) { + return /^[a-z]{2}$/i.test(country); + } + + //判断爬虫状态代码是否正确 + isBotStatus(status) { + const codes = [ + "idle", + "busy" + ]; + + return codes.findIndex((item) => item == status) > -1; + } + + //判断是否单位为秒的时间戳 + isTimestampInSeconds(timestamp) { + return typeof(timestamp) == 'number' && /^1[0-9]{9}$/.test(timestamp); + } + + //检查爬虫名字是否符合标准:6 - 32位字母和下划线的组合 + isBotNameOk(bot_name) { + return /^\w{6,32}$/i.test(bot_name); + } + } let commonFuns = new Common(); diff --git a/heroUnion.mjs b/heroUnion.mjs index 81c2c82..74500e6 100644 --- a/heroUnion.mjs +++ b/heroUnion.mjs @@ -132,7 +132,7 @@ class HeroUnion { //可选 data_mode: 'default', country: 'china', - lang: 'zh-CN', + lang: 'zh', notify_url: '', results: [], @@ -254,7 +254,7 @@ class HeroUnion { notified = true; }else { console.error('[FAILED] Notify to %s failed, response status: %s, status text: %s, result: %s', - notify_url, response.status, response.statusText, response.daa); + notify_url, response.status, response.statusText, response.data); } } }catch(err) { diff --git a/router_api.mjs b/router_api.mjs index ed0f4c2..0c10663 100644 --- a/router_api.mjs +++ b/router_api.mjs @@ -47,9 +47,62 @@ router.get('/querytask/', async (req, res) => { return res.send('api/querytask/'); }); +/** + * 参数列表 + * name + * description + * status: [idle, busy] + * timestamp + * country + * lang + */ router.post('/onboard/', async (req, res) => { + let bot_name = req.body.name, + bot_desc = req.body.description, + status = req.body.status, + timestamp = req.body.timestamp, + country = req.body.country, + lang = req.body.lang; - return res.send('api/onboard/'); + let data = { + "code": 0, + "message": "" + }; + + //参数格式检查 + if (!bot_name || !bot_desc || !status || !timestamp) { + data.message = '必填参数name、description、status、timestamp不能为空'; + }else if (common.isBotNameOk(bot_name) == false) { + data.message = '爬虫名字必须是6 - 32位英文字母、下划线的组合'; + }else if (typeof(bot_desc) != 'string' || bot_desc.length > 100) { + data.message = '爬虫简介必须是100个字符以内的字符串'; + }else if (common.isBotStatus(status) == false) { + data.message = '爬虫状态status传参错误,其可选值:idle、busy'; + }else if (common.isTimestampInSeconds(timestamp) == false) { + data.message = '时间戳timestamp请传秒数'; + }else if (country && common.isIosCountryCode(country) == false) { + data.message = '国家代码country请传小写的两位字母,参考两位ISO CODES:https://countrycode.org/'; + }else if (lang && common.isIosLangCode(lang) == false) { + data.message = '语言代码lang请传小写的两位字母,参考ISO 639-1 Code:https://www.loc.gov/standards/iso639-2/php/code_list.php'; + } + + if (!data.message) { + let bot = { + name: bot_name.toLowerCase(), + description: bot_desc, + status: status, + timestamp: timestamp, + //如果没传则填充默认值 + country: country ? country.toLowerCase() : 'cn', + lang: lang ? lang.toLowerCase() : 'zh' + }; + + heroUnion.heroOnboard(bot); + data.code = 1; + data.message = '欢迎上船,因为有你,联盟将更健壮!'; + } + + return res.status(200).json(data); }); router.get('/stats/', async (req, res) => { diff --git a/test/heroUnion.test.mjs b/test/heroUnion.test.mjs new file mode 100644 index 0000000..fbbacf1 --- /dev/null +++ b/test/heroUnion.test.mjs @@ -0,0 +1,38 @@ +/** + * HeroUnion测试用例 + * 执行此测试之前,请先启动主程序,在根目录执行命令:npm start + */ + +import test from 'node:test'; +import assert from 'node:assert'; +import axios from 'axios'; +import common from '../common.mjs'; +import HeroUnion from '../heroUnion.mjs'; + +test('Hero onboard test', async (t) => { + let params = { + name: 'test_hero', + description: 'Hero test 测试爬虫', + status: 'idle', + timestamp: common.getTimestampInSeconds(), + country: 'cn', + lang: 'zh' + }; + + let api = 'http://127.0.0.1:8080/api/onboard/'; + + const response = await axios.post(api, params, {timeout: 5000}); + console.log(response.data); + + assert.equal(response.status, 200); + assert.equal(response.data.code, 1); +}); + +test('HeroUnion stats test', async (t) => { + let api = 'http://127.0.0.1:8080/api/stats/'; + + const response = await axios.get(api, {timeout: 5000}); + console.log(response.data); + + assert.equal(response.status, 200); +});