]> git.giacomolli.uk - onechat/blob - whatsapp_fake_helper_test.go
f7e6cad948f88fe2c46967f3ffce18852c3311da
[onechat] / whatsapp_fake_helper_test.go
1 package main
2
3 import (
4 "context"
5 "io"
6 "log"
7 "os"
8 "path/filepath"
9 "sync"
10 "testing"
11
12 "github.com/stretchr/testify/require"
13 waAdv "go.mau.fi/whatsmeow/proto/waAdv"
14 "go.mau.fi/whatsmeow/store"
15 "go.mau.fi/whatsmeow/store/sqlstore"
16 "go.mau.fi/whatsmeow/types"
17 waLog "go.mau.fi/whatsmeow/util/log"
18 )
19
20 // whatsappTestNumber is the phone number of the own account in the tests. It
21 // is a number for fiction.
22 const whatsappTestNumber = "15550001111"
23
24 // WhatsAppFake is a fake WhatsApp client. It keeps the event handler that the
25 // daemon gives it, and Emit gives events to the handler, as the library does.
26 type WhatsAppFake struct {
27 mutex sync.Mutex
28 handle func(event any) bool
29 connected chan struct{}
30 }
31
32 // ConnectContext tells the test that the daemon connected.
33 func (f *WhatsAppFake) ConnectContext(ctx context.Context) error {
34 close(f.connected)
35
36 return nil
37 }
38
39 // Disconnect does nothing.
40 func (f *WhatsAppFake) Disconnect() {
41 }
42
43 // Emit gives event to the handler of the daemon and returns its answer.
44 func (f *WhatsAppFake) Emit(event any) bool {
45 f.mutex.Lock()
46 handle := f.handle
47 f.mutex.Unlock()
48
49 return handle(event)
50 }
51
52 // newClient keeps handle and returns the fake as the client of device.
53 func (f *WhatsAppFake) newClient(device *store.Device, handle func(event any) bool) WhatsAppClient {
54 f.mutex.Lock()
55 defer f.mutex.Unlock()
56
57 f.handle = handle
58
59 return f
60 }
61
62 // whatsappStartTest opens the WhatsApp of the data directory dir with a fake
63 // client and the test clock, and closes it at the end of the test.
64 func whatsappStartTest(t *testing.T, dir string) (*WhatsApp, *WhatsAppFake) {
65 t.Helper()
66
67 fake := &WhatsAppFake{
68 connected: make(chan struct{}),
69 }
70
71 whatsapp, err := openWhatsApp(t.Context(), dir, newTestClock().Now, log.New(io.Discard, "", 0), fake.newClient)
72 require.NoError(t, err)
73
74 t.Cleanup(func() {
75 require.NoError(t, whatsapp.Close())
76 })
77
78 return whatsapp, fake
79 }
80
81 // whatsappTestSession writes a session database with mode 0600 to the data
82 // directory dir. When linked is true, it holds a device linked to
83 // whatsappTestNumber, and else a device with no link.
84 func whatsappTestSession(t *testing.T, dir string, linked bool) {
85 t.Helper()
86
87 path := filepath.Join(dir, whatsappDirName, whatsappSessionFileName)
88 require.NoError(t, os.MkdirAll(filepath.Dir(path), 0o700))
89 require.NoError(t, os.WriteFile(path, nil, 0o600))
90
91 address, err := whatsappSessionAddress(path)
92 require.NoError(t, err)
93
94 container, err := sqlstore.New(t.Context(), "sqlite", address, waLog.Noop)
95 require.NoError(t, err)
96
97 if linked {
98 device := container.NewDevice()
99 jid := types.NewADJID(whatsappTestNumber, 0, 1)
100 device.ID = &jid
101 device.Account = &waAdv.ADVSignedDeviceIdentity{
102 Details: []byte{},
103 AccountSignature: make([]byte, 64),
104 AccountSignatureKey: make([]byte, 32),
105 DeviceSignature: make([]byte, 64),
106 }
107 require.NoError(t, device.Save(t.Context()))
108 }
109
110 require.NoError(t, container.Close())
111 }