Repository: All-Hands-AI/OpenHands
File: frontend/__tests__/utils/websocket-url.test.ts (TypeScript)

Code before:
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
import {
  extractBaseHost,
  extractPathPrefix,
  buildHttpBaseUrl,
  buildWebSocketUrl,
} from "@/utils/websocket-url";

describe("websocket-url utilities", () => {
  // Mock window.location for tests
  const originalLocation = window.location;

  beforeEach(() => {
    // @ts-ignore - we're mocking window.location
    delete window.location;
    window.location = {
      ...originalLocation,
      host: "localhost:3001",
      protocol: "https:",
    } as Location;
  });

  afterEach(() => {
    window.location = originalLocation;
  });

  describe("extractBaseHost", () => {
    it("should extract host from a standard URL", () => {
      const result = extractBaseHost(
        "https://example.com/api/conversations/123",
      );
      expect(result).toBe("example.com");
    });

    it("should extract host with port from URL", () => {
      const result = extractBaseHost(
        "http://localhost:3000/api/conversations/123",
      );
      expect(result).toBe("localhost:3000");
    });

    it("should extract host from proxy deployment URL", () => {
      const result = extractBaseHost(
        "https://openhands.example.com/runtime/55313/api/conversations/abc123",
      );
      expect(result).toBe("openhands.example.com");
    });

    it("should return window.location.host for relative URLs", () => {
      const result = extractBaseHost("/api/conversations/123");

Review comment (suggestion):
```suggestion
  beforeEach(() => {
    vi.stubGlobal("location", {
      host: "localhost:3001",
      protocol: "https:",
    });
  });

  afterEach(() => {
    vi.unstubAllGlobals();
  });
```

See https://vitest.dev/api/vi.html#vi-stubglobal

Code after:
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
import {
  extractBaseHost,
  extractPathPrefix,
  buildHttpBaseUrl,
  buildWebSocketUrl,
} from "#/utils/websocket-url";

describe("websocket-url utilities", () => {
  beforeEach(() => {
    vi.stubGlobal("location", {
      host: "localhost:3001",
      protocol: "https:",
    });
  });

  afterEach(() => {
    vi.unstubAllGlobals();
  });

  describe("extractBaseHost", () => {
    it("should extract host from a standard URL", () => {
      const result = extractBaseHost(
        "https://example.com/api/conversations/123",
      );
      expect(result).toBe("example.com");
    });

    it("should extract host with port from URL", () => {
      const result = extractBaseHost(
        "http://localhost:3000/api/conversations/123",
      );
      expect(result).toBe("localhost:3000");
    });

    it("should extract host from proxy deployment URL", () => {
      const result = extractBaseHost(
        "https://openhands.example.com/runtime/55313/api/conversations/abc123",
      );
      expect(result).toBe("openhands.example.com");
    });

    it("should return window.location.host for relative URLs", () => {
      const result = extractBaseHost("/api/conversations/123");
      expect(result).toBe("localhost:3001");
    });

    it("should return window.location.host for null, undefined, or invalid URL", () => {
      expect(extractBaseHost(null)).toBe("localhost:3001");
      expect(extractBaseHost(undefined)).toBe("localhost:3001");