github.com/hellofresh/janus@v0.0.0-20230925145208-ce8de8183c67/pkg/proxy/register_test.go (about) 1 // +build integration 2 3 package proxy 4 5 import ( 6 "fmt" 7 "io/ioutil" 8 "net/http" 9 "os" 10 "testing" 11 12 "github.com/hellofresh/stats-go/client" 13 log "github.com/sirupsen/logrus" 14 "github.com/stretchr/testify/assert" 15 "github.com/stretchr/testify/require" 16 17 "github.com/hellofresh/janus/pkg/router" 18 "github.com/hellofresh/janus/pkg/test" 19 ) 20 21 const defaultUpstreamsPort = "9089" 22 23 var tests = []struct { 24 description string 25 method string 26 url string 27 expectedContentType string 28 expectedCode int 29 }{ 30 { 31 description: "Get example route", 32 method: "GET", 33 url: "/example", 34 expectedContentType: "application/json; charset=utf-8", 35 expectedCode: http.StatusOK, 36 }, { 37 description: "Get invalid route", 38 method: "GET", 39 url: "/invalid-route", 40 expectedContentType: "text/plain; charset=utf-8", 41 expectedCode: http.StatusNotFound, 42 }, 43 { 44 description: "Get one posts - strip path", 45 method: "GET", 46 url: "/posts/1", 47 expectedContentType: "application/json; charset=utf-8", 48 expectedCode: http.StatusOK, 49 }, 50 { 51 description: "Get one posts - append path", 52 method: "GET", 53 url: "/append", 54 expectedContentType: "application/json; charset=utf-8", 55 expectedCode: http.StatusOK, 56 }, 57 { 58 description: "Get one recipe - parameter interpolation", 59 url: "/api/recipes/5252b1b5301bbf46038b473f", 60 expectedContentType: "application/json; charset=utf-8", 61 expectedCode: http.StatusOK, 62 }, 63 { 64 description: "No parameter to interpolate", 65 url: "/api/recipes/search", 66 expectedContentType: "application/json", 67 expectedCode: http.StatusNotFound, 68 }, 69 { 70 description: "named param with strip path to posts", 71 method: "GET", 72 url: "/private/localhost/posts/1", 73 expectedContentType: "application/json; charset=utf-8", 74 expectedCode: http.StatusOK, 75 }, 76 { 77 description: "named param with strip path - no api", 78 method: "GET", 79 url: "/private/localhost/no-api", 80 expectedContentType: "application/json", 81 expectedCode: http.StatusNotFound, 82 }, 83 } 84 85 func TestSuccessfulProxy(t *testing.T) { 86 t.Parallel() 87 88 log.SetOutput(ioutil.Discard) 89 90 ts := test.NewServer(createRegisterAndRouter(t)) 91 defer ts.Close() 92 93 for _, tc := range tests { 94 t.Run(tc.description, func(t *testing.T) { 95 res, err := ts.Do(tc.method, tc.url, make(map[string]string)) 96 require.NoError(t, err) 97 t.Cleanup(func() { 98 err := res.Body.Close() 99 assert.NoError(t, err) 100 }) 101 102 assert.Equal(t, tc.expectedContentType, res.Header.Get("Content-Type"), tc.description) 103 assert.Equal(t, tc.expectedCode, res.StatusCode, tc.description) 104 }) 105 } 106 } 107 108 func createProxyDefinitions(t *testing.T) []*Definition { 109 t.Helper() 110 111 upstreamsPort := os.Getenv("DYNAMIC_UPSTREAMS_PORT") 112 if upstreamsPort == "" { 113 upstreamsPort = defaultUpstreamsPort 114 } 115 116 return []*Definition{ 117 { 118 ListenPath: "/example/*", 119 Upstreams: &Upstreams{ 120 Balancing: "roundrobin", 121 Targets: []*Target{{Target: fmt.Sprintf("http://localhost:%s/hello-world", upstreamsPort)}}, 122 }, 123 Methods: []string{"ALL"}, 124 }, 125 { 126 ListenPath: "/posts/*", 127 StripPath: true, 128 Upstreams: &Upstreams{ 129 Balancing: "roundrobin", 130 Targets: []*Target{{Target: fmt.Sprintf("http://localhost:%s/posts", upstreamsPort)}}, 131 }, 132 Methods: []string{"ALL"}, 133 }, 134 { 135 ListenPath: "/append/*", 136 Upstreams: &Upstreams{ 137 Balancing: "roundrobin", 138 Targets: []*Target{{Target: fmt.Sprintf("http://localhost:%s/hello-world", upstreamsPort)}}, 139 }, 140 AppendPath: true, 141 Methods: []string{"GET"}, 142 }, 143 { 144 ListenPath: "/api/recipes/{id:[\\da-f]{24}}", 145 Upstreams: &Upstreams{ 146 Balancing: "roundrobin", 147 Targets: []*Target{{Target: fmt.Sprintf("http://localhost:%s/recipes/{id}", upstreamsPort)}}, 148 }, 149 Methods: []string{"GET"}, 150 }, 151 { 152 ListenPath: "/api/recipes/search", 153 Upstreams: &Upstreams{ 154 Balancing: "roundrobin", 155 Targets: []*Target{{Target: fmt.Sprintf("http://localhost:%s/recipes/{id}", upstreamsPort)}}, 156 }, 157 Methods: []string{"GET"}, 158 }, 159 { 160 ListenPath: "/private/{service}/*", 161 Upstreams: &Upstreams{ 162 Balancing: "roundrobin", 163 Targets: []*Target{{Target: fmt.Sprintf("http://{service}:%s/", upstreamsPort)}}, 164 }, 165 StripPath: true, 166 Methods: []string{"ALL"}, 167 }, 168 } 169 } 170 171 func createRegisterAndRouter(t *testing.T) router.Router { 172 t.Helper() 173 174 r := router.NewChiRouter() 175 createRegister(t, r) 176 return r 177 } 178 179 func createRegister(t *testing.T, r router.Router) *Register { 180 t.Helper() 181 182 register := NewRegister(WithRouter(r), WithStatsClient(client.NewNoop())) 183 184 definitions := createProxyDefinitions(t) 185 for _, def := range definitions { 186 err := register.Add(NewRouterDefinition(def)) 187 require.NoError(t, err) 188 } 189 190 return register 191 }