user_handler_test.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  1. package api_test
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net/http"
  6. "net/http/httptest"
  7. "reflect"
  8. "strings"
  9. "testing"
  10. "time"
  11. "github.com/go-chi/chi"
  12. "github.com/porter-dev/porter/internal/config"
  13. "github.com/porter-dev/porter/internal/models"
  14. "github.com/porter-dev/porter/internal/repository"
  15. "github.com/porter-dev/porter/internal/repository/test"
  16. "github.com/porter-dev/porter/server/api"
  17. "github.com/porter-dev/porter/server/router"
  18. sessionstore "github.com/porter-dev/porter/internal/auth"
  19. lr "github.com/porter-dev/porter/internal/logger"
  20. vr "github.com/porter-dev/porter/internal/validator"
  21. )
  22. type tester struct {
  23. app *api.App
  24. repo *repository.Repository
  25. store *sessionstore.PGStore
  26. router *chi.Mux
  27. req *http.Request
  28. rr *httptest.ResponseRecorder
  29. cookie *http.Cookie
  30. }
  31. type userTest struct {
  32. initializers []func(t *tester)
  33. msg string
  34. method string
  35. endpoint string
  36. body string
  37. expStatus int
  38. expBody string
  39. useCookie bool
  40. validators []func(c *userTest, tester *tester, t *testing.T)
  41. }
  42. func (t *tester) execute() {
  43. t.router.ServeHTTP(t.rr, t.req)
  44. }
  45. func (t *tester) reset() {
  46. t.rr = httptest.NewRecorder()
  47. t.req = nil
  48. }
  49. func (t *tester) createUserSession(email string, pw string) {
  50. req, _ := http.NewRequest(
  51. "POST",
  52. "/api/users",
  53. strings.NewReader(`{"email":"`+email+`","password":"`+pw+`"}`),
  54. )
  55. t.req = req
  56. t.execute()
  57. if cookies := t.rr.Result().Cookies(); len(cookies) > 0 {
  58. t.cookie = cookies[0]
  59. }
  60. t.reset()
  61. }
  62. func initUserDefault(tester *tester) {
  63. tester.createUserSession("belanger@getporter.dev", "hello")
  64. }
  65. func initUserWithClusters(tester *tester) {
  66. initUserDefault(tester)
  67. user, _ := tester.repo.User.ReadUserByEmail("belanger@getporter.dev")
  68. user.Clusters = []models.ClusterConfig{
  69. models.ClusterConfig{
  70. Name: "cluster-test",
  71. Server: "https://localhost",
  72. Context: "context-test",
  73. User: "test-admin",
  74. },
  75. }
  76. user.RawKubeConfig = []byte("apiVersion: v1\nkind: Config\npreferences: {}\ncurrent-context: context-test\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")
  77. tester.repo.User.UpdateUser(user)
  78. }
  79. func newTester(canQuery bool) *tester {
  80. appConf := config.Conf{
  81. Debug: true,
  82. Server: config.ServerConf{
  83. Port: 8080,
  84. CookieName: "porter",
  85. CookieSecrets: [][]byte{[]byte("secret")},
  86. TimeoutRead: time.Second * 5,
  87. TimeoutWrite: time.Second * 10,
  88. TimeoutIdle: time.Second * 15,
  89. },
  90. // unimportant here
  91. Db: config.DBConf{},
  92. }
  93. logger := lr.NewConsole(appConf.Debug)
  94. validator := vr.New()
  95. repo := test.NewRepository(canQuery)
  96. store, _ := sessionstore.NewStore(repo, appConf.Server)
  97. app := api.New(logger, repo, validator, store, appConf.Server.CookieName)
  98. r := router.New(app, store, appConf.Server.CookieName)
  99. return &tester{
  100. app: app,
  101. repo: repo,
  102. store: store,
  103. router: r,
  104. req: nil,
  105. rr: httptest.NewRecorder(),
  106. cookie: nil,
  107. }
  108. }
  109. func testUserRequests(t *testing.T, tests []*userTest, canQuery bool) {
  110. for _, c := range tests {
  111. // create a new tester
  112. tester := newTester(canQuery)
  113. // if there's an initializer, call it
  114. for _, init := range c.initializers {
  115. init(tester)
  116. }
  117. req, err := http.NewRequest(
  118. c.method,
  119. c.endpoint,
  120. strings.NewReader(c.body),
  121. )
  122. tester.req = req
  123. if c.useCookie {
  124. req.AddCookie(tester.cookie)
  125. }
  126. if err != nil {
  127. t.Fatal(err)
  128. }
  129. tester.execute()
  130. rr := tester.rr
  131. // first, check that the status matches
  132. if status := rr.Code; status != c.expStatus {
  133. t.Errorf("%s, handler returned wrong status code: got %v want %v",
  134. c.msg, status, c.expStatus)
  135. }
  136. // if there's a validator, call it
  137. for _, validate := range c.validators {
  138. validate(c, tester, t)
  139. }
  140. }
  141. }
  142. var createUserTests = []*userTest{
  143. &userTest{
  144. msg: "Create user",
  145. method: "POST",
  146. endpoint: "/api/users",
  147. body: `{
  148. "email": "belanger@getporter.dev",
  149. "password": "hello"
  150. }`,
  151. expStatus: http.StatusCreated,
  152. expBody: "",
  153. },
  154. &userTest{
  155. msg: "Create user invalid email",
  156. method: "POST",
  157. endpoint: "/api/users",
  158. body: `{
  159. "email": "notanemail",
  160. "password": "hello"
  161. }`,
  162. expStatus: http.StatusUnprocessableEntity,
  163. expBody: `{"code":601,"errors":["email validation failed"]}`,
  164. validators: []func(c *userTest, tester *tester, t *testing.T){
  165. BasicBodyValidator,
  166. },
  167. },
  168. &userTest{
  169. msg: "Create user missing field",
  170. method: "POST",
  171. endpoint: "/api/users",
  172. body: `{
  173. "password": "hello"
  174. }`,
  175. expStatus: http.StatusUnprocessableEntity,
  176. expBody: `{"code":601,"errors":["required validation failed"]}`,
  177. validators: []func(c *userTest, tester *tester, t *testing.T){
  178. BasicBodyValidator,
  179. },
  180. },
  181. &userTest{
  182. initializers: []func(tester *tester){
  183. initUserDefault,
  184. },
  185. msg: "Create user same email",
  186. method: "POST",
  187. endpoint: "/api/users",
  188. body: `{
  189. "email": "belanger@getporter.dev",
  190. "password": "hello"
  191. }`,
  192. expStatus: http.StatusUnprocessableEntity,
  193. expBody: `{"code":601,"errors":["email already taken"]}`,
  194. validators: []func(c *userTest, tester *tester, t *testing.T){
  195. BasicBodyValidator,
  196. },
  197. },
  198. &userTest{
  199. msg: "Create user invalid field type",
  200. method: "POST",
  201. endpoint: "/api/users",
  202. body: `{
  203. "email": "belanger@getporter.dev",
  204. "password": 0
  205. }`,
  206. expStatus: http.StatusBadRequest,
  207. expBody: `{"code":600,"errors":["could not process request"]}`,
  208. validators: []func(c *userTest, tester *tester, t *testing.T){
  209. BasicBodyValidator,
  210. },
  211. },
  212. }
  213. func TestHandleCreateUser(t *testing.T) {
  214. testUserRequests(t, createUserTests, true)
  215. }
  216. var createUserTestsWriteFail = []*userTest{
  217. &userTest{
  218. msg: "Create user db connection down",
  219. method: "POST",
  220. endpoint: "/api/users",
  221. body: `{
  222. "email": "belanger@getporter.dev",
  223. "password": "hello"
  224. }`,
  225. expStatus: http.StatusInternalServerError,
  226. expBody: `{"code":500,"errors":["could not read from database"]}`,
  227. validators: []func(c *userTest, tester *tester, t *testing.T){
  228. BasicBodyValidator,
  229. },
  230. },
  231. }
  232. func TestHandleCreateUserWriteFail(t *testing.T) {
  233. testUserRequests(t, createUserTestsWriteFail, false)
  234. }
  235. var loginUserTests = []*userTest{
  236. &userTest{
  237. initializers: []func(tester *tester){
  238. initUserDefault,
  239. },
  240. msg: "Login user successful",
  241. method: "POST",
  242. endpoint: "/api/login",
  243. body: `{
  244. "email": "belanger@getporter.dev",
  245. "password": "hello"
  246. }`,
  247. expStatus: http.StatusOK,
  248. expBody: ``,
  249. validators: []func(c *userTest, tester *tester, t *testing.T){
  250. BasicBodyValidator,
  251. },
  252. },
  253. &userTest{
  254. initializers: []func(tester *tester){
  255. initUserDefault,
  256. },
  257. msg: "Login user already logged in",
  258. method: "POST",
  259. endpoint: "/api/login",
  260. body: `{
  261. "email": "belanger@getporter.dev",
  262. "password": "hello"
  263. }`,
  264. expStatus: http.StatusOK,
  265. expBody: ``,
  266. useCookie: true,
  267. validators: []func(c *userTest, tester *tester, t *testing.T){
  268. BasicBodyValidator,
  269. },
  270. },
  271. &userTest{
  272. msg: "Login user unregistered email",
  273. method: "POST",
  274. endpoint: "/api/login",
  275. body: `{
  276. "email": "belanger@getporter.dev",
  277. "password": "hello"
  278. }`,
  279. expStatus: http.StatusUnauthorized,
  280. expBody: `{"code":401,"errors":["email not registered"]}`,
  281. validators: []func(c *userTest, tester *tester, t *testing.T){
  282. BasicBodyValidator,
  283. },
  284. },
  285. &userTest{
  286. initializers: []func(tester *tester){
  287. initUserDefault,
  288. },
  289. msg: "Login user incorrect password",
  290. method: "POST",
  291. endpoint: "/api/login",
  292. body: `{
  293. "email": "belanger@getporter.dev",
  294. "password": "notthepassword"
  295. }`,
  296. expStatus: http.StatusUnauthorized,
  297. expBody: `{"code":401,"errors":["incorrect password"]}`,
  298. useCookie: true,
  299. validators: []func(c *userTest, tester *tester, t *testing.T){
  300. BasicBodyValidator,
  301. },
  302. },
  303. }
  304. func TestHandleLoginUser(t *testing.T) {
  305. testUserRequests(t, loginUserTests, true)
  306. }
  307. var logoutUserTests = []*userTest{
  308. &userTest{
  309. initializers: []func(tester *tester){
  310. initUserDefault,
  311. },
  312. msg: "Logout user successful",
  313. method: "POST",
  314. endpoint: "/api/logout",
  315. body: `{
  316. "email": "belanger@getporter.dev",
  317. "password": "hello"
  318. }`,
  319. expStatus: http.StatusOK,
  320. expBody: ``,
  321. useCookie: true,
  322. validators: []func(c *userTest, tester *tester, t *testing.T){
  323. func(c *userTest, tester *tester, t *testing.T) {
  324. req, err := http.NewRequest(
  325. "GET",
  326. "/api/users/1",
  327. strings.NewReader(""),
  328. )
  329. req.AddCookie(tester.cookie)
  330. if err != nil {
  331. t.Fatal(err)
  332. }
  333. rr2 := httptest.NewRecorder()
  334. tester.router.ServeHTTP(rr2, req)
  335. if status := rr2.Code; status != http.StatusForbidden {
  336. t.Errorf("%s, handler returned wrong status: got %v want %v",
  337. "validator failed", status, http.StatusForbidden)
  338. }
  339. },
  340. },
  341. },
  342. }
  343. func TestHandleLogoutUser(t *testing.T) {
  344. testUserRequests(t, logoutUserTests, true)
  345. }
  346. var readUserTests = []*userTest{
  347. &userTest{
  348. initializers: []func(tester *tester){
  349. initUserWithClusters,
  350. },
  351. msg: "Read user successful",
  352. method: "GET",
  353. endpoint: "/api/users/1",
  354. body: "",
  355. expStatus: http.StatusOK,
  356. 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: context-test\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"}`,
  357. useCookie: true,
  358. validators: []func(c *userTest, tester *tester, t *testing.T){
  359. UserModelBodyValidator,
  360. },
  361. },
  362. &userTest{
  363. initializers: []func(tester *tester){
  364. initUserDefault,
  365. },
  366. msg: "Read user unauthorized",
  367. method: "GET",
  368. endpoint: "/api/users/2",
  369. body: "",
  370. expStatus: http.StatusForbidden,
  371. expBody: http.StatusText(http.StatusForbidden) + "\n",
  372. validators: []func(c *userTest, tester *tester, t *testing.T){
  373. BasicBodyValidator,
  374. },
  375. },
  376. }
  377. func TestHandleReadUser(t *testing.T) {
  378. testUserRequests(t, readUserTests, true)
  379. }
  380. var readUserClustersTests = []*userTest{
  381. &userTest{
  382. initializers: []func(tester *tester){
  383. initUserWithClusters,
  384. },
  385. msg: "Read user successful",
  386. method: "GET",
  387. endpoint: "/api/users/1/clusters",
  388. body: "",
  389. expStatus: http.StatusOK,
  390. useCookie: true,
  391. expBody: `[{"name":"cluster-test","server":"https://localhost","context":"context-test","user":"test-admin"}]`,
  392. validators: []func(c *userTest, tester *tester, t *testing.T){
  393. ClusterBodyValidator,
  394. },
  395. },
  396. }
  397. func TestHandleReadUserClusters(t *testing.T) {
  398. testUserRequests(t, readUserClustersTests, true)
  399. }
  400. var readUserClustersAllTests = []*userTest{
  401. &userTest{
  402. initializers: []func(tester *tester){
  403. initUserWithClusters,
  404. },
  405. msg: "Read user successful",
  406. method: "GET",
  407. endpoint: "/api/users/1/clusters/all",
  408. body: "",
  409. expStatus: http.StatusOK,
  410. useCookie: true,
  411. expBody: `[{"name":"cluster-test","server":"https://localhost","context":"context-test","user":"test-admin"}]`,
  412. validators: []func(c *userTest, tester *tester, t *testing.T){
  413. ClusterBodyValidator,
  414. },
  415. },
  416. &userTest{
  417. initializers: []func(tester *tester){
  418. initUserWithClusters,
  419. func(tester *tester) {
  420. initUserDefault(tester)
  421. user, _ := tester.repo.User.ReadUserByEmail("belanger@getporter.dev")
  422. user.Clusters = []models.ClusterConfig{}
  423. user.RawKubeConfig = []byte("apiVersion: \xc5\n")
  424. tester.repo.User.UpdateUser(user)
  425. },
  426. },
  427. msg: "Read user with invalid utf-8 \xc5 in kubeconfig",
  428. method: "GET",
  429. endpoint: "/api/users/1/clusters/all",
  430. body: "",
  431. expStatus: http.StatusBadRequest,
  432. useCookie: true,
  433. expBody: `{"code":600,"errors":["could not process request"]}`,
  434. validators: []func(c *userTest, tester *tester, t *testing.T){
  435. ClusterBodyValidator,
  436. },
  437. },
  438. }
  439. func TestHandleReadUserClustersAll(t *testing.T) {
  440. testUserRequests(t, readUserClustersAllTests, true)
  441. }
  442. var updateUserTests = []*userTest{
  443. &userTest{
  444. initializers: []func(tester *tester){
  445. initUserDefault,
  446. },
  447. msg: "Update user successful",
  448. method: "PUT",
  449. endpoint: "/api/users/1",
  450. body: `{"rawKubeConfig":"apiVersion: v1\nkind: Config\npreferences: {}\ncurrent-context: context-test\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":[]}`,
  451. expStatus: http.StatusNoContent,
  452. expBody: "",
  453. useCookie: true,
  454. validators: []func(c *userTest, tester *tester, t *testing.T){
  455. func(c *userTest, tester *tester, t *testing.T) {
  456. req, err := http.NewRequest(
  457. "GET",
  458. "/api/users/1",
  459. strings.NewReader(""),
  460. )
  461. req.AddCookie(tester.cookie)
  462. if err != nil {
  463. t.Fatal(err)
  464. }
  465. rr2 := httptest.NewRecorder()
  466. tester.router.ServeHTTP(rr2, req)
  467. gotBody := &models.UserExternal{}
  468. expBody := &models.UserExternal{}
  469. json.Unmarshal(rr2.Body.Bytes(), gotBody)
  470. json.Unmarshal([]byte(`{"id":1,"email":"belanger@getporter.dev","clusters":[],"rawKubeConfig":"apiVersion: v1\nkind: Config\npreferences: {}\ncurrent-context: context-test\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"}`), expBody)
  471. if !reflect.DeepEqual(gotBody, expBody) {
  472. t.Errorf("%s, handler returned wrong body: got %v want %v",
  473. "validator failed", gotBody, expBody)
  474. }
  475. },
  476. },
  477. },
  478. &userTest{
  479. initializers: []func(tester *tester){
  480. initUserDefault,
  481. },
  482. msg: "Update user successful without allowedClusters parameter",
  483. method: "PUT",
  484. endpoint: "/api/users/1",
  485. body: `{"rawKubeConfig":"apiVersion: v1\nkind: Config\npreferences: {}\ncurrent-context: context-test\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"}`,
  486. expStatus: http.StatusNoContent,
  487. expBody: "",
  488. useCookie: true,
  489. validators: []func(c *userTest, tester *tester, t *testing.T){
  490. func(c *userTest, tester *tester, t *testing.T) {
  491. req, err := http.NewRequest(
  492. "GET",
  493. "/api/users/1",
  494. strings.NewReader(""),
  495. )
  496. req.AddCookie(tester.cookie)
  497. if err != nil {
  498. t.Fatal(err)
  499. }
  500. rr2 := httptest.NewRecorder()
  501. tester.router.ServeHTTP(rr2, req)
  502. gotBody := &models.UserExternal{}
  503. expBody := &models.UserExternal{}
  504. json.Unmarshal(rr2.Body.Bytes(), gotBody)
  505. json.Unmarshal([]byte(`{"id":1,"email":"belanger@getporter.dev","clusters":[],"rawKubeConfig":"apiVersion: v1\nkind: Config\npreferences: {}\ncurrent-context: context-test\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"}`), expBody)
  506. if !reflect.DeepEqual(gotBody, expBody) {
  507. t.Errorf("%s, handler returned wrong body: got %v want %v",
  508. "validator failed", gotBody, expBody)
  509. }
  510. },
  511. },
  512. },
  513. &userTest{
  514. initializers: []func(tester *tester){
  515. initUserDefault,
  516. },
  517. msg: "Update user successful with allowedClusters",
  518. method: "PUT",
  519. endpoint: "/api/users/1",
  520. body: `{"rawKubeConfig":"apiVersion: v1\nkind: Config\npreferences: {}\ncurrent-context: context-test\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":["cluster-test"]}`,
  521. expStatus: http.StatusNoContent,
  522. expBody: "",
  523. useCookie: true,
  524. validators: []func(c *userTest, tester *tester, t *testing.T){
  525. func(c *userTest, tester *tester, t *testing.T) {
  526. req, err := http.NewRequest(
  527. "GET",
  528. "/api/users/1",
  529. strings.NewReader(""),
  530. )
  531. req.AddCookie(tester.cookie)
  532. if err != nil {
  533. t.Fatal(err)
  534. }
  535. rr2 := httptest.NewRecorder()
  536. tester.router.ServeHTTP(rr2, req)
  537. gotBody := &models.UserExternal{}
  538. expBody := &models.UserExternal{}
  539. json.Unmarshal(rr2.Body.Bytes(), gotBody)
  540. json.Unmarshal([]byte(`{"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: context-test\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"}`), expBody)
  541. fmt.Println(gotBody.Clusters[0], expBody.Clusters[0])
  542. if !reflect.DeepEqual(gotBody, expBody) {
  543. t.Errorf("%s, handler returned wrong body: got %v want %v",
  544. "validator failed", gotBody, expBody)
  545. }
  546. },
  547. },
  548. },
  549. &userTest{
  550. initializers: []func(tester *tester){
  551. initUserDefault,
  552. },
  553. msg: "Update user invalid id",
  554. method: "PUT",
  555. endpoint: "/api/users/alsdfjk",
  556. body: `{"rawKubeConfig":"apiVersion: v1\nkind: Config\npreferences: {}\ncurrent-context: context-test\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":[]}`,
  557. expStatus: http.StatusForbidden,
  558. expBody: http.StatusText(http.StatusForbidden) + "\n",
  559. validators: []func(c *userTest, tester *tester, t *testing.T){
  560. BasicBodyValidator,
  561. },
  562. },
  563. &userTest{
  564. initializers: []func(tester *tester){
  565. initUserDefault,
  566. },
  567. msg: "Update user bad kubeconfig",
  568. method: "PUT",
  569. endpoint: "/api/users/1",
  570. body: `{"rawKubeConfig":"notvalidyaml", "allowedClusters":[]}`,
  571. expStatus: http.StatusBadRequest,
  572. expBody: `{"code":600,"errors":["could not process request"]}`,
  573. useCookie: true,
  574. validators: []func(c *userTest, tester *tester, t *testing.T){
  575. BasicBodyValidator,
  576. },
  577. },
  578. }
  579. func TestHandleUpdateUser(t *testing.T) {
  580. testUserRequests(t, updateUserTests, true)
  581. }
  582. var deleteUserTests = []*userTest{
  583. &userTest{
  584. initializers: []func(tester *tester){
  585. initUserDefault,
  586. },
  587. msg: "Delete user successful",
  588. method: "DELETE",
  589. endpoint: "/api/users/1",
  590. body: `{"password":"hello"}`,
  591. expStatus: http.StatusNoContent,
  592. expBody: "",
  593. useCookie: true,
  594. validators: []func(c *userTest, tester *tester, t *testing.T){
  595. func(c *userTest, tester *tester, t *testing.T) {
  596. req, err := http.NewRequest(
  597. "GET",
  598. "/api/users/1",
  599. strings.NewReader(""),
  600. )
  601. req.AddCookie(tester.cookie)
  602. if err != nil {
  603. t.Fatal(err)
  604. }
  605. rr2 := httptest.NewRecorder()
  606. tester.router.ServeHTTP(rr2, req)
  607. gotBody := &models.UserExternal{}
  608. expBody := &models.UserExternal{}
  609. if status := rr2.Code; status != 404 {
  610. t.Errorf("DELETE user validation, handler returned wrong status code: got %v want %v",
  611. status, 404)
  612. }
  613. json.Unmarshal(rr2.Body.Bytes(), gotBody)
  614. json.Unmarshal([]byte(`{"code":602,"errors":["could not find requested object"]}`), expBody)
  615. if !reflect.DeepEqual(gotBody, expBody) {
  616. t.Errorf("%s, handler returned wrong body: got %v want %v",
  617. "validator failed", gotBody, expBody)
  618. }
  619. },
  620. },
  621. },
  622. &userTest{
  623. initializers: []func(tester *tester){
  624. initUserDefault,
  625. },
  626. msg: "Delete user invalid id",
  627. method: "DELETE",
  628. endpoint: "/api/users/aldkjf",
  629. body: `{"password":"hello"}`,
  630. expStatus: http.StatusForbidden,
  631. expBody: http.StatusText(http.StatusForbidden) + "\n",
  632. validators: []func(c *userTest, tester *tester, t *testing.T){
  633. BasicBodyValidator,
  634. },
  635. },
  636. &userTest{
  637. initializers: []func(tester *tester){
  638. initUserDefault,
  639. },
  640. msg: "Delete user missing password",
  641. method: "DELETE",
  642. endpoint: "/api/users/1",
  643. body: `{}`,
  644. expStatus: http.StatusUnprocessableEntity,
  645. expBody: `{"code":601,"errors":["required validation failed"]}`,
  646. useCookie: true,
  647. validators: []func(c *userTest, tester *tester, t *testing.T){
  648. BasicBodyValidator,
  649. },
  650. },
  651. }
  652. func TestHandleDeleteUser(t *testing.T) {
  653. testUserRequests(t, deleteUserTests, true)
  654. }
  655. func BasicBodyValidator(c *userTest, tester *tester, t *testing.T) {
  656. if body := tester.rr.Body.String(); body != c.expBody {
  657. t.Errorf("%s, handler returned wrong body: got %v want %v",
  658. c.msg, body, c.expBody)
  659. }
  660. }
  661. func UserModelBodyValidator(c *userTest, tester *tester, t *testing.T) {
  662. gotBody := &models.UserExternal{}
  663. expBody := &models.UserExternal{}
  664. json.Unmarshal(tester.rr.Body.Bytes(), gotBody)
  665. json.Unmarshal([]byte(c.expBody), expBody)
  666. if !reflect.DeepEqual(gotBody, expBody) {
  667. t.Errorf("%s, handler returned wrong body: got %v want %v",
  668. c.msg, gotBody, expBody)
  669. }
  670. }
  671. func ClusterBodyValidator(c *userTest, tester *tester, t *testing.T) {
  672. // if status is expected to be 200, parse the body for UserExternal
  673. gotBody := &[]models.ClusterConfigExternal{}
  674. expBody := &[]models.ClusterConfigExternal{}
  675. json.Unmarshal(tester.rr.Body.Bytes(), gotBody)
  676. json.Unmarshal([]byte(c.expBody), expBody)
  677. if !reflect.DeepEqual(gotBody, expBody) {
  678. t.Errorf("%s, handler returned wrong body: got %v want %v",
  679. c.msg, gotBody, expBody)
  680. }
  681. }