package domain import ( "errors" "path/filepath" "testing" ) func TestLaunchSpecNormalizeCanonicalizesSafeFields(t *testing.T) { profile := filepath.Join(t.TempDir(), "profile") normalized, err := (LaunchSpec{ Kind: BrowserChrome, Executable: " chrome.exe ", UserDataDir: profile + string(filepath.Separator), ProfileDirectory: " Default ", TargetURL: " https://example.com/path ", ExtraArgs: []string{"--no-first-run"}, }).Normalize() if err != nil { t.Fatalf("Normalize() error = %v", err) } if normalized.Executable != "chrome.exe" || normalized.UserDataDir != filepath.Clean(profile) || normalized.ProfileDirectory != "Default" || normalized.TargetURL != "https://example.com/path" { t.Fatalf("normalized spec = %#v", normalized) } normalized.ExtraArgs[0] = "changed" if normalized.ExtraArgs[0] == "" { t.Fatal("extra args unexpectedly empty") } } func TestLaunchSpecNormalizeRejectsUnsafeValues(t *testing.T) { base := LaunchSpec{Kind: BrowserEdge, UserDataDir: filepath.Join(t.TempDir(), "profile"), TargetURL: "https://example.com"} cases := []LaunchSpec{ {UserDataDir: base.UserDataDir, TargetURL: base.TargetURL}, {Kind: base.Kind, UserDataDir: "relative", TargetURL: base.TargetURL}, {Kind: base.Kind, UserDataDir: base.UserDataDir, TargetURL: "file:///tmp/test"}, {Kind: base.Kind, UserDataDir: base.UserDataDir, TargetURL: "https://user@example.com"}, } for i, spec := range cases { if _, err := spec.Normalize(); !errors.Is(err, ErrInvalidLaunchSpec) { t.Errorf("case %d error = %v, want ErrInvalidLaunchSpec", i, err) } } } func TestLaunchSpecNormalizeAllowsAnEmptyTargetURL(t *testing.T) { profile := filepath.Join(t.TempDir(), "profile") normalized, err := (LaunchSpec{Kind: BrowserChrome, UserDataDir: profile}).Normalize() if err != nil { t.Fatal(err) } if normalized.TargetURL != "" { t.Fatalf("target URL = %q, want empty", normalized.TargetURL) } } func TestLaunchSpecNormalizeRejectsInvalidRemoteDebugPort(t *testing.T) { profile := filepath.Join(t.TempDir(), "profile") for _, port := range []int{1, MinRemoteDebugPort - 1, MaxRemoteDebugPort + 1} { _, err := (LaunchSpec{Kind: BrowserChrome, UserDataDir: profile, RemoteDebugPort: port}).Normalize() if !errors.Is(err, ErrInvalidLaunchSpec) { t.Errorf("port %d error = %v", port, err) } } } func TestNormalizeProxyServerCanonicalizesAndRejectsCredentials(t *testing.T) { got, err := NormalizeProxyServer(" HTTPS://Proxy.Local:8443 ") if err != nil || got != "https://proxy.local:8443" { t.Fatalf("NormalizeProxyServer() = %q, %v", got, err) } for _, value := range []string{ "http://user:secret@127.0.0.1:8080", "http://127.0.0.1:8080/path", "ftp://127.0.0.1:21", "socks5://127.0.0.1:70000", } { if _, err := NormalizeProxyServer(value); !errors.Is(err, ErrInvalidLaunchSpec) { t.Errorf("NormalizeProxyServer(%q) error = %v", value, err) } } }