fix(rpc): sync peer verification badge persistence
This commit is contained in:
parent
5e1f867b2d
commit
cec4361d8b
2 changed files with 73 additions and 1 deletions
|
|
@ -246,6 +246,71 @@ func TestUserAndUserFullCarryBotVerificationOnLayer228Bits(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestPeerSettingsUserPreservesBotVerificationOnLayer228Bit covers the chat-open
|
||||||
|
// race behind a disappearing badge. Official clients merge messages.peerSettings
|
||||||
|
// users into the same peer cache as users.getFullUser; therefore the auxiliary
|
||||||
|
// User must carry the same flags2.14 value regardless of which RPC arrives last.
|
||||||
|
func TestPeerSettingsUserPreservesBotVerificationOnLayer228Bit(t *testing.T) {
|
||||||
|
f := newBotVerificationFixture(t, newFakeBotVerifications())
|
||||||
|
f.enableVerifier(f.bot.ID, 8800011, true)
|
||||||
|
ownerCtx := WithUserID(context.Background(), f.owner.ID)
|
||||||
|
peer := &tg.InputPeerUser{UserID: f.target.ID, AccessHash: f.target.AccessHash}
|
||||||
|
|
||||||
|
peerSettingsUser := func() *tg.User {
|
||||||
|
t.Helper()
|
||||||
|
out, err := f.router.onMessagesGetPeerSettings(ownerCtx, peer)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("get peer settings: %v", err)
|
||||||
|
}
|
||||||
|
if len(out.Users) != 1 {
|
||||||
|
t.Fatalf("get peer settings returned %d users, want 1", len(out.Users))
|
||||||
|
}
|
||||||
|
wire := &tg.User{}
|
||||||
|
tlRoundTrip(t, out.Users[0].(*tg.User), wire)
|
||||||
|
return wire
|
||||||
|
}
|
||||||
|
|
||||||
|
plain := peerSettingsUser()
|
||||||
|
if _, ok := plain.GetBotVerificationIcon(); ok {
|
||||||
|
t.Fatalf("unmarked peer settings user carries an icon: %+v", plain)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ok, err := f.router.onBotsSetCustomVerification(ownerCtx,
|
||||||
|
setCustomVerificationRequest(inputPeerUser(f.target), inputUser(f.bot), true, "Stable in chat cache")); err != nil || !ok {
|
||||||
|
t.Fatalf("grant = %v,%v, want true,nil", ok, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exercise both possible response orders. Neither fullUser -> peerSettings nor
|
||||||
|
// peerSettings -> fullUser may turn the marked peer back into an unmarked one.
|
||||||
|
markedFull, _ := getFullUserProjection(t, f.router, f.owner.ID, f.target)
|
||||||
|
fullMark, ok := markedFull.GetBotVerification()
|
||||||
|
if !ok || fullMark.Icon != 8800011 {
|
||||||
|
t.Fatalf("userFull bot_verification = %+v, ok=%v, want icon 8800011", fullMark, ok)
|
||||||
|
}
|
||||||
|
marked := peerSettingsUser()
|
||||||
|
icon, ok := marked.GetBotVerificationIcon()
|
||||||
|
if !ok || icon != 8800011 {
|
||||||
|
t.Fatalf("peer settings user bot_verification_icon = %d, ok=%v, want 8800011", icon, ok)
|
||||||
|
}
|
||||||
|
assertFlagBitDelta(t, "peerSettings.user", plain.Flags2, marked.Flags2, 14)
|
||||||
|
|
||||||
|
marked = peerSettingsUser()
|
||||||
|
markedFull, _ = getFullUserProjection(t, f.router, f.owner.ID, f.target)
|
||||||
|
icon, ok = marked.GetBotVerificationIcon()
|
||||||
|
fullMark, fullOK := markedFull.GetBotVerification()
|
||||||
|
if !ok || icon != 8800011 || !fullOK || fullMark.Icon != icon {
|
||||||
|
t.Fatalf("reverse order drift: peer icon=%d ok=%v full=%+v ok=%v", icon, ok, fullMark, fullOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ok, err := f.router.onBotsSetCustomVerification(ownerCtx,
|
||||||
|
setCustomVerificationRequest(inputPeerUser(f.target), inputUser(f.bot), false, "")); err != nil || !ok {
|
||||||
|
t.Fatalf("revoke = %v,%v, want true,nil", ok, err)
|
||||||
|
}
|
||||||
|
if revoked := peerSettingsUser(); revoked.Flags2.Has(14) {
|
||||||
|
t.Fatalf("revoked peer settings user still carries flags2.14: %032b", uint32(revoked.Flags2))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TestBotInfoCarriesVerifierSettingsOnFlags9 pins botInfo#4d8a0299
|
// TestBotInfoCarriesVerifierSettingsOnFlags9 pins botInfo#4d8a0299
|
||||||
// verifier_settings:flags.9 inside the verifier bot's own userFull, and the operator
|
// verifier_settings:flags.9 inside the verifier bot's own userFull, and the operator
|
||||||
// kill switch: a disabled verifier stops advertising itself.
|
// kill switch: a disabled verifier stops advertising itself.
|
||||||
|
|
|
||||||
|
|
@ -534,9 +534,16 @@ func (r *Router) onMessagesGetPeerSettings(ctx context.Context, input tg.InputPe
|
||||||
}
|
}
|
||||||
r.peerSettingsProjectionCache.StoreIfEpoch(userID, peer, settings, loadEpoch)
|
r.peerSettingsProjectionCache.StoreIfEpoch(userID, peer, settings, loadEpoch)
|
||||||
}
|
}
|
||||||
|
users := r.peerSettingsUsers(ctx, userID, input)
|
||||||
|
// messages.getPeerSettings is requested while a chat is opened and official
|
||||||
|
// clients feed the returned peer objects into the same cache as getDialogs and
|
||||||
|
// getFullUser. Keep these auxiliary objects on the common response-boundary
|
||||||
|
// projection path: a full User without bot_verification_icon is authoritative
|
||||||
|
// to TDesktop/Android/TWeb and would clear a badge learned from another RPC.
|
||||||
|
r.applyPeerReadModels(ctx, userID, users, nil)
|
||||||
return &tg.MessagesPeerSettings{
|
return &tg.MessagesPeerSettings{
|
||||||
Settings: tgPeerSettings(settings),
|
Settings: tgPeerSettings(settings),
|
||||||
Users: r.peerSettingsUsers(ctx, userID, input),
|
Users: users,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue