98 lines
3.2 KiB
Go
98 lines
3.2 KiB
Go
package rpc
|
||
|
||
import (
|
||
"bytes"
|
||
"encoding/binary"
|
||
"testing"
|
||
|
||
"github.com/iamxvbaba/td/tg"
|
||
|
||
"telesrv/internal/domain"
|
||
)
|
||
|
||
// TestBusinessAuthKeyInt64 钉死 [8]byte→int64 与 store/postgres authKeyIDToInt64
|
||
// 同源(小端,MTProto 即 SHA1 低 64 位)。两者漂移会让密聊绑定键与
|
||
// update_states/authorizations 对不上。
|
||
func TestBusinessAuthKeyInt64(t *testing.T) {
|
||
cases := [][8]byte{
|
||
{1, 0, 0, 0, 0, 0, 0, 0},
|
||
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
||
{0xde, 0xad, 0xbe, 0xef, 0x01, 0x02, 0x03, 0x04},
|
||
}
|
||
for _, id := range cases {
|
||
want := int64(binary.LittleEndian.Uint64(id[:]))
|
||
if got := businessAuthKeyInt64(id); got != want {
|
||
t.Fatalf("businessAuthKeyInt64(%v) = %d, want %d (little-endian, 同 authKeyIDToInt64)", id, got, want)
|
||
}
|
||
}
|
||
}
|
||
|
||
func baseChat() domain.SecretChat {
|
||
return domain.SecretChat{
|
||
ID: 7,
|
||
AdminUserID: 1,
|
||
ParticipantUserID: 2,
|
||
AdminAccessHash: 111,
|
||
ParticipantAccessHash: 222,
|
||
GA: []byte{0x0a, 0x0b},
|
||
GB: []byte{0x0c, 0x0d},
|
||
KeyFingerprint: 99,
|
||
Date: 1000,
|
||
}
|
||
}
|
||
|
||
func TestEncryptedChatForViewerRequested(t *testing.T) {
|
||
chat := baseChat()
|
||
chat.State = domain.SecretChatStateRequested
|
||
|
||
// admin 视角:encryptedChatWaiting(无 g_a),access_hash=admin。
|
||
adminView, ok := tgEncryptedChatForViewer(chat, 1).(*tg.EncryptedChatWaiting)
|
||
if !ok {
|
||
t.Fatalf("admin view type = %T, want *tg.EncryptedChatWaiting", tgEncryptedChatForViewer(chat, 1))
|
||
}
|
||
if adminView.ID != 7 || adminView.AccessHash != 111 || adminView.AdminID != 1 || adminView.ParticipantID != 2 {
|
||
t.Fatalf("admin waiting view = %+v", adminView)
|
||
}
|
||
|
||
// participant 视角:encryptedChatRequested(携 g_a),access_hash=participant。
|
||
partView, ok := tgEncryptedChatForViewer(chat, 2).(*tg.EncryptedChatRequested)
|
||
if !ok {
|
||
t.Fatalf("participant view type = %T, want *tg.EncryptedChatRequested", tgEncryptedChatForViewer(chat, 2))
|
||
}
|
||
if partView.AccessHash != 222 || !bytes.Equal(partView.GA, chat.GA) {
|
||
t.Fatalf("participant requested view = %+v", partView)
|
||
}
|
||
}
|
||
|
||
func TestEncryptedChatForViewerNormal(t *testing.T) {
|
||
chat := baseChat()
|
||
chat.State = domain.SecretChatStateNormal
|
||
|
||
// admin 视角:GAOrB = g_b。
|
||
adminView, ok := tgEncryptedChatForViewer(chat, 1).(*tg.EncryptedChat)
|
||
if !ok {
|
||
t.Fatalf("admin view type = %T, want *tg.EncryptedChat", tgEncryptedChatForViewer(chat, 1))
|
||
}
|
||
if adminView.AccessHash != 111 || !bytes.Equal(adminView.GAOrB, chat.GB) || adminView.KeyFingerprint != 99 {
|
||
t.Fatalf("admin normal view = %+v (GAOrB must be g_b)", adminView)
|
||
}
|
||
|
||
// participant 视角:GAOrB = g_a。
|
||
partView := tgEncryptedChatForViewer(chat, 2).(*tg.EncryptedChat)
|
||
if partView.AccessHash != 222 || !bytes.Equal(partView.GAOrB, chat.GA) {
|
||
t.Fatalf("participant normal view = %+v (GAOrB must be g_a)", partView)
|
||
}
|
||
}
|
||
|
||
func TestEncryptedChatForViewerDiscarded(t *testing.T) {
|
||
chat := baseChat()
|
||
chat.State = domain.SecretChatStateDiscarded
|
||
chat.HistoryDeleted = true
|
||
view, ok := tgEncryptedChatForViewer(chat, 1).(*tg.EncryptedChatDiscarded)
|
||
if !ok {
|
||
t.Fatalf("discarded view type = %T", tgEncryptedChatForViewer(chat, 1))
|
||
}
|
||
if view.ID != 7 || !view.HistoryDeleted {
|
||
t.Fatalf("discarded view = %+v", view)
|
||
}
|
||
}
|