243 lines
6.0 KiB
Go
243 lines
6.0 KiB
Go
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])
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|