跨端: fix(推送客户端): 登记标记绑定账号(token 换账号是"转移"不是并存 ⇒ 别把登记状态缓存成长期结论)

pi 邮件 `2518e1a3` 的服务端事实:注销只认注册者本人、token 字符串不是凭证,
**同一个 token 换账号登录是"转移"而不是并存** ⇒ "我登记过没有"的答案**随账号而变**。

原来的 `shouldReportToken(lastReported, current)` 只按 token 存标记 ⇒ 换账号后
(同一 token)会**错误地跳过上报**,而那个账号其实还没登记过这个 token。
改成 `reportMarker(accountKey, token) = accountKey|token` + `shouldReportToken(lastMarker, accountKey, token)`:
**账号变了标记必然不同** —— 于是"换账号必然重新上报"是**性质**,不靠人记得 reset。

判据 13 条全绿(新增"换账号后必然重新上报 / 切回来也要重新上报",并断言两次 marker 不相等)。
This commit is contained in:
2026-09-15 11:49:04 +08:00
parent 30886271ea
commit ab31690348
3 changed files with 79 additions and 12 deletions

View File

@ -13,11 +13,27 @@ const HERE = dirname(fileURLToPath(import.meta.url));
const HARMONY = join(HERE, '..', '..', 'harmony', 'entry', 'src', 'main', 'ets', 'model');
const C = await import(pathToFileURL(join(HARMONY, 'PushContract.ts')).href);
test('★ 上报决策:空 token 不上报;与上次相同不上报;变了才上报', () => {
assert.equal(C.shouldReportToken('', ''), false, '取不到 token 就不许上报(静默跳过)');
assert.equal(C.shouldReportToken('abc', 'abc'), false, '没变就不许重复上报(否则每次启动打一次接口)');
assert.equal(C.shouldReportToken('abc', 'xyz'), true, '变了要上报');
assert.equal(C.shouldReportToken('', 'xyz'), true, '第一次拿到要上报');
test('★ 上报决策:空 token 不上报;同账号同 token 不上报;变了才上报', () => {
assert.equal(C.shouldReportToken('', 'acct1', ''), false, '取不到 token 就不许上报(静默跳过)');
const m = C.reportMarker('acct1', 'abc');
assert.equal(C.shouldReportToken(m, 'acct1', 'abc'), false, '没变就不许重复上报(否则每次启动打一次接口)');
assert.equal(C.shouldReportToken(m, 'acct1', 'xyz'), true, 'token 变了要上报');
assert.equal(C.shouldReportToken('', 'acct1', 'xyz'), true, '第一次拿到要上报');
});
/*
★ 账号必须绑进标记(pi 邮件 `2518e1a3` 的服务端事实):同一个 token **换账号登录是"转移"不是并存**,
所以"我登记过没有"的答案**随账号而变**。只按 token 存标记 ⇒ 换账号后**错误跳过上报**,
而那个账号其实没登记过。这条判据钉的是"换账号必然重新上报"这个性质。
*/
test('★ 换账号后必然重新上报(token 转移不是并存 —— 别把登记状态缓存成长期结论)', () => {
const token = 'AAAABBBBCCCC123456';
const m1 = C.reportMarker('acct1', token);
assert.equal(C.shouldReportToken(m1, 'acct1', token), false, '同账号同 token:不重复上报');
assert.equal(C.shouldReportToken(m1, 'acct2', token), true,
'换账号 + 同一个 token ⇒ 必须重新上报(服务端是转移,acct2 其实没登记过)');
assert.notEqual(m1, C.reportMarker('acct2', token), '标记的形状就保证账号变了必然不同(不靠人记得 reset)');
assert.equal(C.shouldReportToken(C.reportMarker('acct2', token), 'acct1', token), true, '切回来也要重新上报');
});
test('★ "登记过没有"只按 provider + tail 比 —— 比全文是"看起来更严、其实永远为假"的写法', () => {