|
|
@@ -22,78 +22,154 @@ import (
|
|
|
vr "github.com/porter-dev/porter/internal/validator"
|
|
|
)
|
|
|
|
|
|
-func initApi(canQuery bool) (*api.App, *repository.Repository) {
|
|
|
- appConf := config.Conf{
|
|
|
- Debug: true,
|
|
|
- Server: config.ServerConf{
|
|
|
- Port: 8080,
|
|
|
- TimeoutRead: time.Second * 5,
|
|
|
- TimeoutWrite: time.Second * 10,
|
|
|
- TimeoutIdle: time.Second * 15,
|
|
|
- },
|
|
|
- // unimportant
|
|
|
- Db: config.DBConf{},
|
|
|
- }
|
|
|
-
|
|
|
- logger := lr.NewConsole(appConf.Debug)
|
|
|
- validator := vr.New()
|
|
|
+type tester struct {
|
|
|
+ app *api.App
|
|
|
+ repo *repository.Repository
|
|
|
+ store *sessionstore.PGStore
|
|
|
+ router *chi.Mux
|
|
|
+ req *http.Request
|
|
|
+ rr *httptest.ResponseRecorder
|
|
|
+ cookie *http.Cookie
|
|
|
+}
|
|
|
|
|
|
- repo := test.NewRepository(canQuery)
|
|
|
+type userTest struct {
|
|
|
+ initializers []func(t *tester)
|
|
|
+ msg string
|
|
|
+ method string
|
|
|
+ endpoint string
|
|
|
+ body string
|
|
|
+ expStatus int
|
|
|
+ expBody string
|
|
|
+ useCookie bool
|
|
|
+ validators []func(c *userTest, tester *tester, t *testing.T)
|
|
|
+}
|
|
|
|
|
|
- key := []byte("secret") // TODO: change to os.Getenv("SESSION_KEY")
|
|
|
- store, _ := sessionstore.NewStore(repo, key)
|
|
|
+func (t *tester) execute() {
|
|
|
+ t.router.ServeHTTP(t.rr, t.req)
|
|
|
+}
|
|
|
|
|
|
- return api.New(logger, repo, validator, store), repo
|
|
|
+func (t *tester) reset() {
|
|
|
+ t.rr = httptest.NewRecorder()
|
|
|
+ t.req = nil
|
|
|
}
|
|
|
|
|
|
-func testUserRequest(t *testing.T, c userTest) {
|
|
|
- // create a mock API
|
|
|
- api, repo := initApi(c.canQuery)
|
|
|
- r := router.New(api)
|
|
|
+func (t *tester) createUserSession(email string, pw string) {
|
|
|
+ req, _ := http.NewRequest(
|
|
|
+ "POST",
|
|
|
+ "/api/users",
|
|
|
+ strings.NewReader(`{"email":"`+email+`","password":"`+pw+`"}`),
|
|
|
+ )
|
|
|
|
|
|
- if c.init != nil {
|
|
|
- c.init(repo)
|
|
|
+ t.req = req
|
|
|
+ t.execute()
|
|
|
+
|
|
|
+ if cookies := t.rr.Result().Cookies(); len(cookies) > 0 {
|
|
|
+ t.cookie = cookies[0]
|
|
|
}
|
|
|
|
|
|
- req, err := http.NewRequest(
|
|
|
- c.method,
|
|
|
- c.endpoint,
|
|
|
- strings.NewReader(c.body),
|
|
|
- )
|
|
|
+ t.reset()
|
|
|
+}
|
|
|
|
|
|
- if err != nil {
|
|
|
- t.Fatal(err)
|
|
|
+func initUserDefault(tester *tester) {
|
|
|
+ tester.createUserSession("belanger@getporter.dev", "hello")
|
|
|
+}
|
|
|
+
|
|
|
+func initUserWithClusters(tester *tester) {
|
|
|
+ initUserDefault(tester)
|
|
|
+
|
|
|
+ user, _ := tester.repo.User.ReadUserByEmail("belanger@getporter.dev")
|
|
|
+ user.Clusters = []models.ClusterConfig{
|
|
|
+ models.ClusterConfig{
|
|
|
+ Name: "cluster-test",
|
|
|
+ Server: "https://localhost",
|
|
|
+ Context: "context-test",
|
|
|
+ User: "test-admin",
|
|
|
+ },
|
|
|
}
|
|
|
+ user.RawKubeConfig = []byte("apiVersion: v1\nkind: Config\npreferences: {}\ncurrent-context: default\nclusters:\n- cluster:\n server: https://localhost\n name: cluster-test\ncontexts:\n- context:\n cluster: cluster-test\n user: test-admin\n name: context-test\nusers:\n- name: test-admin")
|
|
|
|
|
|
- rr := httptest.NewRecorder()
|
|
|
- r.ServeHTTP(rr, req)
|
|
|
+ tester.repo.User.UpdateUser(user)
|
|
|
+}
|
|
|
|
|
|
- // first, check that the status matches
|
|
|
- if status := rr.Code; status != c.expStatus {
|
|
|
- t.Errorf("%s, handler returned wrong status code: got %v want %v",
|
|
|
- c.msg, status, c.expStatus)
|
|
|
+func newTester(canQuery bool) *tester {
|
|
|
+ appConf := config.Conf{
|
|
|
+ Debug: true,
|
|
|
+ Server: config.ServerConf{
|
|
|
+ Port: 8080,
|
|
|
+ CookieName: "porter",
|
|
|
+ CookieSecrets: [][]byte{[]byte("secret")},
|
|
|
+ TimeoutRead: time.Second * 5,
|
|
|
+ TimeoutWrite: time.Second * 10,
|
|
|
+ TimeoutIdle: time.Second * 15,
|
|
|
+ },
|
|
|
+ // unimportant here
|
|
|
+ Db: config.DBConf{},
|
|
|
}
|
|
|
|
|
|
- // if there's a validator, call it
|
|
|
- for _, validate := range c.validators {
|
|
|
- validate(rr, c, r, t)
|
|
|
+ logger := lr.NewConsole(appConf.Debug)
|
|
|
+ validator := vr.New()
|
|
|
+
|
|
|
+ repo := test.NewRepository(canQuery)
|
|
|
+
|
|
|
+ store, _ := sessionstore.NewStore(repo, appConf.Server)
|
|
|
+ app := api.New(logger, repo, validator, store, appConf.Server.CookieName)
|
|
|
+ r := router.New(app)
|
|
|
+
|
|
|
+ return &tester{
|
|
|
+ app: app,
|
|
|
+ repo: repo,
|
|
|
+ store: store,
|
|
|
+ router: r,
|
|
|
+ req: nil,
|
|
|
+ rr: httptest.NewRecorder(),
|
|
|
+ cookie: nil,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-type userTest struct {
|
|
|
- init func(repo *repository.Repository)
|
|
|
- msg,
|
|
|
- method,
|
|
|
- endpoint,
|
|
|
- body string
|
|
|
- expStatus int
|
|
|
- expBody string
|
|
|
- canQuery bool
|
|
|
- validators []func(rr *httptest.ResponseRecorder, c userTest, r *chi.Mux, t *testing.T)
|
|
|
+func testUserRequests(t *testing.T, tests []*userTest, canQuery bool) {
|
|
|
+ for _, c := range tests {
|
|
|
+ // create a new tester
|
|
|
+ tester := newTester(canQuery)
|
|
|
+
|
|
|
+ // if there's an initializer, call it
|
|
|
+ for _, init := range c.initializers {
|
|
|
+ init(tester)
|
|
|
+ }
|
|
|
+
|
|
|
+ req, err := http.NewRequest(
|
|
|
+ c.method,
|
|
|
+ c.endpoint,
|
|
|
+ strings.NewReader(c.body),
|
|
|
+ )
|
|
|
+
|
|
|
+ tester.req = req
|
|
|
+
|
|
|
+ if c.useCookie {
|
|
|
+ req.AddCookie(tester.cookie)
|
|
|
+ }
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ t.Fatal(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ tester.execute()
|
|
|
+ rr := tester.rr
|
|
|
+
|
|
|
+ // first, check that the status matches
|
|
|
+ if status := rr.Code; status != c.expStatus {
|
|
|
+ t.Errorf("%s, handler returned wrong status code: got %v want %v",
|
|
|
+ c.msg, status, c.expStatus)
|
|
|
+ }
|
|
|
+
|
|
|
+ // if there's a validator, call it
|
|
|
+ for _, validate := range c.validators {
|
|
|
+ validate(c, tester, t)
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-var createUserTests = []userTest{
|
|
|
- userTest{
|
|
|
+var createUserTests = []*userTest{
|
|
|
+ &userTest{
|
|
|
msg: "Create user",
|
|
|
method: "POST",
|
|
|
endpoint: "/api/users",
|
|
|
@@ -103,9 +179,8 @@ var createUserTests = []userTest{
|
|
|
}`,
|
|
|
expStatus: http.StatusCreated,
|
|
|
expBody: "",
|
|
|
- canQuery: true,
|
|
|
},
|
|
|
- userTest{
|
|
|
+ &userTest{
|
|
|
msg: "Create user invalid email",
|
|
|
method: "POST",
|
|
|
endpoint: "/api/users",
|
|
|
@@ -115,12 +190,11 @@ var createUserTests = []userTest{
|
|
|
}`,
|
|
|
expStatus: http.StatusUnprocessableEntity,
|
|
|
expBody: `{"code":601,"errors":["email validation failed"]}`,
|
|
|
- canQuery: true,
|
|
|
- validators: []func(rr *httptest.ResponseRecorder, c userTest, r *chi.Mux, t *testing.T){
|
|
|
+ validators: []func(c *userTest, tester *tester, t *testing.T){
|
|
|
BasicBodyValidator,
|
|
|
},
|
|
|
},
|
|
|
- userTest{
|
|
|
+ &userTest{
|
|
|
msg: "Create user missing field",
|
|
|
method: "POST",
|
|
|
endpoint: "/api/users",
|
|
|
@@ -129,86 +203,146 @@ var createUserTests = []userTest{
|
|
|
}`,
|
|
|
expStatus: http.StatusUnprocessableEntity,
|
|
|
expBody: `{"code":601,"errors":["required validation failed"]}`,
|
|
|
- canQuery: true,
|
|
|
- validators: []func(rr *httptest.ResponseRecorder, c userTest, r *chi.Mux, t *testing.T){
|
|
|
+ validators: []func(c *userTest, tester *tester, t *testing.T){
|
|
|
BasicBodyValidator,
|
|
|
},
|
|
|
},
|
|
|
- userTest{
|
|
|
- msg: "Create user db connection down",
|
|
|
+ &userTest{
|
|
|
+ initializers: []func(tester *tester){
|
|
|
+ initUserDefault,
|
|
|
+ },
|
|
|
+ msg: "Create user same email",
|
|
|
method: "POST",
|
|
|
endpoint: "/api/users",
|
|
|
body: `{
|
|
|
"email": "belanger@getporter.dev",
|
|
|
"password": "hello"
|
|
|
}`,
|
|
|
+ expStatus: http.StatusUnprocessableEntity,
|
|
|
+ expBody: `{"code":601,"errors":["email already taken"]}`,
|
|
|
+ validators: []func(c *userTest, tester *tester, t *testing.T){
|
|
|
+ BasicBodyValidator,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ &userTest{
|
|
|
+ msg: "Create user invalid field type",
|
|
|
+ method: "POST",
|
|
|
+ endpoint: "/api/users",
|
|
|
+ body: `{
|
|
|
+ "email": "belanger@getporter.dev",
|
|
|
+ "password": 0
|
|
|
+ }`,
|
|
|
+ expStatus: http.StatusBadRequest,
|
|
|
+ expBody: `{"code":600,"errors":["could not process request"]}`,
|
|
|
+ validators: []func(c *userTest, tester *tester, t *testing.T){
|
|
|
+ BasicBodyValidator,
|
|
|
+ },
|
|
|
+ },
|
|
|
+}
|
|
|
+
|
|
|
+func TestHandleCreateUser(t *testing.T) {
|
|
|
+ testUserRequests(t, createUserTests, true)
|
|
|
+}
|
|
|
+
|
|
|
+var createUserTestsWriteFail = []*userTest{
|
|
|
+ &userTest{
|
|
|
+ msg: "Create user db connection down",
|
|
|
+ method: "POST",
|
|
|
+ endpoint: "/api/users",
|
|
|
+ body: `{
|
|
|
+ "email": "belanger@getporter.dev",
|
|
|
+ "password": "hello"
|
|
|
+ }`,
|
|
|
expStatus: http.StatusInternalServerError,
|
|
|
expBody: `{"code":500,"errors":["could not read from database"]}`,
|
|
|
- canQuery: false,
|
|
|
- validators: []func(rr *httptest.ResponseRecorder, c userTest, r *chi.Mux, t *testing.T){
|
|
|
+ validators: []func(c *userTest, tester *tester, t *testing.T){
|
|
|
BasicBodyValidator,
|
|
|
},
|
|
|
},
|
|
|
- userTest{
|
|
|
- init: func(repo *repository.Repository) {
|
|
|
- repo.User.CreateUser(&models.User{
|
|
|
- Email: "belanger@getporter.dev",
|
|
|
- Password: "hello",
|
|
|
- })
|
|
|
+}
|
|
|
+
|
|
|
+func TestHandleCreateUserWriteFail(t *testing.T) {
|
|
|
+ testUserRequests(t, createUserTestsWriteFail, false)
|
|
|
+}
|
|
|
+
|
|
|
+var loginUserTests = []*userTest{
|
|
|
+ &userTest{
|
|
|
+ initializers: []func(tester *tester){
|
|
|
+ initUserDefault,
|
|
|
},
|
|
|
- msg: "Create user same email",
|
|
|
+ msg: "Login user successful",
|
|
|
method: "POST",
|
|
|
- endpoint: "/api/users",
|
|
|
+ endpoint: "/api/login",
|
|
|
body: `{
|
|
|
"email": "belanger@getporter.dev",
|
|
|
"password": "hello"
|
|
|
}`,
|
|
|
- expStatus: http.StatusUnprocessableEntity,
|
|
|
- expBody: `{"code":601,"errors":["email already taken"]}`,
|
|
|
- canQuery: true,
|
|
|
- validators: []func(rr *httptest.ResponseRecorder, c userTest, r *chi.Mux, t *testing.T){
|
|
|
+ expStatus: http.StatusOK,
|
|
|
+ expBody: ``,
|
|
|
+ validators: []func(c *userTest, tester *tester, t *testing.T){
|
|
|
BasicBodyValidator,
|
|
|
},
|
|
|
},
|
|
|
- userTest{
|
|
|
- msg: "Create user invalid field type",
|
|
|
+ &userTest{
|
|
|
+ initializers: []func(tester *tester){
|
|
|
+ initUserDefault,
|
|
|
+ },
|
|
|
+ msg: "Login user already logged in",
|
|
|
method: "POST",
|
|
|
- endpoint: "/api/users",
|
|
|
+ endpoint: "/api/login",
|
|
|
body: `{
|
|
|
"email": "belanger@getporter.dev",
|
|
|
- "password": 0
|
|
|
+ "password": "hello"
|
|
|
}`,
|
|
|
- expStatus: http.StatusBadRequest,
|
|
|
- expBody: `{"code":600,"errors":["could not process request"]}`,
|
|
|
- canQuery: true,
|
|
|
- validators: []func(rr *httptest.ResponseRecorder, c userTest, r *chi.Mux, t *testing.T){
|
|
|
+ expStatus: http.StatusOK,
|
|
|
+ expBody: ``,
|
|
|
+ useCookie: true,
|
|
|
+ validators: []func(c *userTest, tester *tester, t *testing.T){
|
|
|
+ BasicBodyValidator,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ &userTest{
|
|
|
+ msg: "Login user unregistered email",
|
|
|
+ method: "POST",
|
|
|
+ endpoint: "/api/login",
|
|
|
+ body: `{
|
|
|
+ "email": "belanger@getporter.dev",
|
|
|
+ "password": "hello"
|
|
|
+ }`,
|
|
|
+ expStatus: http.StatusUnauthorized,
|
|
|
+ expBody: `{"code":401,"errors":["email not registered"]}`,
|
|
|
+ validators: []func(c *userTest, tester *tester, t *testing.T){
|
|
|
+ BasicBodyValidator,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ &userTest{
|
|
|
+ initializers: []func(tester *tester){
|
|
|
+ initUserDefault,
|
|
|
+ },
|
|
|
+ msg: "Login user incorrect password",
|
|
|
+ method: "POST",
|
|
|
+ endpoint: "/api/login",
|
|
|
+ body: `{
|
|
|
+ "email": "belanger@getporter.dev",
|
|
|
+ "password": "notthepassword"
|
|
|
+ }`,
|
|
|
+ expStatus: http.StatusUnauthorized,
|
|
|
+ expBody: `{"code":401,"errors":["incorrect password"]}`,
|
|
|
+ useCookie: true,
|
|
|
+ validators: []func(c *userTest, tester *tester, t *testing.T){
|
|
|
BasicBodyValidator,
|
|
|
},
|
|
|
},
|
|
|
}
|
|
|
|
|
|
-func TestHandleCreateUser(t *testing.T) {
|
|
|
- for _, c := range createUserTests {
|
|
|
- testUserRequest(t, c)
|
|
|
- }
|
|
|
+func TestHandleLoginUser(t *testing.T) {
|
|
|
+ testUserRequests(t, loginUserTests, true)
|
|
|
}
|
|
|
|
|
|
-var readUserTests = []userTest{
|
|
|
- userTest{
|
|
|
- init: func(repo *repository.Repository) {
|
|
|
- repo.User.CreateUser(&models.User{
|
|
|
- Email: "belanger@getporter.dev",
|
|
|
- Password: "hello",
|
|
|
- Clusters: []models.ClusterConfig{
|
|
|
- models.ClusterConfig{
|
|
|
- Name: "cluster-test",
|
|
|
- Server: "https://localhost",
|
|
|
- Context: "context-test",
|
|
|
- User: "test-admin",
|
|
|
- },
|
|
|
- },
|
|
|
- RawKubeConfig: []byte("apiVersion: v1\nkind: Config\npreferences: {}\ncurrent-context: default\nclusters:\n- cluster:\n server: https://localhost\n name: cluster-test\ncontexts:\n- context:\n cluster: cluster-test\n user: test-admin\n name: context-test\nusers:\n- name: test-admin"),
|
|
|
- })
|
|
|
+var readUserTests = []*userTest{
|
|
|
+ &userTest{
|
|
|
+ initializers: []func(tester *tester){
|
|
|
+ initUserWithClusters,
|
|
|
},
|
|
|
msg: "Read user successful",
|
|
|
method: "GET",
|
|
|
@@ -216,17 +350,13 @@ var readUserTests = []userTest{
|
|
|
body: "",
|
|
|
expStatus: http.StatusOK,
|
|
|
expBody: `{"id":1,"email":"belanger@getporter.dev","clusters":[{"name":"cluster-test","server":"https://localhost","context":"context-test","user":"test-admin"}],"rawKubeConfig":"apiVersion: v1\nkind: Config\npreferences: {}\ncurrent-context: default\nclusters:\n- cluster:\n server: https://localhost\n name: cluster-test\ncontexts:\n- context:\n cluster: cluster-test\n user: test-admin\n name: context-test\nusers:\n- name: test-admin"}`,
|
|
|
- canQuery: true,
|
|
|
- validators: []func(rr *httptest.ResponseRecorder, c userTest, r *chi.Mux, t *testing.T){
|
|
|
+ validators: []func(c *userTest, tester *tester, t *testing.T){
|
|
|
UserModelBodyValidator,
|
|
|
},
|
|
|
},
|
|
|
- userTest{
|
|
|
- init: func(repo *repository.Repository) {
|
|
|
- repo.User.CreateUser(&models.User{
|
|
|
- Email: "belanger@getporter.dev",
|
|
|
- Password: "hello",
|
|
|
- })
|
|
|
+ &userTest{
|
|
|
+ initializers: []func(tester *tester){
|
|
|
+ initUserDefault,
|
|
|
},
|
|
|
msg: "Read user bad id field",
|
|
|
method: "GET",
|
|
|
@@ -234,17 +364,13 @@ var readUserTests = []userTest{
|
|
|
body: "",
|
|
|
expStatus: http.StatusBadRequest,
|
|
|
expBody: `{"code":600,"errors":["could not process request"]}`,
|
|
|
- canQuery: true,
|
|
|
- validators: []func(rr *httptest.ResponseRecorder, c userTest, r *chi.Mux, t *testing.T){
|
|
|
+ validators: []func(c *userTest, tester *tester, t *testing.T){
|
|
|
BasicBodyValidator,
|
|
|
},
|
|
|
},
|
|
|
- userTest{
|
|
|
- init: func(repo *repository.Repository) {
|
|
|
- repo.User.CreateUser(&models.User{
|
|
|
- Email: "belanger@getporter.dev",
|
|
|
- Password: "hello",
|
|
|
- })
|
|
|
+ &userTest{
|
|
|
+ initializers: []func(tester *tester){
|
|
|
+ initUserDefault,
|
|
|
},
|
|
|
msg: "Read user not found",
|
|
|
method: "GET",
|
|
|
@@ -252,35 +378,20 @@ var readUserTests = []userTest{
|
|
|
body: "",
|
|
|
expStatus: http.StatusNotFound,
|
|
|
expBody: `{"code":602,"errors":["could not find requested object"]}`,
|
|
|
- canQuery: true,
|
|
|
- validators: []func(rr *httptest.ResponseRecorder, c userTest, r *chi.Mux, t *testing.T){
|
|
|
+ validators: []func(c *userTest, tester *tester, t *testing.T){
|
|
|
BasicBodyValidator,
|
|
|
},
|
|
|
},
|
|
|
}
|
|
|
|
|
|
func TestHandleReadUser(t *testing.T) {
|
|
|
- for _, c := range readUserTests {
|
|
|
- testUserRequest(t, c)
|
|
|
- }
|
|
|
+ testUserRequests(t, readUserTests, true)
|
|
|
}
|
|
|
|
|
|
-var readUserClustersTests = []userTest{
|
|
|
- userTest{
|
|
|
- init: func(repo *repository.Repository) {
|
|
|
- repo.User.CreateUser(&models.User{
|
|
|
- Email: "belanger@getporter.dev",
|
|
|
- Password: "hello",
|
|
|
- Clusters: []models.ClusterConfig{
|
|
|
- models.ClusterConfig{
|
|
|
- Name: "cluster-test",
|
|
|
- Server: "https://localhost",
|
|
|
- Context: "context-test",
|
|
|
- User: "test-admin",
|
|
|
- },
|
|
|
- },
|
|
|
- RawKubeConfig: []byte("apiVersion: v1\nkind: Config\npreferences: {}\ncurrent-context: default\nclusters:\n- cluster:\n server: https://localhost\n name: cluster-test\ncontexts:\n- context:\n cluster: cluster-test\n user: test-admin\n name: context-test\nusers:\n- name: test-admin"),
|
|
|
- })
|
|
|
+var readUserClustersTests = []*userTest{
|
|
|
+ &userTest{
|
|
|
+ initializers: []func(tester *tester){
|
|
|
+ initUserWithClusters,
|
|
|
},
|
|
|
msg: "Read user successful",
|
|
|
method: "GET",
|
|
|
@@ -288,28 +399,20 @@ var readUserClustersTests = []userTest{
|
|
|
body: "",
|
|
|
expStatus: http.StatusOK,
|
|
|
expBody: `[{"name":"cluster-test","server":"https://localhost","context":"context-test","user":"test-admin"}]`,
|
|
|
- canQuery: true,
|
|
|
- validators: []func(rr *httptest.ResponseRecorder, c userTest, r *chi.Mux, t *testing.T){
|
|
|
+ validators: []func(c *userTest, tester *tester, t *testing.T){
|
|
|
ClusterBodyValidator,
|
|
|
},
|
|
|
},
|
|
|
}
|
|
|
|
|
|
func TestHandleReadUserClusters(t *testing.T) {
|
|
|
- for _, c := range readUserClustersTests {
|
|
|
- testUserRequest(t, c)
|
|
|
- }
|
|
|
+ testUserRequests(t, readUserClustersTests, true)
|
|
|
}
|
|
|
|
|
|
-var readUserClustersAllTests = []userTest{
|
|
|
- userTest{
|
|
|
- init: func(repo *repository.Repository) {
|
|
|
- repo.User.CreateUser(&models.User{
|
|
|
- Email: "belanger@getporter.dev",
|
|
|
- Password: "hello",
|
|
|
- Clusters: []models.ClusterConfig{},
|
|
|
- RawKubeConfig: []byte("apiVersion: v1\nkind: Config\npreferences: {}\ncurrent-context: default\nclusters:\n- cluster:\n server: https://localhost\n name: cluster-test\ncontexts:\n- context:\n cluster: cluster-test\n user: test-admin\n name: context-test\nusers:\n- name: test-admin"),
|
|
|
- })
|
|
|
+var readUserClustersAllTests = []*userTest{
|
|
|
+ &userTest{
|
|
|
+ initializers: []func(tester *tester){
|
|
|
+ initUserWithClusters,
|
|
|
},
|
|
|
msg: "Read user successful",
|
|
|
method: "GET",
|
|
|
@@ -317,19 +420,23 @@ var readUserClustersAllTests = []userTest{
|
|
|
body: "",
|
|
|
expStatus: http.StatusOK,
|
|
|
expBody: `[{"name":"cluster-test","server":"https://localhost","context":"context-test","user":"test-admin"}]`,
|
|
|
- canQuery: true,
|
|
|
- validators: []func(rr *httptest.ResponseRecorder, c userTest, r *chi.Mux, t *testing.T){
|
|
|
+ validators: []func(c *userTest, tester *tester, t *testing.T){
|
|
|
ClusterBodyValidator,
|
|
|
},
|
|
|
},
|
|
|
- userTest{
|
|
|
- init: func(repo *repository.Repository) {
|
|
|
- repo.User.CreateUser(&models.User{
|
|
|
- Email: "belanger@getporter.dev",
|
|
|
- Password: "hello",
|
|
|
- Clusters: []models.ClusterConfig{},
|
|
|
- RawKubeConfig: []byte("apiVersion: \xc5\n"),
|
|
|
- })
|
|
|
+ &userTest{
|
|
|
+ initializers: []func(tester *tester){
|
|
|
+ initUserWithClusters,
|
|
|
+ func(tester *tester) {
|
|
|
+ initUserDefault(tester)
|
|
|
+
|
|
|
+ user, _ := tester.repo.User.ReadUserByEmail("belanger@getporter.dev")
|
|
|
+ user.Clusters = []models.ClusterConfig{}
|
|
|
+ user.RawKubeConfig = []byte("apiVersion: \xc5\n")
|
|
|
+
|
|
|
+ tester.repo.User.UpdateUser(user)
|
|
|
+
|
|
|
+ },
|
|
|
},
|
|
|
msg: "Read user with invalid utf-8 \xc5 in kubeconfig",
|
|
|
method: "GET",
|
|
|
@@ -337,26 +444,20 @@ var readUserClustersAllTests = []userTest{
|
|
|
body: "",
|
|
|
expStatus: http.StatusBadRequest,
|
|
|
expBody: `{"code":600,"errors":["could not process request"]}`,
|
|
|
- canQuery: true,
|
|
|
- validators: []func(rr *httptest.ResponseRecorder, c userTest, r *chi.Mux, t *testing.T){
|
|
|
- BasicBodyValidator,
|
|
|
+ validators: []func(c *userTest, tester *tester, t *testing.T){
|
|
|
+ ClusterBodyValidator,
|
|
|
},
|
|
|
},
|
|
|
}
|
|
|
|
|
|
func TestHandleReadUserClustersAll(t *testing.T) {
|
|
|
- for _, c := range readUserClustersAllTests {
|
|
|
- testUserRequest(t, c)
|
|
|
- }
|
|
|
+ testUserRequests(t, readUserClustersAllTests, true)
|
|
|
}
|
|
|
|
|
|
-var updateUserTests = []userTest{
|
|
|
- userTest{
|
|
|
- init: func(repo *repository.Repository) {
|
|
|
- repo.User.CreateUser(&models.User{
|
|
|
- Email: "belanger@getporter.dev",
|
|
|
- Password: "hello",
|
|
|
- })
|
|
|
+var updateUserTests = []*userTest{
|
|
|
+ &userTest{
|
|
|
+ initializers: []func(tester *tester){
|
|
|
+ initUserDefault,
|
|
|
},
|
|
|
msg: "Update user successful",
|
|
|
method: "PUT",
|
|
|
@@ -364,9 +465,8 @@ var updateUserTests = []userTest{
|
|
|
body: `{"rawKubeConfig":"apiVersion: v1\nkind: Config\npreferences: {}\ncurrent-context: default\nclusters:\n- cluster:\n server: https://localhost\n name: cluster-test\ncontexts:\n- context:\n cluster: cluster-test\n user: test-admin\n name: context-test\nusers:\n- name: test-admin", "allowedClusters":[]}`,
|
|
|
expStatus: http.StatusNoContent,
|
|
|
expBody: "",
|
|
|
- canQuery: true,
|
|
|
- validators: []func(rr *httptest.ResponseRecorder, c userTest, r *chi.Mux, t *testing.T){
|
|
|
- func(rr *httptest.ResponseRecorder, c userTest, r *chi.Mux, t *testing.T) {
|
|
|
+ validators: []func(c *userTest, tester *tester, t *testing.T){
|
|
|
+ func(c *userTest, tester *tester, t *testing.T) {
|
|
|
req, err := http.NewRequest(
|
|
|
"GET",
|
|
|
"/api/users/1",
|
|
|
@@ -378,7 +478,7 @@ var updateUserTests = []userTest{
|
|
|
}
|
|
|
|
|
|
rr2 := httptest.NewRecorder()
|
|
|
- r.ServeHTTP(rr2, req)
|
|
|
+ tester.router.ServeHTTP(rr2, req)
|
|
|
|
|
|
gotBody := &models.UserExternal{}
|
|
|
expBody := &models.UserExternal{}
|
|
|
@@ -393,12 +493,9 @@ var updateUserTests = []userTest{
|
|
|
},
|
|
|
},
|
|
|
},
|
|
|
- userTest{
|
|
|
- init: func(repo *repository.Repository) {
|
|
|
- repo.User.CreateUser(&models.User{
|
|
|
- Email: "belanger@getporter.dev",
|
|
|
- Password: "hello",
|
|
|
- })
|
|
|
+ &userTest{
|
|
|
+ initializers: []func(tester *tester){
|
|
|
+ initUserDefault,
|
|
|
},
|
|
|
msg: "Update user invalid id",
|
|
|
method: "PUT",
|
|
|
@@ -406,17 +503,13 @@ var updateUserTests = []userTest{
|
|
|
body: `{"rawKubeConfig":"apiVersion: v1\nkind: Config\npreferences: {}\ncurrent-context: default\nclusters:\n- cluster:\n server: https://localhost\n name: cluster-test\ncontexts:\n- context:\n cluster: cluster-test\n user: test-admin\n name: context-test\nusers:\n- name: test-admin", "allowedClusters":[]}`,
|
|
|
expStatus: http.StatusBadRequest,
|
|
|
expBody: `{"code":600,"errors":["could not process request"]}`,
|
|
|
- canQuery: true,
|
|
|
- validators: []func(rr *httptest.ResponseRecorder, c userTest, r *chi.Mux, t *testing.T){
|
|
|
+ validators: []func(c *userTest, tester *tester, t *testing.T){
|
|
|
BasicBodyValidator,
|
|
|
},
|
|
|
},
|
|
|
- userTest{
|
|
|
- init: func(repo *repository.Repository) {
|
|
|
- repo.User.CreateUser(&models.User{
|
|
|
- Email: "belanger@getporter.dev",
|
|
|
- Password: "hello",
|
|
|
- })
|
|
|
+ &userTest{
|
|
|
+ initializers: []func(tester *tester){
|
|
|
+ initUserDefault,
|
|
|
},
|
|
|
msg: "Update user bad kubeconfig",
|
|
|
method: "PUT",
|
|
|
@@ -424,17 +517,20 @@ var updateUserTests = []userTest{
|
|
|
body: `{"rawKubeConfig":"notvalidyaml", "allowedClusters":[]}`,
|
|
|
expStatus: http.StatusBadRequest,
|
|
|
expBody: `{"code":600,"errors":["could not process request"]}`,
|
|
|
- canQuery: true,
|
|
|
- validators: []func(rr *httptest.ResponseRecorder, c userTest, r *chi.Mux, t *testing.T){
|
|
|
+ validators: []func(c *userTest, tester *tester, t *testing.T){
|
|
|
BasicBodyValidator,
|
|
|
},
|
|
|
},
|
|
|
- userTest{
|
|
|
- init: func(repo *repository.Repository) {
|
|
|
- repo.User.CreateUser(&models.User{
|
|
|
- Email: "belanger@getporter.dev",
|
|
|
- Password: "hello",
|
|
|
- })
|
|
|
+}
|
|
|
+
|
|
|
+func TestHandleUpdateUser(t *testing.T) {
|
|
|
+ testUserRequests(t, updateUserTests, true)
|
|
|
+}
|
|
|
+
|
|
|
+var updateUserTestsWriteFail = []*userTest{
|
|
|
+ &userTest{
|
|
|
+ initializers: []func(tester *tester){
|
|
|
+ initUserDefault,
|
|
|
},
|
|
|
msg: "Update user db connection down",
|
|
|
method: "PUT",
|
|
|
@@ -442,26 +538,20 @@ var updateUserTests = []userTest{
|
|
|
body: `{"rawKubeConfig":"apiVersion: v1\nkind: Config\npreferences: {}\ncurrent-context: default\nclusters:\n- cluster:\n server: https://localhost\n name: cluster-test\ncontexts:\n- context:\n cluster: cluster-test\n user: test-admin\n name: context-test\nusers:\n- name: test-admin", "allowedClusters":[]}`,
|
|
|
expStatus: http.StatusInternalServerError,
|
|
|
expBody: `{"code":500,"errors":["could not write to database"]}`,
|
|
|
- canQuery: false,
|
|
|
- validators: []func(rr *httptest.ResponseRecorder, c userTest, r *chi.Mux, t *testing.T){
|
|
|
+ validators: []func(c *userTest, tester *tester, t *testing.T){
|
|
|
BasicBodyValidator,
|
|
|
},
|
|
|
},
|
|
|
}
|
|
|
|
|
|
-func TestHandleUpdateUser(t *testing.T) {
|
|
|
- for _, c := range updateUserTests {
|
|
|
- testUserRequest(t, c)
|
|
|
- }
|
|
|
+func TestHandleUpdateUserWriteFail(t *testing.T) {
|
|
|
+ testUserRequests(t, updateUserTestsWriteFail, false)
|
|
|
}
|
|
|
|
|
|
-var deleteUserTests = []userTest{
|
|
|
- userTest{
|
|
|
- init: func(repo *repository.Repository) {
|
|
|
- repo.User.CreateUser(&models.User{
|
|
|
- Email: "belanger@getporter.dev",
|
|
|
- Password: "hello",
|
|
|
- })
|
|
|
+var deleteUserTests = []*userTest{
|
|
|
+ &userTest{
|
|
|
+ initializers: []func(tester *tester){
|
|
|
+ initUserDefault,
|
|
|
},
|
|
|
msg: "Delete user successful",
|
|
|
method: "DELETE",
|
|
|
@@ -469,9 +559,8 @@ var deleteUserTests = []userTest{
|
|
|
body: `{"password":"hello"}`,
|
|
|
expStatus: http.StatusNoContent,
|
|
|
expBody: "",
|
|
|
- canQuery: true,
|
|
|
- validators: []func(rr *httptest.ResponseRecorder, c userTest, r *chi.Mux, t *testing.T){
|
|
|
- func(rr *httptest.ResponseRecorder, c userTest, r *chi.Mux, t *testing.T) {
|
|
|
+ validators: []func(c *userTest, tester *tester, t *testing.T){
|
|
|
+ func(c *userTest, tester *tester, t *testing.T) {
|
|
|
req, err := http.NewRequest(
|
|
|
"GET",
|
|
|
"/api/users/1",
|
|
|
@@ -484,7 +573,7 @@ var deleteUserTests = []userTest{
|
|
|
|
|
|
rr2 := httptest.NewRecorder()
|
|
|
|
|
|
- r.ServeHTTP(rr2, req)
|
|
|
+ tester.router.ServeHTTP(rr2, req)
|
|
|
|
|
|
gotBody := &models.UserExternal{}
|
|
|
expBody := &models.UserExternal{}
|
|
|
@@ -504,12 +593,9 @@ var deleteUserTests = []userTest{
|
|
|
},
|
|
|
},
|
|
|
},
|
|
|
- userTest{
|
|
|
- init: func(repo *repository.Repository) {
|
|
|
- repo.User.CreateUser(&models.User{
|
|
|
- Email: "belanger@getporter.dev",
|
|
|
- Password: "hello",
|
|
|
- })
|
|
|
+ &userTest{
|
|
|
+ initializers: []func(tester *tester){
|
|
|
+ initUserDefault,
|
|
|
},
|
|
|
msg: "Delete user invalid id",
|
|
|
method: "DELETE",
|
|
|
@@ -517,17 +603,13 @@ var deleteUserTests = []userTest{
|
|
|
body: `{"password":"hello"}`,
|
|
|
expStatus: http.StatusBadRequest,
|
|
|
expBody: `{"code":600,"errors":["could not process request"]}`,
|
|
|
- canQuery: true,
|
|
|
- validators: []func(rr *httptest.ResponseRecorder, c userTest, r *chi.Mux, t *testing.T){
|
|
|
+ validators: []func(c *userTest, tester *tester, t *testing.T){
|
|
|
BasicBodyValidator,
|
|
|
},
|
|
|
},
|
|
|
- userTest{
|
|
|
- init: func(repo *repository.Repository) {
|
|
|
- repo.User.CreateUser(&models.User{
|
|
|
- Email: "belanger@getporter.dev",
|
|
|
- Password: "hello",
|
|
|
- })
|
|
|
+ &userTest{
|
|
|
+ initializers: []func(tester *tester){
|
|
|
+ initUserDefault,
|
|
|
},
|
|
|
msg: "Delete user missing password",
|
|
|
method: "DELETE",
|
|
|
@@ -535,31 +617,28 @@ var deleteUserTests = []userTest{
|
|
|
body: `{}`,
|
|
|
expStatus: http.StatusUnprocessableEntity,
|
|
|
expBody: `{"code":601,"errors":["required validation failed"]}`,
|
|
|
- canQuery: true,
|
|
|
- validators: []func(rr *httptest.ResponseRecorder, c userTest, r *chi.Mux, t *testing.T){
|
|
|
+ validators: []func(c *userTest, tester *tester, t *testing.T){
|
|
|
BasicBodyValidator,
|
|
|
},
|
|
|
},
|
|
|
}
|
|
|
|
|
|
func TestHandleDeleteUser(t *testing.T) {
|
|
|
- for _, c := range deleteUserTests {
|
|
|
- testUserRequest(t, c)
|
|
|
- }
|
|
|
+ testUserRequests(t, deleteUserTests, true)
|
|
|
}
|
|
|
|
|
|
-func BasicBodyValidator(rr *httptest.ResponseRecorder, c userTest, r *chi.Mux, t *testing.T) {
|
|
|
- if body := rr.Body.String(); body != c.expBody {
|
|
|
+func BasicBodyValidator(c *userTest, tester *tester, t *testing.T) {
|
|
|
+ if body := tester.rr.Body.String(); body != c.expBody {
|
|
|
t.Errorf("%s, handler returned wrong body: got %v want %v",
|
|
|
c.msg, body, c.expBody)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-func UserModelBodyValidator(rr *httptest.ResponseRecorder, c userTest, r *chi.Mux, t *testing.T) {
|
|
|
+func UserModelBodyValidator(c *userTest, tester *tester, t *testing.T) {
|
|
|
gotBody := &models.UserExternal{}
|
|
|
expBody := &models.UserExternal{}
|
|
|
|
|
|
- json.Unmarshal(rr.Body.Bytes(), gotBody)
|
|
|
+ json.Unmarshal(tester.rr.Body.Bytes(), gotBody)
|
|
|
json.Unmarshal([]byte(c.expBody), expBody)
|
|
|
|
|
|
if !reflect.DeepEqual(gotBody, expBody) {
|
|
|
@@ -568,12 +647,12 @@ func UserModelBodyValidator(rr *httptest.ResponseRecorder, c userTest, r *chi.Mu
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-func ClusterBodyValidator(rr *httptest.ResponseRecorder, c userTest, r *chi.Mux, t *testing.T) {
|
|
|
+func ClusterBodyValidator(c *userTest, tester *tester, t *testing.T) {
|
|
|
// if status is expected to be 200, parse the body for UserExternal
|
|
|
gotBody := &[]models.ClusterConfigExternal{}
|
|
|
expBody := &[]models.ClusterConfigExternal{}
|
|
|
|
|
|
- json.Unmarshal(rr.Body.Bytes(), gotBody)
|
|
|
+ json.Unmarshal(tester.rr.Body.Bytes(), gotBody)
|
|
|
json.Unmarshal([]byte(c.expBody), expBody)
|
|
|
|
|
|
if !reflect.DeepEqual(gotBody, expBody) {
|