1
0
Fork 0
mirror of https://github.com/mautrix/signal.git synced 2026-05-14 21:26:54 -04:00
mautrix-signal/pkg/connector/client_test.go
2026-04-08 15:01:27 -07:00

196 lines
4.9 KiB
Go

package connector
import (
"context"
"testing"
"time"
"github.com/rs/zerolog"
"maunium.net/go/mautrix/bridgev2"
bridgev2database "maunium.net/go/mautrix/bridgev2/database"
"go.mau.fi/mautrix-signal/pkg/libsignalgo"
"go.mau.fi/mautrix-signal/pkg/signalid"
"go.mau.fi/mautrix-signal/pkg/signalmeow"
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/backuppb"
signalstore "go.mau.fi/mautrix-signal/pkg/signalmeow/store"
"go.mau.fi/mautrix-signal/pkg/signalmeow/types"
)
func TestLifecycleContextReplacementCancelsPrevious(t *testing.T) {
client := &SignalClient{}
firstCtx := client.newLifecycleContext(context.Background())
secondCtx := client.newLifecycleContext(context.Background())
select {
case <-firstCtx.Done():
default:
t.Fatal("expected previous lifecycle context to be canceled")
}
select {
case <-secondCtx.Done():
t.Fatal("expected current lifecycle context to remain active")
default:
}
client.cancelLifecycleContext()
select {
case <-secondCtx.Done():
case <-time.After(time.Second):
t.Fatal("expected lifecycle context to be canceled")
}
}
func TestSyncChatsStopsOnContextCancellation(t *testing.T) {
recipientLookupStarted := make(chan struct{})
backupStore := &backupStoreStub{
getBackupChatsFn: func(context.Context) ([]*signalstore.BackupChat, error) {
return []*signalstore.BackupChat{{
Chat: &backuppb.Chat{
Id: 1,
RecipientId: 2,
},
}}, nil
},
getBackupRecipientFn: func(ctx context.Context, recipientID uint64) (*backuppb.Recipient, error) {
close(recipientLookupStarted)
<-ctx.Done()
return nil, ctx.Err()
},
}
client := &SignalClient{
UserLogin: newTestUserLogin(),
Client: &signalmeow.Client{
Store: &signalstore.Device{
BackupStore: backupStore,
},
},
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
done := make(chan struct{})
go func() {
client.syncChats(ctx)
close(done)
}()
select {
case <-recipientLookupStarted:
case <-time.After(time.Second):
t.Fatal("timed out waiting for backup recipient lookup")
}
cancel()
select {
case <-done:
case <-time.After(time.Second):
t.Fatal("syncChats did not exit after context cancellation")
}
if client.UserLogin.Metadata.(*signalid.UserLoginMetadata).ChatsSynced {
t.Fatal("expected chat sync to stop before marking metadata as synced")
}
}
func TestSyncChatSkipsMissingBackupRecipient(t *testing.T) {
backupStore := &backupStoreStub{
getBackupRecipientFn: func(context.Context, uint64) (*backuppb.Recipient, error) {
return nil, nil
},
}
client := &SignalClient{
Client: &signalmeow.Client{
Store: &signalstore.Device{
BackupStore: backupStore,
},
},
}
ok := client.syncChat(context.Background(), &signalstore.BackupChat{
Chat: &backuppb.Chat{
Id: 1,
RecipientId: 2,
},
})
if !ok {
t.Fatal("expected missing backup recipient to be skipped")
}
}
func newTestUserLogin() *bridgev2.UserLogin {
return &bridgev2.UserLogin{
UserLogin: &bridgev2database.UserLogin{
Metadata: &signalid.UserLoginMetadata{},
},
Log: zerolog.Nop(),
}
}
type backupStoreStub struct {
getBackupChatsFn func(context.Context) ([]*signalstore.BackupChat, error)
getBackupRecipientFn func(context.Context, uint64) (*backuppb.Recipient, error)
deleteBackupChatFn func(context.Context, uint64) error
}
func (b *backupStoreStub) AddBackupRecipient(context.Context, *backuppb.Recipient) error {
return nil
}
func (b *backupStoreStub) AddBackupChat(context.Context, *backuppb.Chat) error {
return nil
}
func (b *backupStoreStub) AddBackupChatItem(context.Context, *backuppb.ChatItem) error {
return nil
}
func (b *backupStoreStub) RecalculateChatCounts(context.Context) error {
return nil
}
func (b *backupStoreStub) ClearBackup(context.Context) error {
return nil
}
func (b *backupStoreStub) GetBackupRecipient(ctx context.Context, recipientID uint64) (*backuppb.Recipient, error) {
if b.getBackupRecipientFn != nil {
return b.getBackupRecipientFn(ctx, recipientID)
}
return nil, nil
}
func (b *backupStoreStub) GetBackupChatByUserID(context.Context, libsignalgo.ServiceID) (*signalstore.BackupChat, error) {
return nil, nil
}
func (b *backupStoreStub) GetBackupChatByGroupID(context.Context, types.GroupIdentifier) (*signalstore.BackupChat, error) {
return nil, nil
}
func (b *backupStoreStub) GetBackupChats(ctx context.Context) ([]*signalstore.BackupChat, error) {
if b.getBackupChatsFn != nil {
return b.getBackupChatsFn(ctx)
}
return nil, nil
}
func (b *backupStoreStub) GetBackupChatItems(context.Context, uint64, time.Time, bool, int) ([]*backuppb.ChatItem, error) {
return nil, nil
}
func (b *backupStoreStub) DeleteBackupChat(ctx context.Context, chatID uint64) error {
if b.deleteBackupChatFn != nil {
return b.deleteBackupChatFn(ctx, chatID)
}
return nil
}
func (b *backupStoreStub) DeleteBackupChatItems(context.Context, uint64, time.Time) error {
return nil
}