package main
import (
- "os"
- "path/filepath"
"testing"
"time"
"github.com/stretchr/testify/require"
)
-func TestWhatsAppBatchesFollowTheTimesOfTheMessages(t *testing.T) {
- testCases := []struct {
- name string
- times []time.Duration
- sizes []int
- }{
- {
- name: "messages close together form one batch",
- times: []time.Duration{0, 10 * time.Second, 30 * time.Second},
- sizes: []int{3},
- },
- {
- name: "a quiet chat starts a new batch",
- times: []time.Duration{0, 10 * time.Second, 31 * time.Second},
- sizes: []int{2, 1},
- },
- {
- name: "a batch ends after two minutes",
- times: []time.Duration{0, 20 * time.Second, 40 * time.Second, 60 * time.Second, 80 * time.Second, 100 * time.Second, 120 * time.Second, 140 * time.Second},
- sizes: []int{7, 1},
- },
- }
-
- for _, tc := range testCases {
- t.Run(tc.name, func(t *testing.T) {
- batches := whatsappTestBatches(t, filepath.Join(t.TempDir(), whatsappStateFileName))
- start := time.Date(2026, 1, 1, 12, 0, 0, 0, time.UTC)
- for index, offset := range tc.times {
- _, err := batches.Add(whatsappTestChat, WhatsAppMessage{
- ID: string(rune('a' + index)),
- Time: start.Add(offset),
- Text: "hi",
- }, time.Now())
- require.NoError(t, err)
- }
-
- require.NoError(t, batches.CloseAll())
- var sizes []int
- for _, batch := range batches.Closed() {
- sizes = append(sizes, len(batch.Messages))
- }
-
- require.Equal(t, tc.sizes, sizes)
- })
- }
-}
-
-func TestWhatsAppBatchClosesAtFiftyMessages(t *testing.T) {
- batches := whatsappTestBatches(t, filepath.Join(t.TempDir(), whatsappStateFileName))
- start := time.Date(2026, 1, 1, 12, 0, 0, 0, time.UTC)
- for index := range whatsappBatchMessages {
- closed, err := batches.Add(whatsappTestChat, WhatsAppMessage{
- ID: time.Duration(index).String(),
- Time: start,
- Text: "hi",
- }, time.Now())
- require.NoError(t, err)
- require.Equal(t, index == whatsappBatchMessages-1, closed)
- }
-
- require.Len(t, batches.Closed(), 1)
-}
-
-func TestWhatsAppBatchClosesInRealTime(t *testing.T) {
- batches := whatsappTestBatches(t, filepath.Join(t.TempDir(), whatsappStateFileName))
- arrival := time.Date(2026, 1, 1, 12, 0, 0, 0, time.UTC)
- for index, offset := range []time.Duration{0, 15 * time.Second, 30 * time.Second} {
- _, err := batches.Add(whatsappTestChat, WhatsAppMessage{
- ID: string(rune('a' + index)),
- Time: arrival,
- Text: "hi",
- }, arrival.Add(offset))
- require.NoError(t, err)
- }
-
- wait, open := batches.Wait(arrival.Add(40 * time.Second))
- require.True(t, open)
- require.Equal(t, 10*time.Second, wait)
-
- closed, err := batches.CloseDue(arrival.Add(49 * time.Second))
- require.NoError(t, err)
- require.False(t, closed)
-
- closed, err = batches.CloseDue(arrival.Add(50 * time.Second))
- require.NoError(t, err)
- require.True(t, closed)
-
- _, open = batches.Wait(arrival.Add(50 * time.Second))
- require.False(t, open)
-}
-
-func TestWhatsAppBatchesSurviveARestart(t *testing.T) {
- path := filepath.Join(t.TempDir(), whatsappDirName, whatsappStateFileName)
- batches := whatsappTestBatches(t, path)
- for _, id := range []string{"a", "a", "b"} {
- _, err := batches.Add(whatsappTestChat, WhatsAppMessage{
- ID: id,
- Time: time.Date(2026, 1, 1, 12, 0, 0, 0, time.UTC),
- Text: "hi " + id,
- }, time.Now())
- require.NoError(t, err)
- }
-
- info, err := os.Stat(path)
- require.NoError(t, err)
- require.Equal(t, os.FileMode(0o600), info.Mode().Perm())
-
- again := whatsappTestBatches(t, path)
- require.NoError(t, again.CloseAll())
- closed := again.Closed()
- require.Len(t, closed, 1)
- require.Equal(t, []string{"hi a", "hi b"}, []string{closed[0].Messages[0].Text, closed[0].Messages[1].Text})
-
- require.NoError(t, again.Remove(closed[0].Number))
- require.Empty(t, whatsappTestBatches(t, path).Closed())
-}
-
-func TestWhatsAppBatchesRefuseABrokenStateFile(t *testing.T) {
- path := filepath.Join(t.TempDir(), whatsappStateFileName)
- require.NoError(t, os.WriteFile(path, []byte("{"), 0o600))
-
- _, err := openWhatsAppBatches(path, whatsappBatchQuiet, whatsappBatchWindow)
- require.ErrorContains(t, err, path)
-}
-
func TestWhatsAppBatchText(t *testing.T) {
at := time.Date(2026, 1, 1, 12, 0, 0, 0, time.UTC)
testCases := []struct {
})
}
}
-
-// whatsappTestBatches opens the batches of the state file at path with the
-// times of the plan.
-func whatsappTestBatches(t *testing.T, path string) *WhatsAppBatches {
- t.Helper()
-
- batches, err := openWhatsAppBatches(path, whatsappBatchQuiet, whatsappBatchWindow)
- require.NoError(t, err)
-
- return batches
-}