github.com/hellofresh/janus@v0.0.0-20230925145208-ce8de8183c67/pkg/loader/api_loader_test.go (about) 1 // +build integration 2 3 package loader 4 5 import ( 6 "fmt" 7 "io/ioutil" 8 "net/http" 9 "os" 10 "path/filepath" 11 "strings" 12 "testing" 13 14 "github.com/hellofresh/stats-go/client" 15 log "github.com/sirupsen/logrus" 16 "github.com/stretchr/testify/assert" 17 "github.com/stretchr/testify/require" 18 19 "github.com/hellofresh/janus/pkg/api" 20 "github.com/hellofresh/janus/pkg/errors" 21 "github.com/hellofresh/janus/pkg/middleware" 22 "github.com/hellofresh/janus/pkg/proxy" 23 "github.com/hellofresh/janus/pkg/router" 24 "github.com/hellofresh/janus/pkg/test" 25 ) 26 27 const ( 28 defaultUpstreamsPort = "9089" 29 defaultAPIsDir = "../../assets/apis" 30 ) 31 32 var tests = []struct { 33 description string 34 method string 35 url string 36 headers map[string]string 37 expectedHeaders map[string]string 38 expectedCode int 39 }{ 40 { 41 description: "Get example route", 42 method: "GET", 43 url: "/example", 44 expectedHeaders: map[string]string{ 45 "Content-Type": "application/json; charset=utf-8", 46 }, 47 expectedCode: http.StatusOK, 48 }, { 49 description: "Get invalid route", 50 method: "GET", 51 url: "/invalid-route", 52 expectedHeaders: map[string]string{ 53 "Content-Type": "application/json", 54 }, 55 expectedCode: http.StatusNotFound, 56 }, 57 } 58 59 func TestSuccessfulLoader(t *testing.T) { 60 log.SetOutput(ioutil.Discard) 61 62 routerInstance := createRegisterAndRouter(t) 63 ts := test.NewServer(routerInstance) 64 defer ts.Close() 65 66 for _, tc := range tests { 67 t.Run(tc.description, func(t *testing.T) { 68 res, err := ts.Do(tc.method, tc.url, tc.headers) 69 require.NoError(t, err) 70 t.Cleanup(func() { 71 err := res.Body.Close() 72 assert.NoError(t, err) 73 }) 74 75 for headerName, headerValue := range tc.expectedHeaders { 76 assert.Equal(t, headerValue, res.Header.Get(headerName)) 77 } 78 79 assert.Equal(t, tc.expectedCode, res.StatusCode) 80 }) 81 } 82 } 83 84 func createRegisterAndRouter(t *testing.T) router.Router { 85 t.Helper() 86 87 r := createRouter(t) 88 r.Use(middleware.NewRecovery(errors.RecoveryHandler)) 89 90 register := proxy.NewRegister(proxy.WithRouter(r), proxy.WithStatsClient(client.NewNoop())) 91 proxyRepo, err := api.NewFileSystemRepository(getAPIsDir(t)) 92 require.NoError(t, err) 93 94 defs, err := proxyRepo.FindAll() 95 require.NoError(t, err) 96 97 loader := NewAPILoader(register) 98 loader.RegisterAPIs(defs) 99 100 return r 101 } 102 103 func createRouter(t *testing.T) router.Router { 104 t.Helper() 105 106 router.DefaultOptions.NotFoundHandler = errors.NotFound 107 return router.NewChiRouterWithOptions(router.DefaultOptions) 108 } 109 110 func getAPIsDir(t *testing.T) string { 111 t.Helper() 112 113 upstreamsPort := os.Getenv("DYNAMIC_UPSTREAMS_PORT") 114 if upstreamsPort == "" { 115 // dynamic port is not set - use API defs as is 116 return defaultAPIsDir 117 } 118 119 // dynamic port is set - we need to replace default port with the dynamic one 120 dynamicAPIsDir, err := ioutil.TempDir("", "apis") 121 require.NoError(t, err) 122 t.Cleanup(func() { 123 err := os.RemoveAll(dynamicAPIsDir) 124 assert.NoError(t, err) 125 }) 126 127 defaultUpstreamsHost := fmt.Sprintf("/localhost:%s/", defaultUpstreamsPort) 128 dynamicUpstreamsHost := fmt.Sprintf("/localhost:%s/", upstreamsPort) 129 err = filepath.Walk(defaultAPIsDir, func(path string, info os.FileInfo, err error) error { 130 if err != nil || info.IsDir() { 131 return err 132 } 133 134 defaultContents, err := ioutil.ReadFile(path) 135 if err != nil { 136 return err 137 } 138 139 dynamicContents := strings.ReplaceAll(string(defaultContents), defaultUpstreamsHost, dynamicUpstreamsHost) 140 return ioutil.WriteFile(filepath.Join(dynamicAPIsDir, info.Name()), []byte(dynamicContents), os.ModePerm) 141 }) 142 require.NoError(t, err) 143 144 return dynamicAPIsDir 145 }