feat: 完善淘宝小程序拍照、报告与登录流程
接入本地实时识别和自动三连拍,调整报告裁切、商品跳转、分享标题及居中页眉;完善游客会话、后台渠道隔离、部署脚本与回归测试。
This commit is contained in:
@@ -7,7 +7,7 @@ test('cloud transport initializes once, preserves subpath/auth, caps timeout and
|
||||
application: { httpRequest: async input => { options = input; return { ok: true, http_status: 200 }; } } };
|
||||
const module = { exports: {} };
|
||||
vm.runInNewContext(fs.readFileSync(path.join(__dirname, '../utils/transport.js'), 'utf8'), {
|
||||
module, Promise, require(name) { return name === '../config' ? config : { default: cloud }; }
|
||||
module, Promise, setTimeout, clearTimeout, require(name) { return name === '../config' ? config : { default: cloud }; }
|
||||
});
|
||||
const transport = module.exports;
|
||||
await transport.request('/api/taobao/me', {}, 'token'); await transport.request('/api/taobao/reports', {}, 'token');
|
||||
@@ -26,7 +26,7 @@ test('聚石塔 tower transport omits domain and does not require HTTPS', async
|
||||
application: { httpRequest: async input => { options = input; return { success: true, data: { ok: true } }; } } };
|
||||
const module = { exports: {} };
|
||||
vm.runInNewContext(fs.readFileSync(path.join(__dirname, '../utils/transport.js'), 'utf8'), {
|
||||
module, Promise, require(name) { return name === '../config' ? config : { default: cloud }; }
|
||||
module, Promise, setTimeout, clearTimeout, require(name) { return name === '../config' ? config : { default: cloud }; }
|
||||
});
|
||||
const transport = module.exports;
|
||||
const data = await transport.request('/api/taobao/ping', {});
|
||||
@@ -35,3 +35,61 @@ test('聚石塔 tower transport omits domain and does not require HTTPS', async
|
||||
assert.equal(options.exts.domain, undefined);
|
||||
assert.equal(options.exts.cloudAppId, undefined);
|
||||
});
|
||||
|
||||
const flush = () => new Promise(resolve => setImmediate(resolve));
|
||||
function timeoutTransport(cloud, config = {}, platform = {}) {
|
||||
const timers = [], module = { exports: {} };
|
||||
vm.runInNewContext(fs.readFileSync(path.join(__dirname, '../utils/transport.js'), 'utf8'), {
|
||||
module, Promise, my: platform,
|
||||
setTimeout(fn, ms) { const timer = { fn, ms, active: true }; timers.push(timer); return timer; },
|
||||
clearTimeout(timer) { timer.active = false; },
|
||||
require(name) { return name === '../config' ? { transport: 'cloud', cloudType: 'tower', basePath: '', cloudEnv: 'test', ...config } : { default: cloud }; }
|
||||
});
|
||||
return { transport: module.exports, timers, expire(ms) {
|
||||
const timer = timers.find(value => value.active && value.ms === ms);
|
||||
assert(timer, 'expected active timeout ' + ms); timer.active = false; timer.fn();
|
||||
} };
|
||||
}
|
||||
|
||||
test('a hanging cloud initialization times out, permits retry and ignores its late result', async () => {
|
||||
let finishOld, initialized = 0, requests = 0;
|
||||
const f = timeoutTransport({ init: () => ++initialized === 1 ? new Promise(resolve => { finishOld = resolve; }) : Promise.resolve(true),
|
||||
application: { httpRequest: async () => { requests++; return { ok: true }; } } });
|
||||
const pending = f.transport.request('/api/taobao/analysis', {});
|
||||
const rejected = assert.rejects(pending, error => error.code === 'CLOUD_INIT_TIMEOUT');
|
||||
await flush(); f.expire(15000); await rejected;
|
||||
assert.equal(requests, 0);
|
||||
assert.equal((await f.transport.request('/api/taobao/analysis', {})).ok, true);
|
||||
finishOld(false); await flush();
|
||||
assert.equal((await f.transport.request('/api/taobao/analysis', {})).ok, true);
|
||||
assert.equal(initialized, 2); assert.equal(requests, 2);
|
||||
assert(!f.timers.some(timer => timer.active));
|
||||
});
|
||||
|
||||
test('a hanging cloud request is bounded independently of SDK timeout and does not poison later polling', async () => {
|
||||
let finishOld, requests = 0, initialized = 0;
|
||||
const f = timeoutTransport({ init: async () => { initialized++; return true; }, application: {
|
||||
httpRequest: () => ++requests === 1 ? new Promise(resolve => { finishOld = resolve; }) : Promise.resolve({ ok: true, status: 'complete' })
|
||||
} });
|
||||
const pending = f.transport.request('/api/taobao/analysis', { job: 'original-job' });
|
||||
const rejected = assert.rejects(pending, error => error.code === 'REQUEST_TIMEOUT');
|
||||
await flush(); f.expire(12000); await rejected;
|
||||
const result = await f.transport.request('/api/taobao/analysis', { job: 'original-job' });
|
||||
assert.equal(result.status, 'complete'); assert.equal(initialized, 1);
|
||||
finishOld({ ok: true, status: 'obsolete' }); await flush();
|
||||
assert.equal(result.status, 'complete'); assert(!f.timers.some(timer => timer.active));
|
||||
});
|
||||
|
||||
test('a direct request with no native callback times out and a late callback cannot complete it again', async () => {
|
||||
const calls = [];
|
||||
const f = timeoutTransport(null, { transport: 'direct', baseUrl: 'http://127.0.0.1:18180' }, {
|
||||
request(options) { calls.push(options); }
|
||||
});
|
||||
const pending = f.transport.request('/api/taobao/analysis', {});
|
||||
const rejected = assert.rejects(pending, error => error.code === 'REQUEST_TIMEOUT');
|
||||
await flush(); f.expire(12000); await rejected;
|
||||
const retry = f.transport.request('/api/taobao/analysis', {}); await flush();
|
||||
calls[0].success({ status: 200, data: { ok: true, obsolete: true } });
|
||||
calls[1].success({ status: 200, data: { ok: true, current: true } });
|
||||
assert.equal((await retry).current, true); assert(!f.timers.some(timer => timer.active));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user