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  }