Skip to content

Commit f27117b

Browse files
committed
test: raise coverage for drive and googleapi
1 parent f5a5cef commit f27117b

File tree

4 files changed

+304
-15
lines changed

4 files changed

+304
-15
lines changed

internal/cmd/drive.go

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020
gapi "google.golang.org/api/googleapi"
2121
)
2222

23+
var newDriveService = googleapi.NewDrive
24+
2325
func newDriveCmd(flags *rootFlags) *cobra.Command {
2426
cmd := &cobra.Command{
2527
Use: "drive",
@@ -64,7 +66,7 @@ func newDriveLsCmd(flags *rootFlags) *cobra.Command {
6466
folderID = args[0]
6567
}
6668

67-
svc, err := googleapi.NewDrive(cmd.Context(), account)
69+
svc, err := newDriveService(cmd.Context(), account)
6870
if err != nil {
6971
return err
7072
}
@@ -140,7 +142,7 @@ func newDriveSearchCmd(flags *rootFlags) *cobra.Command {
140142
}
141143
text := strings.Join(args, " ")
142144

143-
svc, err := googleapi.NewDrive(cmd.Context(), account)
145+
svc, err := newDriveService(cmd.Context(), account)
144146
if err != nil {
145147
return err
146148
}
@@ -210,7 +212,7 @@ func newDriveGetCmd(flags *rootFlags) *cobra.Command {
210212
}
211213
fileID := args[0]
212214

213-
svc, err := googleapi.NewDrive(cmd.Context(), account)
215+
svc, err := newDriveService(cmd.Context(), account)
214216
if err != nil {
215217
return err
216218
}
@@ -263,7 +265,7 @@ func newDriveDownloadCmd(flags *rootFlags) *cobra.Command {
263265
destPath = args[1]
264266
}
265267

266-
svc, err := googleapi.NewDrive(cmd.Context(), account)
268+
svc, err := newDriveService(cmd.Context(), account)
267269
if err != nil {
268270
return err
269271
}
@@ -333,7 +335,7 @@ func newDriveUploadCmd(flags *rootFlags) *cobra.Command {
333335
fileName = filepath.Base(localPath)
334336
}
335337

336-
svc, err := googleapi.NewDrive(cmd.Context(), account)
338+
svc, err := newDriveService(cmd.Context(), account)
337339
if err != nil {
338340
return err
339341
}
@@ -387,7 +389,7 @@ func newDriveMkdirCmd(flags *rootFlags) *cobra.Command {
387389

388390
name := args[0]
389391

390-
svc, err := googleapi.NewDrive(cmd.Context(), account)
392+
svc, err := newDriveService(cmd.Context(), account)
391393
if err != nil {
392394
return err
393395
}
@@ -438,7 +440,7 @@ func newDriveDeleteCmd(flags *rootFlags) *cobra.Command {
438440
}
439441
fileID := args[0]
440442

441-
svc, err := googleapi.NewDrive(cmd.Context(), account)
443+
svc, err := newDriveService(cmd.Context(), account)
442444
if err != nil {
443445
return err
444446
}
@@ -473,7 +475,7 @@ func newDriveMoveCmd(flags *rootFlags) *cobra.Command {
473475
fileID := args[0]
474476
newParentID := args[1]
475477

476-
svc, err := googleapi.NewDrive(cmd.Context(), account)
478+
svc, err := newDriveService(cmd.Context(), account)
477479
if err != nil {
478480
return err
479481
}
@@ -524,7 +526,7 @@ func newDriveRenameCmd(flags *rootFlags) *cobra.Command {
524526
fileID := args[0]
525527
newName := args[1]
526528

527-
svc, err := googleapi.NewDrive(cmd.Context(), account)
529+
svc, err := newDriveService(cmd.Context(), account)
528530
if err != nil {
529531
return err
530532
}
@@ -576,7 +578,7 @@ func newDriveShareCmd(flags *rootFlags) *cobra.Command {
576578
return errors.New("invalid --role (expected reader|writer)")
577579
}
578580

579-
svc, err := googleapi.NewDrive(cmd.Context(), account)
581+
svc, err := newDriveService(cmd.Context(), account)
580582
if err != nil {
581583
return err
582584
}
@@ -639,7 +641,7 @@ func newDriveUnshareCmd(flags *rootFlags) *cobra.Command {
639641
fileID := args[0]
640642
permissionID := args[1]
641643

642-
svc, err := googleapi.NewDrive(cmd.Context(), account)
644+
svc, err := newDriveService(cmd.Context(), account)
643645
if err != nil {
644646
return err
645647
}
@@ -677,7 +679,7 @@ func newDrivePermissionsCmd(flags *rootFlags) *cobra.Command {
677679
}
678680
fileID := args[0]
679681

680-
svc, err := googleapi.NewDrive(cmd.Context(), account)
682+
svc, err := newDriveService(cmd.Context(), account)
681683
if err != nil {
682684
return err
683685
}
@@ -724,7 +726,7 @@ func newDriveURLCmd(flags *rootFlags) *cobra.Command {
724726
return err
725727
}
726728

727-
svc, err := googleapi.NewDrive(cmd.Context(), account)
729+
svc, err := newDriveService(cmd.Context(), account)
728730
if err != nil {
729731
return err
730732
}

internal/cmd/drive_url_cmd_test.go

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
package cmd
2+
3+
import (
4+
"bytes"
5+
"context"
6+
"encoding/json"
7+
"io"
8+
"net/http"
9+
"net/http/httptest"
10+
"os"
11+
"strings"
12+
"testing"
13+
14+
"github.com/steipete/gogcli/internal/outfmt"
15+
"github.com/steipete/gogcli/internal/ui"
16+
"google.golang.org/api/drive/v3"
17+
"google.golang.org/api/option"
18+
)
19+
20+
func captureStdout(t *testing.T, fn func()) string {
21+
t.Helper()
22+
23+
orig := os.Stdout
24+
r, w, err := os.Pipe()
25+
if err != nil {
26+
t.Fatalf("pipe: %v", err)
27+
}
28+
os.Stdout = w
29+
30+
fn()
31+
32+
_ = w.Close()
33+
os.Stdout = orig
34+
b, _ := io.ReadAll(r)
35+
_ = r.Close()
36+
return string(b)
37+
}
38+
39+
func TestDriveURLCmd_TextAndJSON(t *testing.T) {
40+
origNew := newDriveService
41+
t.Cleanup(func() { newDriveService = origNew })
42+
43+
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
44+
var id string
45+
switch {
46+
case strings.HasPrefix(r.URL.Path, "/drive/v3/files/"):
47+
id = strings.TrimPrefix(r.URL.Path, "/drive/v3/files/")
48+
case strings.HasPrefix(r.URL.Path, "/files/"):
49+
id = strings.TrimPrefix(r.URL.Path, "/files/")
50+
default:
51+
http.NotFound(w, r)
52+
return
53+
}
54+
var web string
55+
switch id {
56+
case "id1":
57+
web = "https://example.com/id1"
58+
case "id2":
59+
web = "" // force fallback URL
60+
default:
61+
http.NotFound(w, r)
62+
return
63+
}
64+
w.Header().Set("Content-Type", "application/json")
65+
_ = json.NewEncoder(w).Encode(map[string]any{
66+
"id": id,
67+
"webViewLink": web,
68+
})
69+
}))
70+
defer srv.Close()
71+
72+
svc, err := drive.NewService(context.Background(),
73+
option.WithoutAuthentication(),
74+
option.WithHTTPClient(srv.Client()),
75+
option.WithEndpoint(srv.URL+"/"),
76+
)
77+
if err != nil {
78+
t.Fatalf("NewService: %v", err)
79+
}
80+
81+
newDriveService = func(context.Context, string) (*drive.Service, error) {
82+
return svc, nil
83+
}
84+
85+
flags := &rootFlags{Account: "a@b.com"}
86+
87+
// Text mode writes via UI.Out().
88+
var outBuf bytes.Buffer
89+
u, err := ui.New(ui.Options{Stdout: &outBuf, Stderr: io.Discard, Color: "never"})
90+
if err != nil {
91+
t.Fatalf("ui.New: %v", err)
92+
}
93+
ctx := ui.WithUI(context.Background(), u)
94+
ctx = outfmt.WithMode(ctx, outfmt.ModeText)
95+
96+
cmd := newDriveURLCmd(flags)
97+
cmd.SetContext(ctx)
98+
cmd.SetArgs([]string{"id1", "id2"})
99+
if err := cmd.Execute(); err != nil {
100+
t.Fatalf("execute: %v", err)
101+
}
102+
gotText := outBuf.String()
103+
if !strings.Contains(gotText, "id1\thttps://example.com/id1") {
104+
t.Fatalf("missing id1 line: %q", gotText)
105+
}
106+
if !strings.Contains(gotText, "id2\thttps://drive.google.com/file/d/id2/view") {
107+
t.Fatalf("missing id2 fallback line: %q", gotText)
108+
}
109+
110+
// JSON mode writes to os.Stdout via outfmt.WriteJSON.
111+
jsonOut := captureStdout(t, func() {
112+
u2, uiErr := ui.New(ui.Options{Stdout: io.Discard, Stderr: io.Discard, Color: "never"})
113+
if uiErr != nil {
114+
t.Fatalf("ui.New: %v", uiErr)
115+
}
116+
ctx2 := ui.WithUI(context.Background(), u2)
117+
ctx2 = outfmt.WithMode(ctx2, outfmt.ModeJSON)
118+
119+
cmd2 := newDriveURLCmd(flags)
120+
cmd2.SetContext(ctx2)
121+
cmd2.SetArgs([]string{"id1", "id2"})
122+
if err := cmd2.Execute(); err != nil {
123+
t.Fatalf("execute: %v", err)
124+
}
125+
})
126+
127+
var parsed struct {
128+
URLs []struct {
129+
ID string `json:"id"`
130+
URL string `json:"url"`
131+
} `json:"urls"`
132+
}
133+
if err := json.Unmarshal([]byte(jsonOut), &parsed); err != nil {
134+
t.Fatalf("json parse: %v\nout=%q", err, jsonOut)
135+
}
136+
if len(parsed.URLs) != 2 {
137+
t.Fatalf("unexpected urls: %#v", parsed.URLs)
138+
}
139+
if parsed.URLs[0].ID != "id1" || parsed.URLs[0].URL != "https://example.com/id1" {
140+
t.Fatalf("unexpected id1: %#v", parsed.URLs[0])
141+
}
142+
if parsed.URLs[1].ID != "id2" || parsed.URLs[1].URL != "https://drive.google.com/file/d/id2/view" {
143+
t.Fatalf("unexpected id2: %#v", parsed.URLs[1])
144+
}
145+
}

internal/googleapi/client.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,13 @@ import (
1717

1818
const defaultHTTPTimeout = 30 * time.Second
1919

20+
var (
21+
readClientCredentials = config.ReadClientCredentials
22+
openSecretsStore = secrets.OpenDefault
23+
)
24+
2025
func tokenSourceForAccount(ctx context.Context, service googleauth.Service, email string) (oauth2.TokenSource, error) {
21-
creds, err := config.ReadClientCredentials()
26+
creds, err := readClientCredentials()
2227
if err != nil {
2328
return nil, err
2429
}
@@ -32,7 +37,7 @@ func tokenSourceForAccount(ctx context.Context, service googleauth.Service, emai
3237
}
3338

3439
func tokenSourceForAccountScopes(ctx context.Context, serviceLabel string, email string, clientID string, clientSecret string, requiredScopes []string) (oauth2.TokenSource, error) {
35-
store, err := secrets.OpenDefault()
40+
store, err := openSecretsStore()
3641
if err != nil {
3742
return nil, err
3843
}

0 commit comments

Comments
 (0)