92 lines
2.8 KiB
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)
|
|
}
|