File size: 3,507 Bytes
2f49513
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import { renderHook } from "@testing-library/react";
import useACEControllerURL from "../useACEControllerURL";

describe("useACEControllerURL", () => {
  const originalLocation = window.location;

  beforeEach(() => {
    const mockLocation = new URL("http://localhost:3000");

    Object.defineProperty(window, "location", {
      writable: true,
      value: mockLocation,
    });
  });

  // Restore the original location after tests
  afterEach(() => {
    Object.defineProperty(window, "location", {
      writable: true,
      value: originalLocation,
    });
  });

  test("returns default URL when no query parameter is provided", () => {
    const onError = jest.fn();
    const { result } = renderHook(() => useACEControllerURL({ onError }));

    expect(result.current.baseUrl).toBe("ws://localhost:8100/ws/");
    expect(result.current.baseUrlWithStreamID).toMatch(
      /^ws:\/\/localhost:8100\/ws\/[a-z0-9]+$/
    );
    expect(onError).not.toHaveBeenCalled();
  });

  test("uses provided URL from query parameter when valid", () => {
    // Set up query parameter
    window.location.search = "?ace-controller-url=ws://example.com/websocket/";

    const onError = jest.fn();
    const { result } = renderHook(() => useACEControllerURL({ onError }));

    expect(result.current.baseUrl).toBe("ws://example.com/websocket/");
    expect(result.current.baseUrlWithStreamID).toMatch(
      /^ws:\/\/example\.com\/websocket\/[a-z0-9]+$/
    );
    expect(onError).not.toHaveBeenCalled();
  });

  test("uses wss protocol when provided", () => {
    // Set up query parameter with secure websocket
    window.location.search = "?ace-controller-url=wss://secure-example.com/ws/";

    const onError = jest.fn();
    const { result } = renderHook(() => useACEControllerURL({ onError }));

    expect(result.current.baseUrl).toBe("wss://secure-example.com/ws/");
    expect(result.current.baseUrlWithStreamID).toMatch(
      /^wss:\/\/secure-example\.com\/ws\/[a-z0-9]+$/
    );
    expect(onError).not.toHaveBeenCalled();
  });

  test("falls back to default URL when provided URL is invalid", () => {
    // Set up invalid query parameter
    window.location.search = "?ace-controller-url=http://invalid-protocol.com/";

    const onError = jest.fn();
    const { result } = renderHook(() => useACEControllerURL({ onError }));

    expect(result.current.baseUrl).toBe("ws://localhost:8100/ws/");
    expect(result.current.baseUrlWithStreamID).toMatch(
      /^ws:\/\/localhost:8100\/ws\/[a-z0-9]+$/
    );
    expect(onError).toHaveBeenCalledWith(
      expect.objectContaining({
        message: expect.stringContaining("Invalid websocket URL"),
      })
    );
  });

  test("uses cached URL reference on subsequent renders", () => {
    const onError = jest.fn();

    // First render - should set the URL
    const { result, rerender } = renderHook(() =>
      useACEControllerURL({ onError })
    );
    const initialBaseUrl = result.current.baseUrl;
    const initialBaseUrlWithStreamID = result.current.baseUrlWithStreamID;

    // Change the URL in the query parameter, but it shouldn't affect the result
    window.location.search = "?ace-controller-url=ws://different-url.com/ws/";

    // Re-render the hook
    rerender();

    // Verify that the hook uses the cached value and doesn't update
    expect(result.current.baseUrl).toBe(initialBaseUrl);
    expect(result.current.baseUrlWithStreamID).toBe(initialBaseUrlWithStreamID);
    expect(onError).not.toHaveBeenCalled();
  });
});