|
1 | 1 | package kiali |
2 | 2 |
|
3 | 3 | import ( |
4 | | - "context" |
| 4 | + "fmt" |
5 | 5 | "net/http" |
6 | | - "net/http/httptest" |
7 | 6 | "net/url" |
8 | 7 | "testing" |
9 | 8 |
|
| 9 | + "github.com/containers/kubernetes-mcp-server/internal/test" |
10 | 10 | "github.com/containers/kubernetes-mcp-server/pkg/config" |
| 11 | + "github.com/stretchr/testify/suite" |
11 | 12 | ) |
12 | 13 |
|
13 | | -func TestValidateAndGetURL_JoinsProperly(t *testing.T) { |
14 | | - cfg := config.Default() |
15 | | - cfg.SetToolsetConfig("kiali", &Config{Url: "https://kiali.example/"}) |
16 | | - m := NewManager(cfg) |
17 | | - k := m.GetKiali() |
18 | | - |
19 | | - full, err := k.validateAndGetURL("/api/path") |
20 | | - if err != nil { |
21 | | - t.Fatalf("unexpected error: %v", err) |
22 | | - } |
23 | | - if full != "https://kiali.example/api/path" { |
24 | | - t.Fatalf("unexpected url: %s", full) |
25 | | - } |
26 | | - |
27 | | - m.KialiURL = "https://kiali.example" |
28 | | - full, err = k.validateAndGetURL("api/path") |
29 | | - if err != nil { |
30 | | - t.Fatalf("unexpected error: %v", err) |
31 | | - } |
32 | | - if full != "https://kiali.example/api/path" { |
33 | | - t.Fatalf("unexpected url: %s", full) |
34 | | - } |
35 | | - |
36 | | - // preserve query |
37 | | - m.KialiURL = "https://kiali.example" |
38 | | - full, err = k.validateAndGetURL("/api/path?x=1&y=2") |
39 | | - if err != nil { |
40 | | - t.Fatalf("unexpected error: %v", err) |
41 | | - } |
42 | | - u, _ := url.Parse(full) |
43 | | - if u.Path != "/api/path" || u.Query().Get("x") != "1" || u.Query().Get("y") != "2" { |
44 | | - t.Fatalf("unexpected parsed url: %s", full) |
45 | | - } |
| 14 | +type KialiSuite struct { |
| 15 | + suite.Suite |
| 16 | + MockServer *test.MockServer |
| 17 | + Config *config.StaticConfig |
| 18 | +} |
| 19 | + |
| 20 | +func (s *KialiSuite) SetupTest() { |
| 21 | + s.MockServer = test.NewMockServer() |
| 22 | + s.MockServer.Config().BearerToken = "" |
| 23 | + s.Config = config.Default() |
| 24 | +} |
| 25 | + |
| 26 | +func (s *KialiSuite) TearDownTest() { |
| 27 | + s.MockServer.Close() |
| 28 | +} |
| 29 | + |
| 30 | +func (s *KialiSuite) TestNewKiali_SetsFields() { |
| 31 | + s.Config = test.Must(config.ReadToml([]byte(` |
| 32 | + [toolset_configs.kiali] |
| 33 | + url = "https://kiali.example/" |
| 34 | + insecure = true |
| 35 | + `))) |
| 36 | + s.MockServer.Config().BearerToken = "bearer-token" |
| 37 | + k := NewKiali(s.Config, s.MockServer.Config()) |
| 38 | + |
| 39 | + s.Run("URL is set", func() { |
| 40 | + s.Equal("https://kiali.example/", k.kialiURL, "Unexpected Kiali URL") |
| 41 | + }) |
| 42 | + s.Run("Insecure is set", func() { |
| 43 | + s.True(k.kialiInsecure, "Expected Kiali Insecure to be true") |
| 44 | + }) |
| 45 | + s.Run("BearerToken is set", func() { |
| 46 | + s.Equal("bearer-token", k.bearerToken, "Unexpected Kiali BearerToken") |
| 47 | + }) |
| 48 | +} |
| 49 | + |
| 50 | +func (s *KialiSuite) TestNewKiali_InvalidConfig() { |
| 51 | + cfg, err := config.ReadToml([]byte(` |
| 52 | + [toolset_configs.kiali] |
| 53 | + url = "://invalid-url" |
| 54 | + `)) |
| 55 | + s.Error(err, "Expected error reading invalid config") |
| 56 | + s.ErrorContains(err, "kiali-url must be a valid URL", "Unexpected error message") |
| 57 | + s.Nil(cfg, "Unexpected Kiali config") |
| 58 | +} |
| 59 | + |
| 60 | +func (s *KialiSuite) TestValidateAndGetURL() { |
| 61 | + s.Config = test.Must(config.ReadToml([]byte(` |
| 62 | + [toolset_configs.kiali] |
| 63 | + url = "https://kiali.example/" |
| 64 | + `))) |
| 65 | + k := NewKiali(s.Config, s.MockServer.Config()) |
| 66 | + |
| 67 | + s.Run("Computes full URL", func() { |
| 68 | + s.Run("with leading slash", func() { |
| 69 | + full, err := k.validateAndGetURL("/api/path") |
| 70 | + s.Require().NoError(err, "Expected no error validating URL") |
| 71 | + s.Equal("https://kiali.example/api/path", full, "Unexpected full URL") |
| 72 | + }) |
| 73 | + |
| 74 | + s.Run("without leading slash", func() { |
| 75 | + full, err := k.validateAndGetURL("api/path") |
| 76 | + s.Require().NoError(err, "Expected no error validating URL") |
| 77 | + s.Equal("https://kiali.example/api/path", full, "Unexpected full URL") |
| 78 | + }) |
| 79 | + |
| 80 | + s.Run("with query parameters, preserves query", func() { |
| 81 | + full, err := k.validateAndGetURL("/api/path?x=1&y=2") |
| 82 | + s.Require().NoError(err, "Expected no error validating URL") |
| 83 | + u, err := url.Parse(full) |
| 84 | + s.Require().NoError(err, "Expected to parse full URL") |
| 85 | + s.Equal("/api/path", u.Path, "Unexpected path in parsed URL") |
| 86 | + s.Equal("1", u.Query().Get("x"), "Unexpected query parameter x") |
| 87 | + s.Equal("2", u.Query().Get("y"), "Unexpected query parameter y") |
| 88 | + }) |
| 89 | + }) |
46 | 90 | } |
47 | 91 |
|
48 | 92 | // CurrentAuthorizationHeader behavior is now implicit via executeRequest using Manager.BearerToken |
49 | 93 |
|
50 | | -func TestExecuteRequest_SetsAuthAndCallsServer(t *testing.T) { |
| 94 | +func (s *KialiSuite) TestExecuteRequest() { |
51 | 95 | // setup test server to assert path and auth header |
52 | 96 | var seenAuth string |
53 | 97 | var seenPath string |
54 | | - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| 98 | + s.MockServer.Config().BearerToken = "token-xyz" |
| 99 | + s.MockServer.Handle(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
55 | 100 | seenAuth = r.Header.Get("Authorization") |
56 | 101 | seenPath = r.URL.String() |
57 | 102 | _, _ = w.Write([]byte("ok")) |
58 | 103 | })) |
59 | | - defer srv.Close() |
60 | | - |
61 | | - cfg := config.Default() |
62 | | - cfg.SetToolsetConfig("kiali", &Config{Url: srv.URL}) |
63 | | - m := NewManager(cfg) |
64 | | - m.BearerToken = "token-xyz" |
65 | | - k := m.GetKiali() |
66 | | - out, err := k.executeRequest(context.Background(), "/api/ping?q=1") |
67 | | - if err != nil { |
68 | | - t.Fatalf("unexpected error: %v", err) |
69 | | - } |
70 | | - if out != "ok" { |
71 | | - t.Fatalf("unexpected body: %s", out) |
72 | | - } |
73 | | - if seenAuth != "Bearer token-xyz" { |
74 | | - t.Fatalf("expected auth header to be set, got '%s'", seenAuth) |
75 | | - } |
76 | | - if seenPath != "/api/ping?q=1" { |
77 | | - t.Fatalf("unexpected path: %s", seenPath) |
78 | | - } |
| 104 | + |
| 105 | + s.Config = test.Must(config.ReadToml([]byte(fmt.Sprintf(` |
| 106 | + [toolset_configs.kiali] |
| 107 | + url = "%s" |
| 108 | + `, s.MockServer.Config().Host)))) |
| 109 | + k := NewKiali(s.Config, s.MockServer.Config()) |
| 110 | + |
| 111 | + out, err := k.executeRequest(s.T().Context(), "/api/ping?q=1") |
| 112 | + s.Require().NoError(err, "Expected no error executing request") |
| 113 | + s.Run("auth header set", func() { |
| 114 | + s.Equal("Bearer token-xyz", seenAuth, "Unexpected Authorization header") |
| 115 | + }) |
| 116 | + s.Run("path is correct", func() { |
| 117 | + s.Equal("/api/ping?q=1", seenPath, "Unexpected path") |
| 118 | + }) |
| 119 | + s.Run("response body is correct", func() { |
| 120 | + s.Equal("ok", out, "Unexpected response body") |
| 121 | + }) |
| 122 | +} |
| 123 | + |
| 124 | +func TestKiali(t *testing.T) { |
| 125 | + suite.Run(t, new(KialiSuite)) |
79 | 126 | } |
0 commit comments