diff --git a/internal/cmd/calendar_create_update_test.go b/internal/cmd/calendar_create_update_test.go index 455a0edf5..c9f467211 100644 --- a/internal/cmd/calendar_create_update_test.go +++ b/internal/cmd/calendar_create_update_test.go @@ -634,3 +634,103 @@ func TestCalendarUpdateCmd_ScopeFuture(t *testing.T) { t.Fatalf("expected recurrence truncation") } } + +func TestCalendarUpdateCmd_SendUpdates(t *testing.T) { + origNew := newCalendarService + t.Cleanup(func() { newCalendarService = origNew }) + + var gotSendUpdates string + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + path := strings.TrimPrefix(r.URL.Path, "/calendar/v3") + if r.Method == http.MethodPatch && path == "/calendars/cal/events/ev" { + gotSendUpdates = r.URL.Query().Get("sendUpdates") + w.Header().Set("Content-Type", "application/json") + _ = json.NewEncoder(w).Encode(map[string]any{ + "id": "ev", + "summary": "Updated", + }) + return + } + http.NotFound(w, r) + })) + defer srv.Close() + + svc, err := calendar.NewService(context.Background(), + option.WithoutAuthentication(), + option.WithHTTPClient(srv.Client()), + option.WithEndpoint(srv.URL+"/"), + ) + if err != nil { + t.Fatalf("NewService: %v", err) + } + newCalendarService = func(context.Context, string) (*calendar.Service, error) { return svc, nil } + + u, err := ui.New(ui.Options{Stdout: os.Stdout, Stderr: os.Stderr, Color: "never"}) + if err != nil { + t.Fatalf("ui.New: %v", err) + } + ctx := outfmt.WithMode(ui.WithUI(context.Background(), u), outfmt.Mode{JSON: true}) + + cmd := &CalendarUpdateCmd{} + if err := runKong(t, cmd, []string{ + "cal", + "ev", + "--summary", "Updated", + "--send-updates", "all", + }, ctx, &RootFlags{Account: "a@b.com"}); err != nil { + t.Fatalf("runKong: %v", err) + } + if gotSendUpdates != "all" { + t.Fatalf("expected sendUpdates=all, got %q", gotSendUpdates) + } +} + +func TestCalendarUpdateCmd_SendUpdatesExternalOnly(t *testing.T) { + origNew := newCalendarService + t.Cleanup(func() { newCalendarService = origNew }) + + var gotSendUpdates string + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + path := strings.TrimPrefix(r.URL.Path, "/calendar/v3") + if r.Method == http.MethodPatch && path == "/calendars/cal/events/ev" { + gotSendUpdates = r.URL.Query().Get("sendUpdates") + w.Header().Set("Content-Type", "application/json") + _ = json.NewEncoder(w).Encode(map[string]any{ + "id": "ev", + "summary": "Updated", + }) + return + } + http.NotFound(w, r) + })) + defer srv.Close() + + svc, err := calendar.NewService(context.Background(), + option.WithoutAuthentication(), + option.WithHTTPClient(srv.Client()), + option.WithEndpoint(srv.URL+"/"), + ) + if err != nil { + t.Fatalf("NewService: %v", err) + } + newCalendarService = func(context.Context, string) (*calendar.Service, error) { return svc, nil } + + u, err := ui.New(ui.Options{Stdout: os.Stdout, Stderr: os.Stderr, Color: "never"}) + if err != nil { + t.Fatalf("ui.New: %v", err) + } + ctx := outfmt.WithMode(ui.WithUI(context.Background(), u), outfmt.Mode{JSON: true}) + + cmd := &CalendarUpdateCmd{} + if err := runKong(t, cmd, []string{ + "cal", + "ev", + "--summary", "Updated", + "--send-updates", "externalOnly", + }, ctx, &RootFlags{Account: "a@b.com"}); err != nil { + t.Fatalf("runKong: %v", err) + } + if gotSendUpdates != "externalOnly" { + t.Fatalf("expected sendUpdates=externalOnly, got %q", gotSendUpdates) + } +} diff --git a/internal/cmd/calendar_edit.go b/internal/cmd/calendar_edit.go index b51991335..5c84aa720 100644 --- a/internal/cmd/calendar_edit.go +++ b/internal/cmd/calendar_edit.go @@ -325,6 +325,7 @@ type CalendarUpdateCmd struct { ColorId string `name:"event-color" help:"Event color ID (1-11, or empty to clear)"` Visibility string `name:"visibility" help:"Event visibility: default, public, private, confidential"` Transparency string `name:"transparency" help:"Show as busy (opaque) or free (transparent). Aliases: busy, free"` + SendUpdates string `name:"send-updates" help:"Notification mode: all, externalOnly, none (default: all)"` GuestsCanInviteOthers *bool `name:"guests-can-invite" help:"Allow guests to invite others"` GuestsCanModify *bool `name:"guests-can-modify" help:"Allow guests to modify event"` GuestsCanSeeOthers *bool `name:"guests-can-see-others" help:"Allow guests to see other guests"`