fix(qdreader): use upstream executable task endpoints

This commit is contained in:
2026-05-20 18:29:59 +08:00
parent 85405751b8
commit 9091137852
4 changed files with 296 additions and 30 deletions
+67 -5
View File
@@ -245,7 +245,7 @@ test('cron signs then immediately archives and clears recent logs', () => {
};
const r = runPlugin({ content: '', store, userId: 'cron', globals: { Date: fixedDateClass('2026-05-19T07:01:00.000+08:00') } });
assert.equal(r.calls.length, 4);
assert.match(r.calls[3].url, /getcurrentweekcheckininfo$/);
assert.match(r.calls[3].url, /receivegifts$/);
assert.match(r.replies[0], /启点读书签到结果/);
assert.match(r.replies[0], /日志已归档:2026-05-19/);
const archive = JSON.parse(r.store.qdreader_archive_json);
@@ -263,7 +263,7 @@ test('manual sign also archives immediately after run', () => {
};
const r = runPlugin({ content: '启点签到', store, userId: 'user-a', globals: { Date: fixedDateClass('2026-05-19T08:01:00.000+08:00') } });
assert.equal(r.calls.length, 4);
assert.match(r.calls[3].url, /getcurrentweekcheckininfo$/);
assert.match(r.calls[3].url, /receivegifts$/);
assert.match(r.replies[0], /日志已归档:2026-05-19/);
assert.equal(JSON.parse(r.store.qdreader_archive_json)['2026-05-19'].source, 'manual');
assert.deepEqual(JSON.parse(r.store.qdreader_last_run_json), {});
@@ -342,7 +342,7 @@ test('manual sign and cron sign both call sign gateway then qidian checkin', ()
assert.equal(manual.calls.length, 4);
assert.match(manual.calls[0].url, /api\.120399\.xyz\/qdreader\/sign$/);
assert.match(manual.calls[1].url, /h5\.if\.qidian\.com\/argus\/api\/v3\/checkin\/checkin$/);
assert.match(manual.calls[3].url, /getcurrentweekcheckininfo$/);
assert.match(manual.calls[3].url, /receivegifts$/);
assert.match(manual.replies[0], /✅ 12\*\*\*45/);
assert.match(manual.replies[0], /记录时间:/);
assert.equal(JSON.parse(manual.store.qdreader_archive_json)['2026-05-20'].source, 'manual');
@@ -355,12 +355,74 @@ test('manual sign and cron sign both call sign gateway then qidian checkin', ()
const cron = runPlugin({ content: '', store: { ...store }, globals: { Date: fixedDateClass('2026-05-19T07:01:00.000+08:00') } });
assert.equal(cron.calls.length, 4);
assert.match(cron.calls[3].url, /getcurrentweekcheckininfo$/);
assert.match(cron.calls[3].url, /receivegifts$/);
assert.match(cron.replies[0], /启点读书签到结果/);
assert.equal(JSON.parse(cron.store.qdreader_archive_json)['2026-05-19'].source, 'cron');
assert.deepEqual(JSON.parse(cron.store.qdreader_last_run_json), {});
});
test('optional QDReader full tasks use upstream executable endpoints and sign absolute message API', () => {
const store = {
qdreader_cookie_json: JSON.stringify({ '12345': cookie }),
qdreader_user_bind_json: JSON.stringify({ '12345': 'user-a' }),
qdreader_task_pref_json: JSON.stringify({ '12345': { adv: true, extraAdv: true, lottery: true, weeklyExchange: true, chapterCard: true, messageBox: true } }),
};
const originalDate = Date;
const sunday = fixedDateClass('2026-05-24T07:01:00.000+08:00');
const r = runPlugin({
content: '启点签到',
store,
userId: 'user-a',
globals: { Date: sunday },
requests: [
(req) => String(req.url).includes('/sign') ? { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } } : { statusCode: 200, body: { code: 0, msg: 'ok' } },
{ statusCode: 200, body: { code: 0, msg: '签到成功' } },
(req) => String(req.url).includes('/sign') ? { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } } : { statusCode: 200, body: { code: 0, msg: 'ok' } },
{ statusCode: 200, body: { code: 0, msg: '奖励完成' } },
(req) => String(req.url).includes('/sign') ? { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } } : { statusCode: 200, body: { code: 0, msg: 'ok' } },
{ statusCode: 200, body: { code: 0, Data: { VideoRewardTab: { TaskList: [{ TaskId: 'adv-1', IsFinished: 0 }] } } } },
(req) => String(req.url).includes('/sign') ? { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } } : { statusCode: 200, body: { code: 0, msg: 'ok' } },
{ statusCode: 200, body: { code: 0, msg: '视频完成' } },
(req) => String(req.url).includes('/sign') ? { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } } : { statusCode: 200, body: { code: 0, msg: 'ok' } },
{ statusCode: 200, body: { code: 0, Data: { TaskList: [{ TaskId: 'daily-1', TaskName: '每日任务', IsFinished: 0, NeedWatchCount: 1 }] } } },
(req) => String(req.url).includes('/sign') ? { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } } : { statusCode: 200, body: { code: 0, msg: 'ok' } },
{ statusCode: 200, body: { code: 0, msg: '每日视频完成' } },
(req) => String(req.url).includes('/sign') ? { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } } : { statusCode: 200, body: { code: 0, msg: 'ok' } },
{ statusCode: 200, body: { code: 0, Data: { HasVideoUrge: 0, LotteryCount: 1 } } },
(req) => String(req.url).includes('/sign') ? { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } } : { statusCode: 200, body: { code: 0, msg: 'ok' } },
{ statusCode: 200, body: { code: 0, msg: '抽奖成功' } },
(req) => String(req.url).includes('/sign') ? { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } } : { statusCode: 200, body: { code: 0, msg: 'ok' } },
{ statusCode: 200, body: { code: 0, Data: { Balance: 100, GoodsList: [{ GoodsId: 'g1', NeedScore: 10 }] } } },
(req) => String(req.url).includes('/sign') ? { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } } : { statusCode: 200, body: { code: 0, msg: 'ok' } },
{ statusCode: 200, body: { code: 0, msg: '兑换成功' } },
(req) => String(req.url).includes('/sign') ? { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } } : { statusCode: 200, body: { code: 0, msg: 'ok' } },
{ statusCode: 200, body: { code: 0, Data: { Cards: [{ id: 1 }] } } },
(req) => String(req.url).includes('/sign') ? { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } } : { statusCode: 200, body: { code: 0, msg: 'ok' } },
{ statusCode: 200, body: { code: 0, Data: { List: [] } } },
],
});
const urls = r.calls.map(c => c.url);
assert.ok(urls.some(u => /argus\/api\/v3\/checkin\/receivegifts$/.test(u)));
assert.ok(urls.some(u => /argus\/api\/v2\/video\/adv\/mainPage$/.test(u)));
assert.ok(urls.some(u => /argus\/api\/v1\/video\/adv\/finishWatch$/.test(u)));
assert.ok(urls.some(u => /argus\/api\/v3\/checkin\/packagelist$/.test(u)));
assert.ok(urls.some(u => /argus\/api\/v2\/checkin\/detail$/.test(u)));
assert.ok(urls.some(u => /argus\/api\/v2\/checkin\/lottery$/.test(u)));
assert.ok(urls.some(u => /argus\/api\/v3\/checkin\/checkinexchangepage$/.test(u)));
assert.ok(urls.some(u => /argus\/api\/v3\/checkin\/exchangegoods$/.test(u)));
assert.ok(urls.some(u => /argus\/api\/v1\/readtime\/scoremall\/chaptercardwithbook$/.test(u)));
assert.ok(urls.some(u => /^https:\/\/magev6\.if\.qidian\.com\/argus\/api\/v2\/message\/pullmessage/.test(u)));
const signed = r.calls.filter(c => /api\.120399\.xyz\/qdreader\/sign$/.test(c.url)).map(c => JSON.parse(c.body).url);
assert.ok(signed.includes('https://magev6.if.qidian.com/argus/api/v2/message/pullmessage'));
assert.match(r.replies[0], /激励任务✅/);
assert.match(r.replies[0], /每日任务✅/);
assert.match(r.replies[0], /每日抽奖✅/);
assert.match(r.replies[0], /每周兑换✅/);
assert.match(r.replies[0], /章节卡片✅/);
assert.match(r.replies[0], /大咖荐书✅/);
});
test('bucketGet/bucketSet fallback rejects when user identity is absent', () => {
const replies = [];
const bucketStore = {};
@@ -585,7 +647,7 @@ test('account task menu stores full task switches per account and sign uses sele
const sign = runPlugin({ content: '启点签到', store: { ...store, qdreader_task_pref_json: JSON.stringify({ '12345': { adv: true } }) }, userId: 'user-a' });
assert.equal(sign.calls.length, 6);
assert.match(sign.calls[3].url, /getcurrentweekcheckininfo$/);
assert.match(sign.calls[3].url, /receivegifts$/);
assert.match(sign.calls[5].url, /video\/adv\/mainPage$/);
assert.match(sign.replies[0], /激励任务/);
});