]> git.giacomolli.uk - onechat/blobdiff - whatsapp_inbox_test.go
Add local context to chat operation failures
[onechat] / whatsapp_inbox_test.go
index cea65fec15ca501cf6b62b97bd96de14efc38a08..c086e0747e44e3b6510390de0c07f6e4760309dd 100644 (file)
@@ -3,6 +3,7 @@ package main
 import (
        "net/http"
        "testing"
 import (
        "net/http"
        "testing"
+       "testing/synctest"
        "time"
 
        "github.com/stretchr/testify/require"
        "time"
 
        "github.com/stretchr/testify/require"
@@ -56,13 +57,13 @@ func TestWhatsAppGroupTurns(t *testing.T) {
                turn    bool
        }{
                {
                turn    bool
        }{
                {
-                       name: "plain",
+                       name: "keeps plain group text without starting a turn",
                        message: func(_ *events.Message) {
                        },
                        line: "12:00 Bruno Lima: Who brings the cake?",
                },
                {
                        message: func(_ *events.Message) {
                        },
                        line: "12:00 Bruno Lima: Who brings the cake?",
                },
                {
-                       name: "mention",
+                       name: "starts a turn for a mention of the user",
                        message: func(event *events.Message) {
                                event.Message = &waE2E.Message{
                                        ExtendedTextMessage: &waE2E.ExtendedTextMessage{
                        message: func(event *events.Message) {
                                event.Message = &waE2E.Message{
                                        ExtendedTextMessage: &waE2E.ExtendedTextMessage{
@@ -77,7 +78,7 @@ func TestWhatsAppGroupTurns(t *testing.T) {
                        turn: true,
                },
                {
                        turn: true,
                },
                {
-                       name: "reply",
+                       name: "starts a turn for a reply to the user",
                        message: func(event *events.Message) {
                                event.Message = &waE2E.Message{
                                        ExtendedTextMessage: &waE2E.ExtendedTextMessage{
                        message: func(event *events.Message) {
                                event.Message = &waE2E.Message{
                                        ExtendedTextMessage: &waE2E.ExtendedTextMessage{
@@ -115,6 +116,9 @@ func TestWhatsAppGroupTurns(t *testing.T) {
                        event.Info.PushName = "Bruno Lima"
                        tc.message(event)
                        require.True(t, fake.Emit(event))
                        event.Info.PushName = "Bruno Lima"
                        tc.message(event)
                        require.True(t, fake.Emit(event))
+                       require.NoError(t, whatsapp.state.CloseAll())
+
+                       whatsapp.inbox.wake <- struct{}{}
 
                        text := "[WhatsApp] Family, group 120363000000000001@g.us, Thursday 2026-01-01\n" + tc.line
                        if tc.turn {
 
                        text := "[WhatsApp] Family, group 120363000000000001@g.us, Thursday 2026-01-01\n" + tc.line
                        if tc.turn {
@@ -133,6 +137,27 @@ func TestWhatsAppGroupTurns(t *testing.T) {
        }
 }
 
        }
 }
 
+func TestWhatsAppRunClosesABatchAfterQuietTime(t *testing.T) {
+       synctest.Test(t, func(t *testing.T) {
+               test := whatsappRetryTest(t)
+               test.start(t)
+               synctest.Wait()
+               require.True(t, test.fake.Emit(&events.Connected{}))
+               require.True(t, test.fake.Emit(&events.OfflineSyncCompleted{}))
+               synctest.Wait()
+               require.True(t, test.fake.Emit(whatsappTestMessage(whatsappTestAna, whatsappTestOwn, "m1", "On my way.", time.Now())))
+               synctest.Wait()
+               time.Sleep(whatsappBatchIdleTimeout - time.Nanosecond)
+               synctest.Wait()
+               require.Zero(t, test.loop.memory.Len())
+
+               time.Sleep(time.Nanosecond)
+               synctest.Wait()
+               require.Equal(t, 1, test.loop.memory.Len())
+               require.Contains(t, test.events.Last("work"), "You: On my way.")
+       })
+}
+
 func TestWhatsAppSkipsExcludedMessages(t *testing.T) {
        at := time.Date(2026, 1, 1, 12, 0, 0, 0, time.UTC)
        testCases := []struct {
 func TestWhatsAppSkipsExcludedMessages(t *testing.T) {
        at := time.Date(2026, 1, 1, 12, 0, 0, 0, time.UTC)
        testCases := []struct {
@@ -140,43 +165,43 @@ func TestWhatsAppSkipsExcludedMessages(t *testing.T) {
                change func(event *events.Message)
        }{
                {
                change func(event *events.Message)
        }{
                {
-                       name: "an edit",
+                       name: "ignores an edit",
                        change: func(event *events.Message) {
                                event.IsEdit = true
                        },
                },
                {
                        change: func(event *events.Message) {
                                event.IsEdit = true
                        },
                },
                {
-                       name: "old history",
+                       name: "ignores old history",
                        change: func(event *events.Message) {
                                event.SourceWebMsg = &waWeb.WebMessageInfo{}
                        },
                },
                {
                        change: func(event *events.Message) {
                                event.SourceWebMsg = &waWeb.WebMessageInfo{}
                        },
                },
                {
-                       name: "a view-once message",
+                       name: "ignores a view-once message",
                        change: func(event *events.Message) {
                                event.IsViewOnce = true
                        },
                },
                {
                        change: func(event *events.Message) {
                                event.IsViewOnce = true
                        },
                },
                {
-                       name: "a disappearing message",
+                       name: "ignores a disappearing message",
                        change: func(event *events.Message) {
                                event.IsEphemeral = true
                        },
                },
                {
                        change: func(event *events.Message) {
                                event.IsEphemeral = true
                        },
                },
                {
-                       name: "the chat of the user with itself",
+                       name: "ignores the chat of the user with itself",
                        change: func(event *events.Message) {
                                event.Info.Chat = whatsappTestOwn
                        },
                },
                {
                        change: func(event *events.Message) {
                                event.Info.Chat = whatsappTestOwn
                        },
                },
                {
-                       name: "a status broadcast",
+                       name: "ignores a status broadcast",
                        change: func(event *events.Message) {
                                event.Info.Chat = types.StatusBroadcastJID
                        },
                },
                {
                        change: func(event *events.Message) {
                                event.Info.Chat = types.StatusBroadcastJID
                        },
                },
                {
-                       name: "a text of spaces",
+                       name: "ignores a text of spaces",
                        change: func(event *events.Message) {
                                event.Message.Conversation = new("  ")
                        },
                        change: func(event *events.Message) {
                                event.Message.Conversation = new("  ")
                        },
@@ -235,17 +260,20 @@ func TestWhatsAppCatchupGivesOneTurn(t *testing.T) {
 }
 
 func TestWhatsAppCatchupEndsAfterItsLimit(t *testing.T) {
 }
 
 func TestWhatsAppCatchupEndsAfterItsLimit(t *testing.T) {
-       whatsapp, fake := whatsappStartTestLinked(t)
-       whatsapp.inbox.catchupLimit = 100 * time.Millisecond
-       socket, memory := daemonStartTestWithWhatsApp(t, newModelFake(t), nil, whatsapp)
-       client := terminalStartTestClient(t, socket)
-       client.WaitFor(t, "[connected to OneChat]")
-       <-fake.connects
+       synctest.Test(t, func(t *testing.T) {
+               test := whatsappRetryTest(t)
+               test.whatsapp.client = test.fake
+               require.True(t, test.whatsapp.handle(&events.Connected{}))
+               require.True(t, test.whatsapp.handle(whatsappTestMessage(whatsappTestAna, whatsappTestOwn, "m1", "On my way.", time.Date(2026, 1, 1, 12, 0, 0, 0, time.UTC))))
+               require.NoError(t, test.whatsapp.inbox.deliver(t.Context(), test.loop, test.whatsapp.link(), false))
+               require.Zero(t, test.loop.memory.Len())
 
 
-       require.True(t, fake.Emit(&events.Connected{}))
-       require.True(t, fake.Emit(whatsappTestMessage(whatsappTestAna, whatsappTestOwn, "m1", "On my way.", time.Date(2026, 1, 1, 12, 0, 0, 0, time.UTC))))
-       client.WaitFor(t, "12:00 You: On my way.")
-       require.Len(t, whatsappTestLogTexts(t, memory), 1)
+               time.Sleep(whatsappCatchupTimeout)
+               synctest.Wait()
+               require.NoError(t, test.whatsapp.inbox.deliver(t.Context(), test.loop, test.whatsapp.link(), false))
+               require.Equal(t, 1, test.loop.memory.Len())
+               require.Contains(t, test.events.Last("work"), "12:00 You: On my way.")
+       })
 }
 
 func TestWhatsAppStateOfTheStateFileWaitForTheCatchup(t *testing.T) {
 }
 
 func TestWhatsAppStateOfTheStateFileWaitForTheCatchup(t *testing.T) {