package dyzurbot import ( "context" "os" "testing" "time" ) // TestLiveReminderFire performs ONE real reminder fire against a live Telegram // chat and the live Google Sheet, exercising the full scheduler send path: // Syncer.Sync -> Store.Snapshot -> reminderText -> mention -> BotSendFunc. // // It is a manual smoke test, skipped unless DYZUR_LIVE_FIRE=1, and needs the same // env the binary uses: BOT_TOKEN, GROUP_CHAT_ID, GOOGLE_CREDENTIALS_FILE, GOOGLE_SHEETS_ID // (and ROTA_CACHE_PATH for the cache file). // // WARNING — this MUTATES the sheet. fire() announces the current week and, when // that week is empty, auto-assigns two people and WRITES their names into the // rota. Point GROUP_CHAT_ID at a SANDBOX chat AND GOOGLE_SHEETS_ID at a COPY of // the sheet — otherwise this pings real members and edits the production rota. func TestLiveReminderFire(t *testing.T) { if os.Getenv("DYZUR_LIVE_FIRE") != "1" { t.Skip("set DYZUR_LIVE_FIRE=1 to run the live reminder smoke test") } ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() cfg, err := LoadConfig() if err != nil { t.Fatalf("LoadConfig: %v", err) } if cfg.Reminder == nil { t.Fatal("Reminder config is nil — set GROUP_CHAT_ID") } // Synchronous sync so the store is populated before we fire (Service.Start // would run the first sync in the background, racing the fire below). svc := NewService(cfg) if err := svc.Syncer.Sync(ctx); err != nil { t.Fatalf("sheet sync: %v", err) } token := os.Getenv("BOT_TOKEN") if token == "" { t.Fatal("missing BOT_TOKEN") } b, err := NewBot(token, svc) if err != nil { t.Fatalf("NewBot: %v", err) } rc := *cfg.Reminder assign := SheetAssigner(cfg.SpreadsheetID, cfg.SheetRange) NewReminder(svc.Store, BotSendFunc(b, rc.ChatID), assign, rc).fire(ctx) t.Logf("fired reminder to chat %d for the current week — verify it landed in the chat", rc.ChatID) }