Showing
20 changed files
with
8 additions
and
1261 deletions
1 | 'use strict'; | 1 | 'use strict'; |
2 | 2 | ||
3 | const mRoot = '../models'; | 3 | const mRoot = '../models'; |
4 | -const library = '../../../library'; | ||
5 | 4 | ||
6 | const couponModel = require(`${mRoot}/coupon`); // 领取优惠券 model | 5 | const couponModel = require(`${mRoot}/coupon`); // 领取优惠券 model |
7 | -const log = require(`${library}/logger`); | ||
8 | 6 | ||
9 | exports.index = (req, res, next) => { | 7 | exports.index = (req, res, next) => { |
10 | var renderData = { | 8 | var renderData = { |
@@ -8,8 +8,8 @@ | @@ -8,8 +8,8 @@ | ||
8 | const request = require('request-promise'); | 8 | const request = require('request-promise'); |
9 | const Promise = require('bluebird'); | 9 | const Promise = require('bluebird'); |
10 | const crypto = require('crypto'); | 10 | const crypto = require('crypto'); |
11 | -const logger = require('../../../library/logger'); | ||
12 | -const cache = require('../../../library/cache'); | 11 | +const logger = global.yoho.logger; |
12 | +const cache = global.yoho.cache; | ||
13 | 13 | ||
14 | // 此处请勿使用有货公众号的 appId, 此处使用的是 女生志 的appId | 14 | // 此处请勿使用有货公众号的 appId, 此处使用的是 女生志 的appId |
15 | const appId = 'wxb52ec6a352f0b090'; | 15 | const appId = 'wxb52ec6a352f0b090'; |
@@ -71,14 +71,16 @@ let index = (req, res, next) => { | @@ -71,14 +71,16 @@ let index = (req, res, next) => { | ||
71 | Object.assign(params.renderData.pageHeader, { | 71 | Object.assign(params.renderData.pageHeader, { |
72 | saleNav: saleModel.saleNav(req.yoho.channel) | 72 | saleNav: saleModel.saleNav(req.yoho.channel) |
73 | }); | 73 | }); |
74 | + | ||
75 | + // 此处 channel 需要读取 cookies 的 channel | ||
76 | + req.cookies._Channel && (res.locals.pageChannel[req.cookies._Channel] = true); | ||
74 | res.render('sale/index', Object.assign(params.renderData, { | 77 | res.render('sale/index', Object.assign(params.renderData, { |
75 | content: result, | 78 | content: result, |
76 | floorHeader: { | 79 | floorHeader: { |
77 | title: { | 80 | title: { |
78 | title: '最新降价' | 81 | title: '最新降价' |
79 | } | 82 | } |
80 | - }, | ||
81 | - pageChannel: false // 需求中,头部不需要跟随频道变颜色 | 83 | + } |
82 | })); | 84 | })); |
83 | }).catch(next); | 85 | }).catch(next); |
84 | }; | 86 | }; |
@@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
3 | * @return {[type]} | 3 | * @return {[type]} |
4 | */ | 4 | */ |
5 | const headerModel = require('../models/header'); | 5 | const headerModel = require('../models/header'); |
6 | -const logger = require('../../library/logger'); | 6 | +const logger = global.yoho.logger; |
7 | 7 | ||
8 | exports.notFound = () => { | 8 | exports.notFound = () => { |
9 | return (req, res) => { | 9 | return (req, res) => { |
library/api.js
deleted
100644 → 0
1 | -/** | ||
2 | - * 接口公共方法 | ||
3 | - * @author: xuqi<qi.xu@yoho.cn> | ||
4 | - * @date: 2016/4/25 | ||
5 | - */ | ||
6 | - | ||
7 | -'use strict'; | ||
8 | -const rp = require('request-promise'); | ||
9 | -const qs = require('querystring'); | ||
10 | -const md5 = require('md5'); | ||
11 | -const _ = require('lodash'); | ||
12 | -const log = require('./logger'); | ||
13 | -const cache = require('./cache'); | ||
14 | -const Timer = require('./timer'); | ||
15 | -const sign = require('./sign'); | ||
16 | -const config = require('../config/common'); | ||
17 | -const api = config.domains.api; | ||
18 | -const serviceApi = config.domains.service; | ||
19 | -const searchApi = config.domains.search; | ||
20 | - | ||
21 | -// 错误返回 | ||
22 | -const API_BAD_RETSULT = { | ||
23 | - code: 500, | ||
24 | - message: 'API result is not JSON string or null.' | ||
25 | -}; | ||
26 | - | ||
27 | -// 调用失败 | ||
28 | -const API_CALL_FAIL = { | ||
29 | - code: 500, | ||
30 | - message: 'Call API failed.' | ||
31 | -}; | ||
32 | - | ||
33 | -// all 方法错误的传参 | ||
34 | -const API_ALL_METHOD_ERROR = 'the parameters of api all method should be Array!'; | ||
35 | - | ||
36 | -// 获取缓存数据失败 | ||
37 | -const SLAVE_CACHE_FAIL = 'get slave cache fail'; | ||
38 | -const MASTER_CACHE_FAIL = 'get master cache fail'; | ||
39 | - | ||
40 | -// 获取缓存数据成功 | ||
41 | -const SLAVE_CACHE_SUCCESS = 'get slave cache success'; | ||
42 | -const MASTER_CACHE_SUCCESS = 'get master cache success'; | ||
43 | - | ||
44 | -class Http { | ||
45 | - | ||
46 | - constructor(baseUrl) { | ||
47 | - this.ApiUrl = baseUrl; | ||
48 | - } | ||
49 | - | ||
50 | - /** | ||
51 | - * 获取请求 ID | ||
52 | - */ | ||
53 | - _getReqId(options) { | ||
54 | - return md5(`${options.url}?${qs.stringify(options.qs || options.form)}`); | ||
55 | - } | ||
56 | - | ||
57 | - /** | ||
58 | - * 调用接口 | ||
59 | - */ | ||
60 | - _requestFromAPI(options, cacheOption, reqId) { | ||
61 | - const timer = new Timer(); | ||
62 | - const method = options.method || 'get'; | ||
63 | - | ||
64 | - timer.put('getApi');// 统计时间开始 | ||
65 | - return rp(options).then((result) => { | ||
66 | - const duration = timer.put('getApi');// 统计时间结束 | ||
67 | - | ||
68 | - // 数据校验 | ||
69 | - if (!result) { | ||
70 | - log.error(`error: ${API_BAD_RETSULT.message}`); | ||
71 | - return Promise.reject(API_BAD_RETSULT); | ||
72 | - } | ||
73 | - | ||
74 | - // 写缓存, 否则返回 Slave 缓存服务器的数据 | ||
75 | - if (config.useCache && cacheOption) { | ||
76 | - const cacheTime = _.isNumber(cacheOption) ? cacheOption : 60; | ||
77 | - const catchErr = (err) => { | ||
78 | - log.error(`cache: ${err.toString()}`); | ||
79 | - }; | ||
80 | - | ||
81 | - reqId = reqId || this._getReqId(options); | ||
82 | - cache.set(`apiCache:${reqId}`, result, cacheTime).catch(catchErr); | ||
83 | - cache.setSlave(`apiCache:${reqId}`, result, 86400).catch(catchErr); // 二级缓存存储一天 | ||
84 | - } | ||
85 | - | ||
86 | - let reqData = options.qs || options.form; | ||
87 | - | ||
88 | - log.info(`use: ${duration}ms for ${method} api: ${options.url}?${qs.stringify(reqData)} `); | ||
89 | - return result; | ||
90 | - }).catch((err)=> { | ||
91 | - const duration = timer.put('getApi');// 统计时间结束 | ||
92 | - | ||
93 | - log.error(`${method} api fail: use: ${duration}ms, code:${err.statusCode}, error: ${err.message}`); | ||
94 | - log.error(`API: ${options.url}?${qs.stringify(options.qs)}`); | ||
95 | - | ||
96 | - // 使用缓存的时候,读取二级缓存 | ||
97 | - if (config.useCache && cacheOption) { | ||
98 | - return this._requestFromCache(options, true); | ||
99 | - } | ||
100 | - return Promise.resolve(API_CALL_FAIL); | ||
101 | - }); | ||
102 | - } | ||
103 | - | ||
104 | - /** | ||
105 | - * 读取缓存 | ||
106 | - * @param {[object]} options | ||
107 | - * @param {[boolean]} slave true: 读取二级缓存 | ||
108 | - * @return {[type]} | ||
109 | - */ | ||
110 | - _requestFromCache(options, slave) { | ||
111 | - const reqId = this._getReqId(options); | ||
112 | - const getCache = slave ? cache.getFromSlave : cache.get; | ||
113 | - | ||
114 | - log.info(`get ${slave ? 'slave' : 'master'} cache: ${reqId}, url: ${options.url}?${qs.stringify(options.qs)}`); | ||
115 | - return getCache(`apiCache:${reqId}`).then((result) => { | ||
116 | - if (!_.isNil(result)) { | ||
117 | - try { | ||
118 | - result = JSON.parse(result); | ||
119 | - } finally { | ||
120 | - log.info(slave ? SLAVE_CACHE_SUCCESS : MASTER_CACHE_SUCCESS); | ||
121 | - return result; | ||
122 | - } | ||
123 | - } | ||
124 | - | ||
125 | - // 读取缓存失败,并且不是二级缓存的时候,调用 API | ||
126 | - if (!slave) { | ||
127 | - return this._requestFromAPI(options, true, reqId); | ||
128 | - } | ||
129 | - }).catch(() => { | ||
130 | - log.error(slave ? SLAVE_CACHE_FAIL : MASTER_CACHE_FAIL); | ||
131 | - | ||
132 | - // 读取缓存失败,并且不是二级缓存的时候,调用 API | ||
133 | - if (!slave) { | ||
134 | - return this._requestFromAPI(options, true, reqId); | ||
135 | - } | ||
136 | - | ||
137 | - return Promise.resolve(API_CALL_FAIL); | ||
138 | - }); | ||
139 | - } | ||
140 | - | ||
141 | - /** | ||
142 | - * 使用 get 请求获取接口 | ||
143 | - * @param {[string]} url | ||
144 | - * @param {[object]} data | ||
145 | - * @param {[bool or number]} cacheOption 使用数字时,数字表示缓存时间 | ||
146 | - * @return {[type]} | ||
147 | - */ | ||
148 | - get(url, data, cacheOption) { | ||
149 | - const options = { | ||
150 | - url: `${this.ApiUrl}${url}`, | ||
151 | - qs: data.client_secret ? data : sign.apiSign(data), | ||
152 | - json: true, | ||
153 | - gzip: true, | ||
154 | - timeout: 3000 | ||
155 | - }; | ||
156 | - | ||
157 | - // 从缓存获取数据 | ||
158 | - if (config.useCache && cacheOption) { | ||
159 | - return this._requestFromCache(options); | ||
160 | - } | ||
161 | - | ||
162 | - return this._requestFromAPI(options, cacheOption); | ||
163 | - } | ||
164 | - | ||
165 | - /** | ||
166 | - * post | ||
167 | - * @param url String | ||
168 | - * @param data Obejct | ||
169 | - */ | ||
170 | - post(url, data) { | ||
171 | - const options = { | ||
172 | - url: `${this.ApiUrl}${url}`, | ||
173 | - form: data.client_secret ? data : sign.apiSign(data), | ||
174 | - method: 'post', | ||
175 | - json: true, | ||
176 | - timeout: 3000 | ||
177 | - }; | ||
178 | - | ||
179 | - return this._requestFromAPI(options); | ||
180 | - } | ||
181 | - | ||
182 | - all(list) { | ||
183 | - if (_.isArray(list)) { | ||
184 | - return Promise.all(list); | ||
185 | - } else { | ||
186 | - return Promise.reject(Error(API_ALL_METHOD_ERROR)); | ||
187 | - } | ||
188 | - } | ||
189 | -} | ||
190 | - | ||
191 | -class API extends Http { | ||
192 | - constructor() { | ||
193 | - super(api); | ||
194 | - } | ||
195 | -} | ||
196 | - | ||
197 | -class ServiceAPI extends Http { | ||
198 | - constructor() { | ||
199 | - super(serviceApi); | ||
200 | - } | ||
201 | -} | ||
202 | - | ||
203 | -class SearchAPI extends Http { | ||
204 | - constructor() { | ||
205 | - super(searchApi); | ||
206 | - } | ||
207 | -} | ||
208 | - | ||
209 | -exports.API = API; | ||
210 | -exports.ServiceAPI = ServiceAPI; | ||
211 | -exports.SearchAPI = SearchAPI; |
library/cache.js
deleted
100644 → 0
1 | -/** | ||
2 | - * 缓存封装 | ||
3 | - * 前期使用 memcache, 写方法的时候考虑一下如何转换为 redis | ||
4 | - * @author bikai kai.bi@yoho.cn | ||
5 | - * @date 2016/05/16 | ||
6 | - */ | ||
7 | -'use strict'; | ||
8 | -const Promise = require('bluebird'); | ||
9 | -const Memcached = require('memcached'); | ||
10 | -const _ = require('lodash'); | ||
11 | -const config = require('../config/common'); | ||
12 | - | ||
13 | -let master = new Memcached(config.memcache.master, config.memcache); | ||
14 | -let slave = new Memcached(config.memcache.slave, config.memcache); | ||
15 | - | ||
16 | -master = Promise.promisifyAll(master); | ||
17 | -slave = Promise.promisifyAll(slave); | ||
18 | - | ||
19 | -/** | ||
20 | - * 获取缓存 | ||
21 | - * @param {[string]} key 键 | ||
22 | - * @return {[type]} | ||
23 | - */ | ||
24 | -exports.get = (key) => { | ||
25 | - if (_.isString(key)) { | ||
26 | - return master.getAsync(key); | ||
27 | - } | ||
28 | - | ||
29 | - return Promise.resolve(); | ||
30 | -}; | ||
31 | - | ||
32 | -/** | ||
33 | - * 批量获取缓存 | ||
34 | - * @param {[array]} list 字符串数组 | ||
35 | - * @return {[type]} | ||
36 | - */ | ||
37 | -exports.getMulti = (list) => { | ||
38 | - if (_.isArray(list)) { | ||
39 | - return master.getMultiAsync(list); | ||
40 | - } | ||
41 | - return Promise.resolve(); | ||
42 | -}; | ||
43 | - | ||
44 | -/** | ||
45 | - * 获取缓存(从 Slave 服务器) | ||
46 | - * @param {[string]} key 键 | ||
47 | - * @return {[type]} | ||
48 | - */ | ||
49 | -exports.getFromSlave = (key) => { | ||
50 | - if (_.isString(key)) { | ||
51 | - return slave.getAsync(key); | ||
52 | - } | ||
53 | - return Promise.resolve(); | ||
54 | -}; | ||
55 | - | ||
56 | -/** | ||
57 | - * 批量获取缓存(从 Slave 服务器) | ||
58 | - * @param {[array]} list 字符串数组 | ||
59 | - * @return {[type]} | ||
60 | - */ | ||
61 | -exports.getMultiFromSlave = (list) => { | ||
62 | - if (_.isArray(list)) { | ||
63 | - return slave.getMultiAsync(list); | ||
64 | - } | ||
65 | - return Promise.resolve(); | ||
66 | -}; | ||
67 | - | ||
68 | -/** | ||
69 | - * 写缓存 | ||
70 | - * @param {[type]} key 键 | ||
71 | - * @param {[type]} value 值 | ||
72 | - * @param {[type]} lifetime 生命周期 | ||
73 | - * @return {[type]} | ||
74 | - */ | ||
75 | -exports.set = (key, value, lifetime) => { | ||
76 | - lifetime = lifetime || 86400; | ||
77 | - | ||
78 | - if (_.isObject(value)) { | ||
79 | - value = JSON.stringify(value); | ||
80 | - } | ||
81 | - | ||
82 | - if (_.isString(key)) { | ||
83 | - return master.setAsync(key, value, lifetime); | ||
84 | - } | ||
85 | - return Promise.resolve(); | ||
86 | -}; | ||
87 | - | ||
88 | -/** | ||
89 | - * 写缓存(到 Slave 服务器) | ||
90 | - * @param {[type]} key 键 | ||
91 | - * @param {[type]} value 值 | ||
92 | - * @param {[type]} lifetime 生命周期 | ||
93 | - * @return {[type]} | ||
94 | - */ | ||
95 | -exports.setSlave = (key, value, lifetime) => { | ||
96 | - lifetime = lifetime || 86400; | ||
97 | - | ||
98 | - if (_.isObject(value)) { | ||
99 | - value = JSON.stringify(value); | ||
100 | - } | ||
101 | - | ||
102 | - if (_.isString(key)) { | ||
103 | - return slave.setAsync(key, value, lifetime); | ||
104 | - } | ||
105 | - return Promise.resolve(); | ||
106 | -}; | ||
107 | - | ||
108 | -/** | ||
109 | - * 删除缓存 | ||
110 | - * @param {[string]} key 键 | ||
111 | - * @return {[type]} | ||
112 | - */ | ||
113 | -exports.del = (key) => { | ||
114 | - if (_.isString(key)) { | ||
115 | - return master.delAsync(key); | ||
116 | - } | ||
117 | - return Promise.resolve(); | ||
118 | -}; |
library/camel-case.js
deleted
100644 → 0
1 | -/** | ||
2 | - * 对象键名驼峰化 | ||
3 | - * @author: Bi Kai<kai.bi@yoho.cn> | ||
4 | - * @date: 2016/05/09 | ||
5 | - */ | ||
6 | -'use strict'; | ||
7 | -const _ = require('lodash'); | ||
8 | - | ||
9 | -let camelCase, | ||
10 | - camelCaseObject, | ||
11 | - camelCaseArray; | ||
12 | - | ||
13 | -camelCaseObject = (obj) => { | ||
14 | - _.forEach(Object.keys(obj), (k) => { | ||
15 | - obj[k] = camelCase(obj[k]); | ||
16 | - if (/[_-]/.test(k)) { | ||
17 | - obj[_.camelCase(k)] = obj[k]; | ||
18 | - delete obj[k]; | ||
19 | - } | ||
20 | - }); | ||
21 | - return obj; | ||
22 | -}; | ||
23 | - | ||
24 | -camelCaseArray = (list) => { | ||
25 | - _.forEach(list, (k) => { | ||
26 | - k = camelCase(k); | ||
27 | - }); | ||
28 | - return list; | ||
29 | -}; | ||
30 | - | ||
31 | -camelCase = (data) => { | ||
32 | - if (_.isArray(data)) { | ||
33 | - data = camelCaseArray(data); | ||
34 | - } else if (_.isObject(data)) { | ||
35 | - data = camelCaseObject(data); | ||
36 | - } | ||
37 | - | ||
38 | - return data; | ||
39 | -}; | ||
40 | - | ||
41 | -module.exports = camelCase; |
library/cookie.js
deleted
100644 → 0
1 | -/** | ||
2 | - * 获取 UID | ||
3 | - * @param {[object]} req | ||
4 | - * @return {[string]} | ||
5 | - */ | ||
6 | -'use strict'; | ||
7 | -const sign = require('./sign'); | ||
8 | - | ||
9 | -exports.getUid = (req) => { | ||
10 | - const cookie = req.cookies._UID; | ||
11 | - let _uid = 0; | ||
12 | - let cookieList; | ||
13 | - | ||
14 | - if (req.isApp) { | ||
15 | - return req.query.uid || 0; | ||
16 | - } | ||
17 | - | ||
18 | - if (cookie) { | ||
19 | - cookieList = cookie.split('::'); | ||
20 | - if (cookieList[1] && !isNaN(cookieList[1])) { | ||
21 | - _uid = cookieList[1]; | ||
22 | - } | ||
23 | - } | ||
24 | - | ||
25 | - // 校验 cookie 的 uid 有没有被修改 | ||
26 | - if (req.cookies._TOKEN !== sign.makeToken(_uid)) { | ||
27 | - _uid = 0; | ||
28 | - } | ||
29 | - | ||
30 | - return _uid; | ||
31 | -}; | ||
32 | - | ||
33 | -exports.getShoppingKey = (req) => { | ||
34 | - return req.cookies['_SPK'] ? req.cookies['_SPK'] : ''; // eslint-disable-line | ||
35 | -}; |
library/helpers.js
deleted
100644 → 0
1 | -/** | ||
2 | - * Handlebars helpers | ||
3 | - * bikai kai.bi@yoho.cn | ||
4 | - * 2016-05-10 | ||
5 | - */ | ||
6 | -'use strict'; | ||
7 | -const querystring = require('querystring'); | ||
8 | -const _ = require('lodash'); | ||
9 | -const moment = require('moment'); | ||
10 | -const config = require('../config/common'); | ||
11 | - | ||
12 | -/** | ||
13 | - * 七牛图片路径处理 | ||
14 | - * @param {[string]} url | ||
15 | - * @param {[string]} width | ||
16 | - * @param {[string]} height | ||
17 | - * @param {[string]} mode | ||
18 | - * @return {[string]} | ||
19 | - */ | ||
20 | -exports.image = (url, width, height, mode) => { | ||
21 | - mode = _.isNumber(mode) ? mode : 2; | ||
22 | - url = url || ''; | ||
23 | - url = url.replace(/{width}/g, width).replace(/{height}/g, height).replace(/{mode}/g, mode); | ||
24 | - | ||
25 | - return url.replace('http:', ''); | ||
26 | -}; | ||
27 | - | ||
28 | -/** | ||
29 | - * 条件判断 | ||
30 | - * @param {[string]} v1 | ||
31 | - * @param {[string]} v2 | ||
32 | - * @param {[object]} options 上下文环境,一般不手动传 | ||
33 | - * @return {[boolen]} | ||
34 | - */ | ||
35 | -exports.isEqual = (v1, v2, _options) => { | ||
36 | - if (_.isEqual(v1, v2)) { | ||
37 | - return _options.fn(this); // eslint-disable-line | ||
38 | - } | ||
39 | - | ||
40 | - return _options.inverse(this); // eslint-disable-line | ||
41 | -}; | ||
42 | - | ||
43 | -/** | ||
44 | - * 站内地址格式化 | ||
45 | - * @param {[string]} uri 路径 | ||
46 | - * @param {[object]} qs 查询字符串 | ||
47 | - * @param {[string]} module 模块 | ||
48 | - * @return {[string]} | ||
49 | - */ | ||
50 | -exports.urlFormat = (uri, qs, module) => { | ||
51 | - const subDomain = '.m.yohobuy.com'; | ||
52 | - const subName = { | ||
53 | - default: config.siteUrl, | ||
54 | - guang: `//guang${subDomain}`, | ||
55 | - list: `//list${subDomain}`, | ||
56 | - search: `//search${subDomain}`, | ||
57 | - huodong: `//huodong${subDomain}`, | ||
58 | - activity: '//activity.yohobuy.com', | ||
59 | - index: config.siteUrl | ||
60 | - }; | ||
61 | - let url; | ||
62 | - | ||
63 | - module = module || 'default'; | ||
64 | - if (subName[module]) { | ||
65 | - url = subName[module]; | ||
66 | - } else { | ||
67 | - url = `//${module}${subDomain}`; // 规则没匹配到就把模块当作子域名 | ||
68 | - } | ||
69 | - | ||
70 | - url += uri; | ||
71 | - if (qs) { | ||
72 | - url += `?${querystring.stringify(qs)}`; | ||
73 | - } | ||
74 | - | ||
75 | - return url; | ||
76 | -}; | ||
77 | - | ||
78 | -/** | ||
79 | - * 大写转小写处理 | ||
80 | - * @param {[string]} str 转换字符 | ||
81 | - */ | ||
82 | -exports.lowerCase = (str) => { | ||
83 | - str = str || ''; | ||
84 | - return str.toLowerCase(); | ||
85 | -}; | ||
86 | - | ||
87 | -/** | ||
88 | - * 小写转大写处理 | ||
89 | - * @param {[string]} str 转换字符 | ||
90 | - */ | ||
91 | -exports.upperCase = (str) => { | ||
92 | - str = str || ''; | ||
93 | - return str.toUpperCase(); | ||
94 | -}; | ||
95 | - | ||
96 | - | ||
97 | -/** | ||
98 | - * 四舍五入 | ||
99 | - * @param {[type]} num 数字 | ||
100 | - * @param {[type]} precision 精度 | ||
101 | - * @return {[type]} | ||
102 | - */ | ||
103 | -exports.round = (num, precision) => { | ||
104 | - precision = _.isNumber(precision) ? precision : 2; | ||
105 | - num = _.isInteger(num) ? (+num).toFixed(precision) : _.round(num, precision); | ||
106 | - return num; | ||
107 | -}; | ||
108 | - | ||
109 | -/** | ||
110 | - * 链接改成自适应链接 | ||
111 | - * @return {[type]} | ||
112 | - */ | ||
113 | -exports.https = (url) => { | ||
114 | - return url.replace('http:', ''); | ||
115 | -}; | ||
116 | - | ||
117 | -/** | ||
118 | - * 时间格式化 | ||
119 | - * @param format 格式化token @see{http://momentjs.cn/docs/#/displaying/format/} | ||
120 | - * @param date 日期或者数字 | ||
121 | - * @return string | ||
122 | - * | ||
123 | - */ | ||
124 | -exports.dateFormat = (format, date) => { | ||
125 | - if (typeof format !== 'string' || typeof date === 'undefined') { | ||
126 | - return ''; | ||
127 | - } else { | ||
128 | - if (date instanceof Date) { | ||
129 | - return moment(date).format(format); | ||
130 | - } else { | ||
131 | - const d = moment.unix(date); | ||
132 | - | ||
133 | - return moment(d).utc().format(format); | ||
134 | - } | ||
135 | - } | ||
136 | -}; | ||
137 | - | ||
138 | -/** | ||
139 | - * 时间差格式化 | ||
140 | - * @param {[string]} format 格式化字符串 | ||
141 | - * @param {[number]} diff 相差值 | ||
142 | - * @param {[string]} type diff时间类型 默认ms | ||
143 | - * | ||
144 | - * Key Shorthand | ||
145 | - * years y | ||
146 | - * quarters Q | ||
147 | - * months M | ||
148 | - * weeks w | ||
149 | - * days d | ||
150 | - * hours h | ||
151 | - * minutes m | ||
152 | - * seconds s | ||
153 | - * milliseconds ms | ||
154 | - * | ||
155 | - * @example | ||
156 | - * let diff = 60 * 60 * 24 * (1.3) + 2; | ||
157 | - * | ||
158 | - * let s = helpers.dateDiffFormat('{d}天{h}小时', diff, 's'); | ||
159 | - * >>> 1天7小时 | ||
160 | - */ | ||
161 | -exports.dateDiffFormat = (format, diff, type) => { | ||
162 | - if (typeof format !== 'string' || typeof diff === 'undefined') { | ||
163 | - return ''; | ||
164 | - } else { | ||
165 | - type = type || 'ms'; | ||
166 | - const m = moment.duration(diff, type); | ||
167 | - | ||
168 | - format.match(/(\{.*?\})/g).forEach((s) => { | ||
169 | - format = format.replace(s, m.get(s.substring(1, s.length - 1))); | ||
170 | - }); | ||
171 | - | ||
172 | - return format; | ||
173 | - } | ||
174 | -}; | ||
175 | - | ||
176 | -/** | ||
177 | - * 验证邮箱是否合法 | ||
178 | - * | ||
179 | - * @param string email | ||
180 | - * @return boolean | ||
181 | - */ | ||
182 | -exports.verifyEmail = (email) => { | ||
183 | - if (!email) { | ||
184 | - return false; | ||
185 | - } | ||
186 | - | ||
187 | - const emailRegExp = /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/; | ||
188 | - | ||
189 | - return emailRegExp.test(email); | ||
190 | -}; | ||
191 | - | ||
192 | -/** | ||
193 | - * 各国手机号规则 | ||
194 | - */ | ||
195 | -function areaMobileVerify(phone, area) { | ||
196 | - area = area || '86'; | ||
197 | - phone = phone.trim(); | ||
198 | - | ||
199 | - let verify = { | ||
200 | - 86: { | ||
201 | - name: '中国', | ||
202 | - match: /^1[3|4|5|8|7][0-9]{9}$/.test(phone) | ||
203 | - }, | ||
204 | - 852: { | ||
205 | - name: '中国香港', | ||
206 | - match: /^[9|6|5][0-9]{7}$/.test(phone) | ||
207 | - }, | ||
208 | - 853: { | ||
209 | - name: '中国澳门', | ||
210 | - match: /^[0-9]{8}$/.test(phone) | ||
211 | - }, | ||
212 | - 886: { | ||
213 | - name: '中国台湾', | ||
214 | - match: /^[0-9]{10}$/.test(phone) | ||
215 | - }, | ||
216 | - 65: { | ||
217 | - name: '新加坡', | ||
218 | - match: /^[9|8][0-9]{7}$/.test(phone) | ||
219 | - }, | ||
220 | - 60: { | ||
221 | - name: '马来西亚', | ||
222 | - match: /^1[1|2|3|4|6|7|9][0-9]{8}$/.test(phone) | ||
223 | - }, | ||
224 | - 1: { | ||
225 | - name: '加拿大&美国', | ||
226 | - match: /^[0-9]{10}$/.test(phone) | ||
227 | - }, | ||
228 | - 82: { | ||
229 | - name: '韩国', | ||
230 | - match: /^01[0-9]{9}$/.test(phone) | ||
231 | - }, | ||
232 | - 44: { | ||
233 | - name: '英国', | ||
234 | - match: /^7[7|8|9][0-9]{8}$/.test(phone) | ||
235 | - }, | ||
236 | - 81: { | ||
237 | - name: '日本', | ||
238 | - match: /^0[9|8|7][0-9]{9}$/.test(phone) | ||
239 | - }, | ||
240 | - 61: { | ||
241 | - name: '澳大利亚', | ||
242 | - match: /^[0-9]{11}$/.test(phone) | ||
243 | - } | ||
244 | - }; | ||
245 | - | ||
246 | - if (verify[area]) { | ||
247 | - return verify[area].match; | ||
248 | - } else { | ||
249 | - return false; | ||
250 | - } | ||
251 | -} | ||
252 | - | ||
253 | -/** | ||
254 | - * 验证国际手机号是否合法 | ||
255 | - */ | ||
256 | -exports.verifyAreaMobile = (areaMobile) => { | ||
257 | - if (!areaMobile) { | ||
258 | - return false; | ||
259 | - } | ||
260 | - | ||
261 | - let mobile = { | ||
262 | - area: '86', | ||
263 | - phone: '' | ||
264 | - }; | ||
265 | - | ||
266 | - let splitMobile = areaMobile.split('-'); | ||
267 | - | ||
268 | - if (splitMobile.length === 2) { | ||
269 | - mobile.area = splitMobile[0]; | ||
270 | - mobile.phone = splitMobile[1]; | ||
271 | - } else { | ||
272 | - mobile.phone = splitMobile[0]; | ||
273 | - } | ||
274 | - | ||
275 | - return areaMobileVerify(mobile.phone, mobile.area); | ||
276 | -}; | ||
277 | - | ||
278 | -/** | ||
279 | - * 验证手机是否合法 | ||
280 | - */ | ||
281 | -exports.verifyMobile = (phone) => { | ||
282 | - if (!phone) { | ||
283 | - return false; | ||
284 | - } | ||
285 | - | ||
286 | - return /^1[3|4|5|8|7][0-9]{9}$/.test(phone); | ||
287 | -}; | ||
288 | - | ||
289 | -/** | ||
290 | - * 验证密码规则 | ||
291 | - */ | ||
292 | -exports.verifyPassword = (password) => { | ||
293 | - if (!password) { | ||
294 | - return false; | ||
295 | - } | ||
296 | - | ||
297 | - return /^([a-zA-Z0-9\-\+_!@\#$%\^&\*\(\)\:\;\.=\[\]\\\',\?]){6,20}$/.test(password); | ||
298 | -}; |
library/logger.js
deleted
100644 → 0
1 | -/** | ||
2 | - * 日志工具类 | ||
3 | - * @author: hbomb<qiqi.zhou@yoho.cn> | ||
4 | - * @date: 2016/05/06 | ||
5 | - */ | ||
6 | -'use strict'; | ||
7 | - | ||
8 | -const winston = require('winston'); | ||
9 | -const config = require('../config/common'); | ||
10 | -const FileTransport = require('winston-daily-rotate-file'); | ||
11 | - | ||
12 | -require('influxdb-winston'); | ||
13 | - | ||
14 | -const logger = new(winston.Logger)({ | ||
15 | - transports: [ | ||
16 | - new(FileTransport)(config.loggers.infoFile), | ||
17 | - new(FileTransport)(config.loggers.errorFile), | ||
18 | - new(winston.transports.UdpTransport)(config.loggers.udp), | ||
19 | - new(winston.transports.Console)(config.loggers.console) | ||
20 | - ], | ||
21 | - exitOnError: false | ||
22 | -}); | ||
23 | - | ||
24 | -module.exports = logger; |
library/sign.js
deleted
100644 → 0
1 | -/** | ||
2 | - * 签名 | ||
3 | - * @author: bikai | ||
4 | - * @date: 2016/5/6 | ||
5 | - */ | ||
6 | - | ||
7 | -'use strict'; | ||
8 | -const _ = require('lodash'); | ||
9 | -const md5 = require('md5'); | ||
10 | - | ||
11 | -const privateKey = { | ||
12 | - android: 'fd4ad5fcfa0de589ef238c0e7331b585', | ||
13 | - iphone: 'a85bb0674e08986c6b115d5e3a4884fa', | ||
14 | - ipad: 'ad9fcda2e679cf9229e37feae2cdcf80', | ||
15 | - web: '0ed29744ed318fd28d2c07985d3ba633', | ||
16 | - yoho: 'fd4ad5fcsa0de589af23234ks1923ks', | ||
17 | - h5: 'fd4ad5fcfa0de589ef238c0e7331b585' | ||
18 | -}; | ||
19 | - | ||
20 | -/** | ||
21 | - * 排序参数 | ||
22 | - * @param {Object} argument 需要排序的参数对象 | ||
23 | - * @return {Object} 排序之后的参数对象 | ||
24 | - */ | ||
25 | -const packageSort = argument => { | ||
26 | - const newObj = {}; | ||
27 | - | ||
28 | - for (const k of Object.keys(argument).sort()) { | ||
29 | - newObj[k] = argument[k]; | ||
30 | - } | ||
31 | - | ||
32 | - return newObj; | ||
33 | -}; | ||
34 | - | ||
35 | -/** | ||
36 | - * 生成签名 | ||
37 | - * @param {Object} argument 需要签名的数据 | ||
38 | - * @return {string} 生成的签名字符串 | ||
39 | - */ | ||
40 | -const makeSign = argument => { | ||
41 | - const qs = []; | ||
42 | - | ||
43 | - _.forEach(argument, (value, key) => { | ||
44 | - qs.push(`${key}=${_.trim(value)}`); | ||
45 | - }); | ||
46 | - | ||
47 | - return md5(qs.join('&')).toLowerCase(); | ||
48 | -}; | ||
49 | - | ||
50 | -// 生成API签名,调用后端接口的时候有私钥校验 | ||
51 | -exports.apiSign = (params) => { | ||
52 | - const clientType = params.client_type || 'h5'; | ||
53 | - | ||
54 | - /* eslint-disable */ | ||
55 | - let sign = packageSort(Object.assign({ | ||
56 | - client_type: clientType, | ||
57 | - private_key: privateKey[clientType], | ||
58 | - app_version: '4.6.0', | ||
59 | - os_version: 'yohobuy:h5', | ||
60 | - screen_size: '720x1280', | ||
61 | - v: '7' | ||
62 | - }, params)); | ||
63 | - /* eslint-enable */ | ||
64 | - | ||
65 | - sign = Object.assign(sign, { | ||
66 | - client_secret: makeSign(sign) // eslint-disable-line camelcase | ||
67 | - }); | ||
68 | - delete sign.private_key; | ||
69 | - return sign; | ||
70 | -}; | ||
71 | - | ||
72 | -// 检查签名,APP 访问 H5 页面的时候需要检查 | ||
73 | -exports.checkSign = (params) => { | ||
74 | - const // eslint-disable-line camelcase | ||
75 | - clientSecret = params.client_secret; | ||
76 | - | ||
77 | - let sortedParams; | ||
78 | - | ||
79 | - // 忽略部分参数 | ||
80 | - delete params.client_secret; | ||
81 | - delete params.q; | ||
82 | - delete params.debug_data; | ||
83 | - delete params['/api']; | ||
84 | - | ||
85 | - params.private_key = privateKey[params.client_type]; // eslint-disable-line camelcase | ||
86 | - sortedParams = packageSort(params); | ||
87 | - | ||
88 | - return clientSecret === makeSign(sortedParams); | ||
89 | -}; | ||
90 | - | ||
91 | -// 检查签名,APP 访问 H5 页面的时候需要检查, 有可能不同于上边的签名方式 | ||
92 | -exports.webSign = (params) => { | ||
93 | - const webPrivateKey = 'yohobuyapp'; | ||
94 | - | ||
95 | - return params.key === md5(md5(webPrivateKey) + params.uid); | ||
96 | -}; | ||
97 | - | ||
98 | -// 生成 token | ||
99 | -exports.makeToken = (string) => { | ||
100 | - return md5(md5(string + '#@!@#')); | ||
101 | -}; | ||
102 | - | ||
103 | -// 校验 token | ||
104 | -exports.verifyToken = (string, token) => { | ||
105 | - return exports.makeToken(string) === token; | ||
106 | -}; |
library/timer.js
deleted
100644 → 0
1 | -/** | ||
2 | - * 计时类 | ||
3 | - * @example | ||
4 | - * let timer = new Timer(); | ||
5 | - * timer.put('profile'); | ||
6 | - * timer.put('proflie'); // console output: 12.14 | ||
7 | - * | ||
8 | - * @author: hbomb<qiqi.zhou@yoho.cn> | ||
9 | - * @date: 2016/05/07 | ||
10 | - */ | ||
11 | -'use strict'; | ||
12 | -class Timer { | ||
13 | - constructor() { | ||
14 | - this.timers = {}; | ||
15 | - } | ||
16 | - | ||
17 | - /** | ||
18 | - * 打点计时 | ||
19 | - */ | ||
20 | - put(label) { | ||
21 | - const labelTime = this.timers[label]; | ||
22 | - | ||
23 | - if (labelTime) { | ||
24 | - const duration = process.hrtime(labelTime); | ||
25 | - | ||
26 | - return this._round(duration[0], duration[1]); | ||
27 | - } else { | ||
28 | - this.timers[label] = process.hrtime(); | ||
29 | - } | ||
30 | - } | ||
31 | - | ||
32 | - /** | ||
33 | - * 格式化成毫秒 | ||
34 | - * @param {Number} value 纳秒 | ||
35 | - */ | ||
36 | - _round(seconds, nanoseconds) { | ||
37 | - return Math.round((seconds * 1e9 + nanoseconds) / 10000) / 100; | ||
38 | - } | ||
39 | - | ||
40 | -} | ||
41 | - | ||
42 | -module.exports = Timer; |
test/library/api.test.js
deleted
100644 → 0
1 | -/** | ||
2 | - * http api 测试 | ||
3 | - * | ||
4 | - * @author: jiangfeng<jeff.jiang@yoho.cn> | ||
5 | - * @date: 2016/05/17 | ||
6 | - */ | ||
7 | -'use strict'; | ||
8 | - | ||
9 | -const test = require('ava'); | ||
10 | -const sign = require('../../library/sign'); | ||
11 | - | ||
12 | - | ||
13 | -const API = require('../../library/api').API; | ||
14 | -const ServiceAPI = require('../../library/api').ServiceAPI; | ||
15 | -const SearchAPI = require('../../library/api').SearchAPI; | ||
16 | - | ||
17 | -const getUrl = 'operations/api/v6/category/getCategory'; | ||
18 | - | ||
19 | -test('api constructor test', (t) => { | ||
20 | - let api = new ServiceAPI(); | ||
21 | - let api2 = new API(); | ||
22 | - let api3 = new SearchAPI(); | ||
23 | - | ||
24 | - t.true(api !== null); | ||
25 | - t.true(api2 !== null); | ||
26 | - t.true(api3 !== null); | ||
27 | -}); | ||
28 | - | ||
29 | -test('api get test', t => { | ||
30 | - let api = new ServiceAPI(); | ||
31 | - | ||
32 | - return api.get(getUrl, sign.apiSign({})).then(result => { | ||
33 | - if (result && result.code) { | ||
34 | - t.pass(); | ||
35 | - } else { | ||
36 | - t.fail(); | ||
37 | - } | ||
38 | - }); | ||
39 | -}); | ||
40 | - | ||
41 | -test('api get test, api return an error', t => { | ||
42 | - let api = new ServiceAPI(); | ||
43 | - | ||
44 | - return api.get(getUrl + '/error', sign.apiSign({})).catch(err => { | ||
45 | - | ||
46 | - // 故意调用一个错误的接口 | ||
47 | - if (err && err.code === 500) { | ||
48 | - t.pass(); | ||
49 | - } else { | ||
50 | - t.fail(); | ||
51 | - } | ||
52 | - }); | ||
53 | -}); | ||
54 | - | ||
55 | -test('api get use cache test', t => { | ||
56 | - let api = new ServiceAPI(); | ||
57 | - | ||
58 | - return api.get(getUrl, sign.apiSign({}), true).then(result => { | ||
59 | - if (result && result.code) { | ||
60 | - t.pass(); | ||
61 | - } else { | ||
62 | - t.fail(); | ||
63 | - } | ||
64 | - }); | ||
65 | -}); | ||
66 | - | ||
67 | -test('api post test', t => { | ||
68 | - let api = new ServiceAPI(); | ||
69 | - | ||
70 | - return api.post(getUrl, sign.apiSign({})).then(result => { | ||
71 | - if (result && result.code) { | ||
72 | - t.pass(); | ||
73 | - } else { | ||
74 | - t.fail(); | ||
75 | - } | ||
76 | - }); | ||
77 | -}); | ||
78 | - | ||
79 | -test('api multiple call test', (t) => { | ||
80 | - let api = new ServiceAPI(); | ||
81 | - let multi = [api.get(getUrl, sign.apiSign({})), api.get(getUrl, sign.apiSign({}))]; | ||
82 | - | ||
83 | - return api.all(multi).then(result => { | ||
84 | - if (result.length === 2) { | ||
85 | - t.pass(); | ||
86 | - } else { | ||
87 | - t.fail(); | ||
88 | - } | ||
89 | - }); | ||
90 | -}); | ||
91 | - | ||
92 | -test('api multiple fail call test', (t) => { | ||
93 | - let api = new ServiceAPI(); | ||
94 | - | ||
95 | - return api.all(1).catch((e) => { | ||
96 | - if (e) { | ||
97 | - t.pass(); | ||
98 | - } else { | ||
99 | - t.fail(); | ||
100 | - } | ||
101 | - }); | ||
102 | -}); |
test/library/cache.test.js
deleted
100644 → 0
1 | -/** | ||
2 | - * cache 测试 | ||
3 | - * | ||
4 | - * @author: jf<jeff.jiang@yoho.cn> | ||
5 | - * @date: 2016/5/18 | ||
6 | - */ | ||
7 | - | ||
8 | -'use strict'; | ||
9 | - | ||
10 | -import test from 'ava'; | ||
11 | - | ||
12 | -import cache from '../../library/cache'; | ||
13 | - | ||
14 | -let testKey = 'test_unit_key:' + (new Date()).getTime(); | ||
15 | -let testValue = 'anotherValue'; | ||
16 | -let anotherKey = 'test_unit_key2:' + (new Date()).getTime(); | ||
17 | -let anotherValue = {a: 1}; | ||
18 | - | ||
19 | -let slaveTestKey = 'test_unit_key3:' + (new Date()).getTime(); | ||
20 | -let slaveTestValue = 'anotherValue3'; | ||
21 | - | ||
22 | -test.before('set test key', (t) => { | ||
23 | - cache.set(testKey, testValue); | ||
24 | - cache.set(anotherKey, anotherValue); | ||
25 | - t.pass(); | ||
26 | -}); | ||
27 | - | ||
28 | -test.after('del test key', (t) => { | ||
29 | - cache.del(testKey); | ||
30 | - cache.del(anotherKey); | ||
31 | - t.pass(); | ||
32 | -}); | ||
33 | - | ||
34 | -test('cache get test', (t) => { | ||
35 | - return cache.get(testKey).then((v) => { | ||
36 | - t.is(v, testValue); | ||
37 | - }); | ||
38 | -}); | ||
39 | - | ||
40 | -test('cache get multi test', (t) => { | ||
41 | - cache.set(anotherKey, anotherValue); | ||
42 | - return cache.getMulti([testKey, anotherKey]).then((values) => { | ||
43 | - t.is(values[testKey], testValue); | ||
44 | - t.is(values[anotherKey], JSON.stringify(anotherValue)); | ||
45 | - }); | ||
46 | -}); | ||
47 | - | ||
48 | -test('cache get from slave test', (t) => { | ||
49 | - return cache.getFromSlave(testKey).then((v) => { | ||
50 | - t.is(v, testValue); | ||
51 | - }); | ||
52 | -}); | ||
53 | - | ||
54 | -test('cache get multi from slave test', (t) => { | ||
55 | - cache.set(anotherKey, anotherValue); | ||
56 | - return cache.getMultiFromSlave([testKey, anotherKey]).then((values) => { | ||
57 | - t.is(values[testKey], testValue); | ||
58 | - t.is(values[anotherKey], JSON.stringify(anotherValue)); | ||
59 | - }); | ||
60 | -}); | ||
61 | - | ||
62 | -test('cache set to slave', (t) => { | ||
63 | - return cache.setSlave(slaveTestKey, { | ||
64 | - value: slaveTestValue | ||
65 | - }).then(() => { | ||
66 | - return cache.getFromSlave(slaveTestKey); | ||
67 | - }).then((v) => { | ||
68 | - v = JSON.parse(v); | ||
69 | - t.is(v.value, slaveTestValue); | ||
70 | - cache.del(slaveTestKey); | ||
71 | - }); | ||
72 | -}); | ||
73 | - | ||
74 | -test('cache get test, key is not a string', (t) => { | ||
75 | - return cache.get(123).then((v) => { | ||
76 | - t.notOk(v); | ||
77 | - }); | ||
78 | -}); | ||
79 | - | ||
80 | -test('cache get multi test, key is not an array', (t) => { | ||
81 | - return cache.getMulti(123).then((v) => { | ||
82 | - t.notOk(v); | ||
83 | - }); | ||
84 | -}); | ||
85 | - | ||
86 | -test('cache get from slave test, key is not a string', (t) => { | ||
87 | - return cache.getFromSlave(123).then((v) => { | ||
88 | - t.notOk(v); | ||
89 | - }); | ||
90 | -}); | ||
91 | - | ||
92 | -test('cache get multi from slave test, key is not an array', (t) => { | ||
93 | - return cache.getMultiFromSlave(123).then((v) => { | ||
94 | - t.notOk(v); | ||
95 | - }); | ||
96 | -}); | ||
97 | - | ||
98 | -test('cache set test, key is not a string', (t) => { | ||
99 | - return cache.set(123).then((v) => { | ||
100 | - t.notOk(v); | ||
101 | - }); | ||
102 | -}); | ||
103 | - | ||
104 | -test('cache set multi test, key is not an array', (t) => { | ||
105 | - return cache.setSlave(123).then((v) => { | ||
106 | - t.notOk(v); | ||
107 | - }); | ||
108 | -}); | ||
109 | - | ||
110 | -test('cache del test, key is not a string', (t) => { | ||
111 | - return cache.del(123).then((v) => { | ||
112 | - t.notOk(v); | ||
113 | - }); | ||
114 | -}); |
test/library/camel-case.test.js
deleted
100644 → 0
1 | -/** | ||
2 | - * 对象键名驼峰测试 | ||
3 | - * | ||
4 | - * @author: jiangfeng<jeff.jiang@yoho.cn> | ||
5 | - * @date: 2016/05/17 | ||
6 | - */ | ||
7 | - | ||
8 | -import {test} from 'ava'; | ||
9 | - | ||
10 | -const camelCase = require('../../library/camel-case'); | ||
11 | - | ||
12 | -test('camel case object', t => { | ||
13 | - let o = { | ||
14 | - A_B: 'ab_cd' | ||
15 | - }; | ||
16 | - | ||
17 | - t.is(camelCase(o).aB, 'ab_cd'); | ||
18 | -}); | ||
19 | - | ||
20 | -test('camel case array', t => { | ||
21 | - let arr = [{ | ||
22 | - A_B: 'ab_cd' | ||
23 | - }, { | ||
24 | - A_B: 'ab_cd' | ||
25 | - }]; | ||
26 | - | ||
27 | - t.is(camelCase(arr)[1].aB, 'ab_cd'); | ||
28 | -}); |
test/library/helpers.test.js
deleted
100644 → 0
1 | -/** | ||
2 | - * library helpers 类单元测试 | ||
3 | - * @author jeff.jiang<jeff.jiang@yoho.cn> | ||
4 | - * @date 2016/05/17 | ||
5 | - */ | ||
6 | - | ||
7 | -'use strict'; | ||
8 | - | ||
9 | -const test = require('ava'); | ||
10 | -const helpers = require('../../library/helpers'); | ||
11 | - | ||
12 | -test('qiniu image url handle', t => { | ||
13 | - let url = 'http://img11.static.yhbimg.com/yhb-img01/2016/04/18/03/016d50b20cfdec5a91c614b68546bc9d72.jpg?imageView2/{mode}/w/{width}/h/{height}'; | ||
14 | - let expected = 'http://img11.static.yhbimg.com/yhb-img01/2016/04/18/03/016d50b20cfdec5a91c614b68546bc9d72.jpg?imageView2/2/w/400/h/300'; | ||
15 | - | ||
16 | - t.is(helpers.image(url, 400, 300), expected); | ||
17 | -}); | ||
18 | - | ||
19 | -test('uri format', t => { | ||
20 | - let uri = '/test'; | ||
21 | - let qs = { name: 'yoho' }; | ||
22 | - let mod = 'list'; | ||
23 | - let expected = '//list.m.yohobuy.com/test?name=yoho'; | ||
24 | - | ||
25 | - t.is(helpers.urlFormat(uri, qs, mod), expected); | ||
26 | -}); | ||
27 | - | ||
28 | -test('upper char to lowercase', t => { | ||
29 | - let str = 'ABc'; | ||
30 | - let expected = 'abc'; | ||
31 | - | ||
32 | - t.is(helpers.lowerCase(str), expected); | ||
33 | -}); | ||
34 | - | ||
35 | -test('lower char to uppercase', t => { | ||
36 | - let str = 'abc!'; | ||
37 | - let expected = 'ABC!'; | ||
38 | - | ||
39 | - t.is(helpers.upperCase(str), expected); | ||
40 | -}); | ||
41 | - | ||
42 | -test('date format test', (t) => { | ||
43 | - let seconds = 60 * 60 * 3 + 2; | ||
44 | - let str = helpers.dateFormat('HH:mm:ss', seconds, 'ss'); | ||
45 | - let expected = '03:00:02'; | ||
46 | - | ||
47 | - t.is(str, expected); | ||
48 | -}); | ||
49 | - | ||
50 | -test('date diff format test', (t) => { | ||
51 | - let seconds = 60 * 60 * 24 * (1.3) + 2; | ||
52 | - | ||
53 | - let str = helpers.dateDiffFormat('{d}天{h}小时', seconds, 's'); | ||
54 | - | ||
55 | - console.log(str); | ||
56 | - t.pass(); | ||
57 | -}); |
test/library/logger.test.js
deleted
100644 → 0
1 | -/** | ||
2 | - * logger 工具类测试 | ||
3 | - */ | ||
4 | - | ||
5 | -const test = require('ava'); | ||
6 | -const logger = require('../../library/logger'); | ||
7 | - | ||
8 | -test('logger error test', t => { | ||
9 | - logger.error('error test', () => { | ||
10 | - t.pass(); | ||
11 | - }); | ||
12 | -}); | ||
13 | - | ||
14 | -test('logger info test', t => { | ||
15 | - logger.info('info test', () => { | ||
16 | - t.pass(); | ||
17 | - }); | ||
18 | -}); |
test/library/sign.test.js
deleted
100644 → 0
1 | -/** | ||
2 | - * 签名类测试 | ||
3 | - * | ||
4 | - * @author: jiangfeng<jeff.jiang@yoho.cn> | ||
5 | - * @date: 2016/05/17 | ||
6 | - */ | ||
7 | - | ||
8 | -const test = require('ava'); | ||
9 | -const sign = require('../../library/sign'); | ||
10 | - | ||
11 | -test('app sign test', t => { | ||
12 | - let params = { | ||
13 | - client_type: 'h5', // eslint-disable-line | ||
14 | - a: 1, | ||
15 | - b: 'b' | ||
16 | - }; | ||
17 | - let signedParams = sign.apiSign(params); | ||
18 | - | ||
19 | - t.true(sign.checkSign(signedParams)); | ||
20 | -}); | ||
21 | - | ||
22 | -test('app sign test webSign', t => { | ||
23 | - let params = { | ||
24 | - uid: '123', | ||
25 | - key: '3fc5a9fcea9fea49cce5432202a167ad' | ||
26 | - }; | ||
27 | - | ||
28 | - t.true(sign.webSign(params)); | ||
29 | -}); |
test/library/timer.test.js
deleted
100644 → 0
1 | -/** | ||
2 | - * Timer 计时类测试 | ||
3 | - * | ||
4 | - * @author: jiangfeng<jeff.jiang@yoho.cn> | ||
5 | - * @date: 2016/05/17 | ||
6 | - */ | ||
7 | - | ||
8 | -const test = require('ava'); | ||
9 | -const Timer = require('../../library/timer'); | ||
10 | - | ||
11 | -const sleep = (timeout) => { | ||
12 | - return new Promise((resolve) => { | ||
13 | - setTimeout(() => { | ||
14 | - resolve(); | ||
15 | - }, timeout); | ||
16 | - }); | ||
17 | -}; | ||
18 | - | ||
19 | -test.cb('timer class ', t => { | ||
20 | - let timer = new Timer(); | ||
21 | - | ||
22 | - timer.put('test'); | ||
23 | - sleep(300).then(() => { | ||
24 | - let diff = timer.put('test'); | ||
25 | - | ||
26 | - t.true(diff >= 300); | ||
27 | - t.end(); | ||
28 | - }); | ||
29 | -}); |
-
Please register or login to post a comment