Browse Source

add test case of common.mjs

master
master 8 months ago
parent
commit
2f70f0fcca
  1. 18
      README.md
  2. 47
      common.mjs
  3. 36
      heroUnion.mjs
  4. 34
      test/common.test.mjs
  5. 16
      test/package.json

18
README.md

@ -143,7 +143,7 @@ https://herounion.filesite.io/api/stats/
## 接口参数签名方法 ## 接口参数签名方法
将所有参数按字母排序之后拼接成GET请求字符串,最后再拼接上token计算MD5值。 将所有参数按字母排序之后转换成JSON字符串,最后再拼接上token计算MD5值。
示例如下: 示例如下:
``` ```
@ -161,24 +161,10 @@ var sortObj = function(obj) { //参数排序方法
}, {}); }, {});
}; };
var joinObj = function(obj, glue, separator) { //参数拼接方法
if (typeof(glue) == 'undefined') {
glue = '=';
}
if (typeof(separator) == 'undefined') {
separator = '&';
}
return Object.keys(obj).map(function(key) {
return [key, obj[key]].join(glue);
}).join(separator);
};
//1. 排序参数 //1. 排序参数
var sortedParams = sortObj(params); var sortedParams = sortObj(params);
//2. 计算MD5值 //2. 计算MD5值
var sign = md5( joinObj(sortedParams, '=', '&') + token ); var sign = md5( JSON.stringify(sortedParams) + token );
``` ```

47
common.mjs

@ -0,0 +1,47 @@
/**
* 公用方法
*/
import fs from 'node:fs';
import { readdir, readFile } from 'node:fs/promises';
import md5 from 'md5';
class Common {
sortDict(obj) { //dict按key排序
return Object.keys(obj).sort().reduce(function (result, key) {
result[key] = obj[key];
return result;
}, {});
}
joinDict(obj, glue, separator) { //dict拼接成字符串
if (typeof(glue) == 'undefined') {
glue = '=';
}
if (typeof(separator) == 'undefined') {
separator = '&';
}
return Object.keys(obj).map(function(key) {
let arr = [key];
let val = obj[key];
if (typeof(val) == 'string' || typeof(val) == 'number') {
arr.push(val);
}else if (typeof(val) == 'object') {
arr.push(JSON.stringify(val));
}
return arr.join(glue);
}).join(separator);
}
sign(params, token) { //对参数做MD5签名
return md5( JSON.stringify(this.sortDict(params)) + token );
}
}
let commonFuns = new Common();
export default commonFuns;

36
heroUnion.mjs

@ -20,6 +20,8 @@ import fs from 'node:fs';
import { readdir, readFile } from 'node:fs/promises'; import { readdir, readFile } from 'node:fs/promises';
import path from 'node:path'; import path from 'node:path';
import cron from 'node-cron'; import cron from 'node-cron';
import axios from 'axios';
import common from './common.mjs';
class HeroUnion { class HeroUnion {
@ -29,6 +31,7 @@ class HeroUnion {
//this.task_data_dir = path.resolve('./tmp/data/'); //任务数据保存目录 //this.task_data_dir = path.resolve('./tmp/data/'); //任务数据保存目录
this.task_cache_time = 86400; //任务数据最长缓存时间,单位:秒 this.task_cache_time = 86400; //任务数据最长缓存时间,单位:秒
this.task_data_max_size = 1024; //任务数据最大字节数,单位:KB this.task_data_max_size = 1024; //任务数据最大字节数,单位:KB
this.notify_timeout = 8; //回调通知请求超时时长,单位:秒
this.stats = {}; this.stats = {};
@ -210,10 +213,39 @@ class HeroUnion {
return this.tasks.find((item) => item.id == id); return this.tasks.find((item) => item.id == id);
} }
//TODO: 根据uuid获取用户的签名密钥
getUserToken(uuid) {
return 'token';
}
//任务完成触发回调通知 //任务完成触发回调通知
async handleTaskDone() { async handleTaskDone(id) {
//当任务完成回传回来的时候调用此方法触发回调通知 let notified = false;
let task = this.getTaskById(id);
let notify_url = task.notify_url;
try {
if (notify_url && /^http(s)?:\/\/[\w\.]+/i.test(notify_url)) {
let params = {
"task_id": task.id,
"task_result": task.results,
"timestamp": this.getTimestamp(),
};
params.sign = common.sign(params, this.getUserToken(task.uuid));
const response = await axios.post(notify_url, params, {timeout: this.notify_timeout*1000});
if (response.status == 200) {
notified = true;
}else {
console.error('Notify to %s failed, response status: %s, status text: %s, result: %s',
notify_url, response.status, response.statusText, response.daa);
}
}
}catch(err) {
console.error('Notify to %s failed: %s', notify_url, err);
}
return notified;
} }

34
test/common.test.mjs

@ -0,0 +1,34 @@
/**
* Common公用方法测试用例
*/
import test from 'node:test';
import assert from 'node:assert';
import common from '../common.mjs';
test('Common function sortDict test', (t) => {
let params = {
b: 2,
a: 1
};
const expectRes = {
a: 1,
b: 2
};
assert.deepEqual(common.sortDict(params), expectRes);
});
test('Common function joinDict test', (t) => {
let params = {
b: 2,
a: 1
};
const expectRes = "a=1&b=2";
assert.strictEqual(common.joinDict(common.sortDict(params)), expectRes);
});

16
test/package.json

@ -0,0 +1,16 @@
{
"name": "Hero Union Test",
"version": "0.1",
"author": "filesite.io",
"type": "module",
"dependencies": {
"axios": "^1.3.3",
"body-parser": "^1.20.1",
"express": "^4.18.2",
"md5": "^2.3.0",
"node-cron": "^3.0.2"
},
"scripts": {
"test": "node common.test.mjs"
}
}
Loading…
Cancel
Save