+// GetQRChannel gives a new channel of pairing items to the test.
+func (f *WhatsAppFake) GetQRChannel(_ context.Context) (<-chan whatsmeow.QRChannelItem, error) {
+ items := make(chan whatsmeow.QRChannelItem, 8)
+ f.pairings <- items
+
+ return items, nil
+}
+
+// PairPhone keeps phone and returns whatsappTestCode.
+func (f *WhatsAppFake) PairPhone(_ context.Context, phone string, _ bool, _ whatsmeow.PairClientType, _ string) (string, error) {
+ f.mutex.Lock()
+ defer f.mutex.Unlock()
+
+ f.phones = append(f.phones, phone)
+
+ return whatsappTestCode, nil
+}
+
+// Logout counts the logouts and returns logoutErr.
+func (f *WhatsAppFake) Logout(_ context.Context) error {
+ f.mutex.Lock()
+ defer f.mutex.Unlock()
+
+ f.logouts++
+
+ return f.logoutErr
+}
+
+// GetJoinedGroups returns groups.
+func (f *WhatsAppFake) GetJoinedGroups(_ context.Context) ([]*types.GroupInfo, error) {
+ f.mutex.Lock()
+ defer f.mutex.Unlock()
+
+ return f.groups, nil
+}
+
+// Download waits for downloadWait, records the request, and returns the made-up
+// image or downloadErr. A canceled context ends the wait.
+func (f *WhatsAppFake) Download(ctx context.Context, message whatsmeow.DownloadableMessage) ([]byte, error) {
+ if f.downloadWait > 0 {
+ timer := time.NewTimer(f.downloadWait)
+ defer timer.Stop()
+
+ select {
+ case <-ctx.Done():
+ return nil, ctx.Err()
+ case <-timer.C:
+ }
+ }
+
+ f.mutex.Lock()
+ defer f.mutex.Unlock()
+
+ f.downloads = append(f.downloads, message)
+
+ return slices.Clone(f.downloadData), f.downloadErr
+}
+
+// Downloads returns the media requested from the fake.
+func (f *WhatsAppFake) Downloads() []whatsmeow.DownloadableMessage {
+ f.mutex.Lock()
+ defer f.mutex.Unlock()
+
+ return slices.Clone(f.downloads)
+}
+
+// Upload records the pixels and returns made-up media metadata.
+func (f *WhatsAppFake) Upload(_ context.Context, data []byte, mediaType whatsmeow.MediaType) (whatsmeow.UploadResponse, error) {
+ f.mutex.Lock()
+ defer f.mutex.Unlock()
+
+ if mediaType != whatsmeow.MediaImage {
+ return whatsmeow.UploadResponse{}, fmt.Errorf("unexpected media type %q", mediaType)
+ }
+
+ f.uploads = append(f.uploads, slices.Clone(data))
+ if f.uploadErr != nil {
+ return whatsmeow.UploadResponse{}, f.uploadErr
+ }
+
+ return whatsmeow.UploadResponse{
+ URL: "https://example.com/image",
+ DirectPath: "/image",
+ MediaKey: []byte("made-up key"),
+ FileSHA256: []byte("made-up hash"),
+ FileEncSHA256: []byte("made-up encrypted hash"),
+ FileLength: uint64(len(data)),
+ }, nil
+}
+
+// Uploads returns the pixels passed to Upload.
+func (f *WhatsAppFake) Uploads() [][]byte {
+ f.mutex.Lock()
+ defer f.mutex.Unlock()
+
+ return slices.Clone(f.uploads)
+}
+
+// ImageSends returns the outgoing image messages.
+func (f *WhatsAppFake) ImageSends() []*waE2E.ImageMessage {
+ f.mutex.Lock()
+ defer f.mutex.Unlock()
+
+ return slices.Clone(f.imageSends)
+}
+
+// GenerateMessageID returns a new message ID.
+func (f *WhatsAppFake) GenerateMessageID() types.MessageID {
+ f.mutex.Lock()
+ defer f.mutex.Unlock()
+
+ return fmt.Sprintf("MSG%d", len(f.sent)+1)
+}
+
+// SendMessage keeps the send and returns sendErr.
+func (f *WhatsAppFake) SendMessage(_ context.Context, to types.JID, message *waE2E.Message, extra ...whatsmeow.SendRequestExtra) (whatsmeow.SendResponse, error) {
+ f.mutex.Lock()
+ defer f.mutex.Unlock()
+
+ if message.GetImageMessage() != nil {
+ f.imageSends = append(f.imageSends, message.GetImageMessage())
+ }
+
+ f.sent = append(f.sent, WhatsAppFakeSend{
+ to: to.String(),
+ text: message.GetConversation(),
+ id: extra[0].ID,
+ })
+
+ if f.sendErr != nil {
+ return whatsmeow.SendResponse{}, f.sendErr
+ }
+
+ return whatsmeow.SendResponse{
+ Timestamp: whatsappTestSendTime,
+ }, nil
+}
+
+// Sent returns the sends.
+func (f *WhatsAppFake) Sent() []WhatsAppFakeSend {
+ f.mutex.Lock()
+ defer f.mutex.Unlock()
+
+ return slices.Clone(f.sent)
+}
+
+// Phones returns the phone numbers of the pairings.
+func (f *WhatsAppFake) Phones() []string {
+ f.mutex.Lock()
+ defer f.mutex.Unlock()
+
+ return append([]string{}, f.phones...)
+}
+
+// Logouts returns the number of logouts.
+func (f *WhatsAppFake) Logouts() int {
+ f.mutex.Lock()
+ defer f.mutex.Unlock()
+
+ return f.logouts
+}
+