dyzur-bot/live_auth_check_test.go

92 lines
2.8 KiB
Go

package dyzurbot
import (
"context"
"os"
"strconv"
"testing"
"time"
"github.com/joho/godotenv"
"google.golang.org/api/sheets/v4"
)
// These are manual smoke tests that hit the real Google Sheet using the
// credential in .env (GOOGLE_CREDENTIALS_FILE, GOOGLE_SHEETS_ID). They are
// skipped unless their gate env var is set, so the normal `go test ./...` run
// stays offline and side-effect-free.
// TestLiveAuthRead proves the service-account credential loads and the sheet is
// reachable. Read-only. Gate: DYZUR_LIVE_AUTH=1.
func TestLiveAuthRead(t *testing.T) {
if os.Getenv("DYZUR_LIVE_AUTH") != "1" {
t.Skip("set DYZUR_LIVE_AUTH=1 to run")
}
_ = godotenv.Load()
id := os.Getenv("GOOGLE_SHEETS_ID")
rows, err := ReadSheet(context.Background(), id, resolveRange("", time.Now()))
if err != nil {
t.Fatalf("ReadSheet: %v", err)
}
t.Logf("OK: fetched %d rows", len(rows))
}
// TestLiveWriteRoundTrip proves the spreadsheets (read+write) scope actually
// grants writes: it creates a throwaway tab, writes a marker via WriteSheet,
// reads it back, and deletes the tab — so no real rota data is touched. Gate:
// DYZUR_LIVE_WRITE=1.
func TestLiveWriteRoundTrip(t *testing.T) {
if os.Getenv("DYZUR_LIVE_WRITE") != "1" {
t.Skip("set DYZUR_LIVE_WRITE=1 to run")
}
_ = godotenv.Load()
ctx := context.Background()
id := os.Getenv("GOOGLE_SHEETS_ID")
srv, err := newSheetsService(ctx)
if err != nil {
t.Fatalf("newSheetsService: %v", err)
}
// Create an isolated throwaway tab; the timestamp keeps the title unique.
title := "scratch-" + strconv.FormatInt(time.Now().UnixNano(), 10)
addResp, err := srv.Spreadsheets.BatchUpdate(id, &sheets.BatchUpdateSpreadsheetRequest{
Requests: []*sheets.Request{{
AddSheet: &sheets.AddSheetRequest{
Properties: &sheets.SheetProperties{Title: title},
},
}},
}).Context(ctx).Do()
if err != nil {
t.Fatalf("create scratch tab: %v", err)
}
sheetID := addResp.Replies[0].AddSheet.Properties.SheetId
// Always remove the throwaway tab, even if the assertions below fail.
defer func() {
_, derr := srv.Spreadsheets.BatchUpdate(id, &sheets.BatchUpdateSpreadsheetRequest{
Requests: []*sheets.Request{{
DeleteSheet: &sheets.DeleteSheetRequest{SheetId: sheetID},
}},
}).Context(ctx).Do()
if derr != nil {
t.Errorf("cleanup: delete scratch tab %q: %v", title, derr)
}
}()
const want = "dyzur-write-probe"
writeRange := title + "!A1"
if err := WriteSheet(ctx, id, writeRange, [][]interface{}{{want}}); err != nil {
t.Fatalf("WriteSheet: %v", err)
}
rows, err := ReadSheet(ctx, id, writeRange)
if err != nil {
t.Fatalf("ReadSheet back: %v", err)
}
if len(rows) == 0 || len(rows[0]) == 0 || rows[0][0] != want {
t.Fatalf("round-trip mismatch: got %v, want %q", rows, want)
}
t.Logf("OK: wrote and read back %q from throwaway tab %q", want, title)
}