X-Git-Url: https://git.giacomolli.uk/onechat/blobdiff_plain/a6a82d96b4906e9e1f09f45f69f48124f11ae1bb..b1be0ee8530df5db8973bfe355f2f6d3149383a0:/whatsapp_inbox_test.go diff --git a/whatsapp_inbox_test.go b/whatsapp_inbox_test.go index 7e9d3a3..1ce9a72 100644 --- a/whatsapp_inbox_test.go +++ b/whatsapp_inbox_test.go @@ -3,6 +3,7 @@ package main import ( "net/http" "testing" + "testing/synctest" "time" "github.com/stretchr/testify/require" @@ -17,7 +18,7 @@ func TestWhatsAppPrivateBatchStartsATurnWithAnEmptyReply(t *testing.T) { require.NoError(t, whatsapp.device.Contacts.PutContactName(t.Context(), whatsappTestAna, "Ana", "Ana Souza")) server := newModelFake(t) - server.reply = func(w http.ResponseWriter, call ModelFakeCall) { + server.reply = func(w http.ResponseWriter, _ ModelFakeCall) { modelWriteEvents(w, modelCompletedEvent([]any{modelMessageItem("")}, 100, 0, 5)) } @@ -31,6 +32,7 @@ func TestWhatsAppPrivateBatchStartsATurnWithAnEmptyReply(t *testing.T) { // The catch-up holds the batch open until its end, so the two messages // form one batch also on a slow machine. require.True(t, fake.Emit(&events.Connected{})) + at := time.Date(2026, 1, 1, 12, 0, 0, 0, time.UTC) require.True(t, fake.Emit(whatsappTestMessage(whatsappTestAna, whatsappTestAna, "m1", "Are you at home?", at))) require.True(t, fake.Emit(whatsappTestMessage(whatsappTestAna, whatsappTestOwn, "m2", "Yes", at))) @@ -56,7 +58,7 @@ func TestWhatsAppGroupTurns(t *testing.T) { }{ { name: "plain", - message: func(event *events.Message) { + message: func(_ *events.Message) { }, line: "12:00 Bruno Lima: Who brings the cake?", }, @@ -114,10 +116,14 @@ func TestWhatsAppGroupTurns(t *testing.T) { 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 += "\n" + whatsappBatchEmptyReply + client.WaitFor(t, "[done]") require.Equal(t, 1, server.Calls()) } else { @@ -131,7 +137,28 @@ func TestWhatsAppGroupTurns(t *testing.T) { } } -func TestWhatsAppTakesOnlyText(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 { name string @@ -173,16 +200,6 @@ func TestWhatsAppTakesOnlyText(t *testing.T) { event.Info.Chat = types.StatusBroadcastJID }, }, - { - name: "a photo with a caption", - change: func(event *events.Message) { - event.Message = &waE2E.Message{ - ImageMessage: &waE2E.ImageMessage{ - Caption: new("look"), - }, - } - }, - }, { name: "a text of spaces", change: func(event *events.Message) { @@ -212,6 +229,7 @@ func TestWhatsAppCatchupGivesOneTurn(t *testing.T) { <-fake.connects require.True(t, fake.Emit(&events.Connected{})) + at := time.Date(2026, 1, 1, 8, 0, 0, 0, time.UTC) for index, event := range []*events.Message{ whatsappTestMessage(whatsappTestAna, whatsappTestAna, "m1", "Good morning", at), @@ -235,28 +253,33 @@ func TestWhatsAppCatchupGivesOneTurn(t *testing.T) { time.Sleep(100 * time.Millisecond) require.Equal(t, 1, server.Calls()) + for _, text := range []string{"Good morning", "Call me", "Are you there?"} { require.Contains(t, string(server.Call(0).raw), text) } } 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) { dir := t.TempDir() whatsappTestSession(t, dir, true) + before, _, _ := whatsappStartTest(t, dir, newTestClock()) _, err := before.state.Add(whatsappTestChat, WhatsAppMessage{ ID: "m1",