Skip to content

Commit a0c03f9

Browse files
committed
✅ Add tests for common
1 parent befcf78 commit a0c03f9

File tree

6 files changed

+524
-0
lines changed

6 files changed

+524
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ dist/
4949
/.aswb/
5050
/.clwb/
5151

52+
/docs/superpowers
5253
# except for the following files
5354
!winres/*
5455
!server.json

pkg/auth/auth_test.go

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@ import (
1212
"os"
1313
"strings"
1414
"testing"
15+
"testing/iotest"
1516
"time"
1617

1718
"github.com/eat-pray-ai/yutu/pkg"
1819
"golang.org/x/oauth2"
20+
"google.golang.org/api/youtube/v3"
1921
)
2022

2123
// helper to build a minimal valid Google OAuth2 credential JSON.
@@ -227,3 +229,120 @@ func TestSaveToken_InvalidPath(t *testing.T) {
227229
t.Fatalf("expected error from saveToken with invalid path, got nil")
228230
}
229231
}
232+
233+
func TestStartWebServer_Success(t *testing.T) {
234+
ln, err := net.Listen("tcp", "127.0.0.1:0")
235+
if err != nil {
236+
t.Fatalf("failed to listen: %v", err)
237+
}
238+
addr := ln.Addr().String()
239+
_ = ln.Close()
240+
241+
redirectURL := fmt.Sprintf("http://%s", addr)
242+
s := NewY2BService().(*svc)
243+
s.state = "test-state"
244+
245+
codeCh, err := s.startWebServer(redirectURL)
246+
if err != nil {
247+
t.Fatalf("startWebServer error: %v", err)
248+
}
249+
250+
// Send the HTTP request in a goroutine to avoid deadlock:
251+
// the handler blocks on codeCh <- code until someone reads from codeCh.
252+
go func() {
253+
resp, err := http.Get(redirectURL + "/?state=test-state&code=auth-code-123")
254+
if err == nil {
255+
_ = resp.Body.Close()
256+
}
257+
}()
258+
259+
select {
260+
case code := <-codeCh:
261+
if code != "auth-code-123" {
262+
t.Errorf("expected code=auth-code-123, got %s", code)
263+
}
264+
case <-time.After(2 * time.Second):
265+
t.Fatal("timed out waiting for code")
266+
}
267+
}
268+
269+
func TestSaveToken_Success(t *testing.T) {
270+
tmpDir := t.TempDir()
271+
272+
origRootDir := *pkg.RootDir
273+
origRoot := pkg.Root
274+
defer func() {
275+
pkg.RootDir = &origRootDir
276+
pkg.Root = origRoot
277+
}()
278+
279+
pkg.RootDir = &tmpDir
280+
root, err := os.OpenRoot(tmpDir)
281+
if err != nil {
282+
t.Fatalf("failed to open root: %v", err)
283+
}
284+
pkg.Root = root
285+
286+
s := NewY2BService().(*svc)
287+
s.tokenFile = "token.json"
288+
289+
tok := &oauth2.Token{AccessToken: "test-token"}
290+
err = s.saveToken(tok)
291+
if err != nil {
292+
t.Fatalf("saveToken returned error: %v", err)
293+
}
294+
295+
data, err := os.ReadFile(tmpDir + "/token.json")
296+
if err != nil {
297+
t.Fatalf("failed to read saved token file: %v", err)
298+
}
299+
300+
var savedToken oauth2.Token
301+
if err := json.Unmarshal(data, &savedToken); err != nil {
302+
t.Fatalf("failed to unmarshal saved token: %v", err)
303+
}
304+
if savedToken.AccessToken != "test-token" {
305+
t.Errorf("expected AccessToken=test-token, got %s", savedToken.AccessToken)
306+
}
307+
}
308+
309+
func TestGetConfig_Scopes(t *testing.T) {
310+
s := NewY2BService(
311+
WithCredential(validCredentialJSON("http://localhost:8216"), os.DirFS(".")),
312+
).(*svc)
313+
314+
config, err := s.getConfig()
315+
if err != nil {
316+
t.Fatalf("getConfig returned error: %v", err)
317+
}
318+
319+
if len(config.Scopes) != 3 {
320+
t.Fatalf("expected 3 scopes, got %d", len(config.Scopes))
321+
}
322+
323+
expectedScopes := []string{
324+
youtube.YoutubeScope,
325+
youtube.YoutubeForceSslScope,
326+
youtube.YoutubeChannelMembershipsCreatorScope,
327+
}
328+
for i, expected := range expectedScopes {
329+
if config.Scopes[i] != expected {
330+
t.Errorf("scope[%d] = %q, want %q", i, config.Scopes[i], expected)
331+
}
332+
}
333+
}
334+
335+
func TestGetCodeFromPrompt_ReadError(t *testing.T) {
336+
errReader := iotest.ErrReader(fmt.Errorf("read error"))
337+
var out bytes.Buffer
338+
339+
s := NewY2BService(WithIO(errReader, &out)).(*svc)
340+
341+
_, err := s.getCodeFromPrompt("http://example.com/auth", "http://localhost:8216")
342+
if err == nil {
343+
t.Fatalf("expected error from getCodeFromPrompt, got nil")
344+
}
345+
if !strings.Contains(err.Error(), "failed to read prompt") {
346+
t.Errorf("expected error to contain %q, got %q", "failed to read prompt", err.Error())
347+
}
348+
}

0 commit comments

Comments
 (0)