package oauth import ( "fmt" "strings" "testing" ) // mockCommandExecutor is a test mock that records executed commands without actually running them. type mockCommandExecutor struct { executedCmd string executedArgs []string returnError error } func (m *mockCommandExecutor) Execute(name string, args ...string) error { m.executedCmd = name m.executedArgs = args return m.returnError } func TestBuildBrowserCommand(t *testing.T) { tests := []struct { name string goos string url string wantCmd string wantArgs []string wantErr bool errContains string }{ { name: "macOS with simple URL", goos: "darwin", url: "https://example.com", wantCmd: "open", wantArgs: []string{"https://example.com"}, wantErr: false, }, { name: "Linux with simple URL", goos: "linux", url: "https://example.com", wantCmd: "xdg-open", wantArgs: []string{"https://example.com"}, wantErr: false, }, { name: "Windows with simple URL", goos: "windows", url: "https://example.com", wantCmd: "rundll32", wantArgs: []string{"url.dll,FileProtocolHandler", "https://example.com"}, wantErr: false, }, { name: "macOS with URL containing query params", goos: "darwin", url: "https://example.com/callback?code=123&state=abc", wantCmd: "open", wantArgs: []string{"https://example.com/callback?code=123&state=abc"}, wantErr: false, }, { name: "Linux with URL containing fragment", goos: "linux", url: "https://example.com/page#section", wantCmd: "xdg-open", wantArgs: []string{"https://example.com/page#section"}, wantErr: false, }, { name: "Windows with URL containing special chars", goos: "windows", url: "https://example.com/path?key=value&other=123", wantCmd: "rundll32", wantArgs: []string{"url.dll,FileProtocolHandler", "https://example.com/path?key=value&other=123"}, wantErr: false, }, { name: "unsupported OS", goos: "freebsd", url: "https://example.com", wantCmd: "", wantArgs: nil, wantErr: true, errContains: "unsupported platform", }, { name: "unknown OS", goos: "amiga", url: "https://example.com", wantCmd: "", wantArgs: nil, wantErr: true, errContains: "amiga", }, { name: "empty URL on macOS", goos: "darwin", url: "", wantCmd: "open", wantArgs: []string{""}, wantErr: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { cmd, args, err := buildBrowserCommand(tt.goos, tt.url) // Check error if tt.wantErr { if err == nil { t.Errorf("buildBrowserCommand() expected error, got nil") return } if tt.errContains != "" && !strings.Contains(err.Error(), tt.errContains) { t.Errorf("buildBrowserCommand() error = %v, should contain %q", err, tt.errContains) } return } if err != nil { t.Errorf("buildBrowserCommand() unexpected error = %v", err) return } // Check command if cmd != tt.wantCmd { t.Errorf("buildBrowserCommand() cmd = %v, want %v", cmd, tt.wantCmd) } // Check args if len(args) != len(tt.wantArgs) { t.Errorf("buildBrowserCommand() args length = %d, want %d", len(args), len(tt.wantArgs)) return } for i, arg := range args { if arg != tt.wantArgs[i] { t.Errorf("buildBrowserCommand() args[%d] = %v, want %v", i, arg, tt.wantArgs[i]) } } }) } } func TestOpenBrowserWithExecutor(t *testing.T) { tests := []struct { name string goos string url string executorError error wantCmd string wantArgs []string wantErr bool errContains string }{ { name: "macOS success", goos: "darwin", url: "https://example.com", wantCmd: "open", wantArgs: []string{"https://example.com"}, wantErr: false, }, { name: "Linux success", goos: "linux", url: "https://example.com/auth", wantCmd: "xdg-open", wantArgs: []string{"https://example.com/auth"}, wantErr: false, }, { name: "Windows success", goos: "windows", url: "https://example.com/callback?code=123", wantCmd: "rundll32", wantArgs: []string{"url.dll,FileProtocolHandler", "https://example.com/callback?code=123"}, wantErr: false, }, { name: "unsupported OS", goos: "plan9", url: "https://example.com", wantErr: true, errContains: "unsupported platform", }, { name: "executor error", goos: "darwin", url: "https://example.com", executorError: fmt.Errorf("exec failed"), wantCmd: "open", wantArgs: []string{"https://example.com"}, wantErr: true, errContains: "exec failed", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { mock := &mockCommandExecutor{returnError: tt.executorError} err := openBrowserWithExecutor(tt.goos, tt.url, mock) // Check error if tt.wantErr { if err == nil { t.Errorf("openBrowserWithExecutor() expected error, got nil") return } if tt.errContains != "" && !strings.Contains(err.Error(), tt.errContains) { t.Errorf("openBrowserWithExecutor() error = %v, should contain %q", err, tt.errContains) } return } if err != nil { t.Errorf("openBrowserWithExecutor() unexpected error = %v", err) return } // Verify mock was called with correct command if mock.executedCmd != tt.wantCmd { t.Errorf("executed command = %v, want %v", mock.executedCmd, tt.wantCmd) } // Verify mock was called with correct args if len(mock.executedArgs) != len(tt.wantArgs) { t.Errorf("executed args length = %d, want %d", len(mock.executedArgs), len(tt.wantArgs)) return } for i, arg := range mock.executedArgs { if arg != tt.wantArgs[i] { t.Errorf("executed args[%d] = %v, want %v", i, arg, tt.wantArgs[i]) } } }) } }