diff --git a/app/rest/api/admin_test.go b/app/rest/api/admin_test.go index e874a3a7..a9c66188 100644 --- a/app/rest/api/admin_test.go +++ b/app/rest/api/admin_test.go @@ -10,33 +10,32 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/umputun/remark/app/store" ) func TestAdmin_Delete(t *testing.T) { - srv, port := prep(t) + srv, ts := prep(t) assert.NotNil(t, srv) - defer cleanup(srv) + defer cleanup(ts) c1 := store.Comment{Text: "test test #1", User: store.User{ID: "id", Name: "name"}, Locator: store.Locator{SiteID: "radio-t", URL: "https://radio-t.com/blah"}} c2 := store.Comment{Text: "test test #2", User: store.User{ID: "id", Name: "name"}, ParentID: "p1", Locator: store.Locator{SiteID: "radio-t", URL: "https://radio-t.com/blah"}} - id1 := addComment(t, c1, port) - addComment(t, c2, port) + id1 := addComment(t, c1, ts) + addComment(t, c2, ts) client := http.Client{} req, err := http.NewRequest(http.MethodDelete, - fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/admin/comment/%s?site=radio-t&url=https://radio-t.com/blah", - port, id1), nil) + fmt.Sprintf("%s/api/v1/admin/comment/%s?site=radio-t&url=https://radio-t.com/blah", ts.URL, id1), nil) assert.Nil(t, err) + withBasicAuth(req, "dev", "password") resp, err := client.Do(req) assert.Nil(t, err) assert.Equal(t, 200, resp.StatusCode) - body, code := get(t, fmt.Sprintf("http://127.0.0.1:%d/api/v1/id/%s?site=radio-t&url=https://radio-t.com/blah", port, id1)) + body, code := getWithAuth(t, fmt.Sprintf("%s/api/v1/id/%s?site=radio-t&url=https://radio-t.com/blah", ts.URL, id1)) assert.Equal(t, 200, code) cr := store.Comment{} err = json.Unmarshal([]byte(body), &cr) @@ -46,23 +45,24 @@ func TestAdmin_Delete(t *testing.T) { } func TestAdmin_Pin(t *testing.T) { - srv, port := prep(t) + srv, ts := prep(t) assert.NotNil(t, srv) - defer cleanup(srv) + defer cleanup(ts) c1 := store.Comment{Text: "test test #1", Locator: store.Locator{SiteID: "radio-t", URL: "https://radio-t.com/blah"}} c2 := store.Comment{Text: "test test #2", ParentID: "p1", Locator: store.Locator{SiteID: "radio-t", URL: "https://radio-t.com/blah"}} - id1 := addComment(t, c1, port) - addComment(t, c2, port) + id1 := addComment(t, c1, ts) + addComment(t, c2, ts) pin := func(val int) int { client := http.Client{} req, err := http.NewRequest(http.MethodPut, - fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/admin/pin/%s?site=radio-t&url=https://radio-t.com/blah&pin=%d", port, id1, val), nil) + fmt.Sprintf("%s/api/v1/admin/pin/%s?site=radio-t&url=https://radio-t.com/blah&pin=%d", ts.URL, id1, val), nil) assert.Nil(t, err) + withBasicAuth(req, "dev", "password") resp, err := client.Do(req) assert.Nil(t, err) return resp.StatusCode @@ -71,7 +71,7 @@ func TestAdmin_Pin(t *testing.T) { code := pin(1) assert.Equal(t, 200, code) - body, code := get(t, fmt.Sprintf("http://127.0.0.1:%d/api/v1/id/%s?site=radio-t&url=https://radio-t.com/blah", port, id1)) + body, code := get(t, fmt.Sprintf("%s/api/v1/id/%s?site=radio-t&url=https://radio-t.com/blah", ts.URL, id1)) assert.Equal(t, 200, code) cr := store.Comment{} err := json.Unmarshal([]byte(body), &cr) @@ -80,7 +80,7 @@ func TestAdmin_Pin(t *testing.T) { code = pin(-1) assert.Equal(t, 200, code) - body, code = get(t, fmt.Sprintf("http://127.0.0.1:%d/api/v1/id/%s?site=radio-t&url=https://radio-t.com/blah", port, id1)) + body, code = get(t, fmt.Sprintf("%s/api/v1/id/%s?site=radio-t&url=https://radio-t.com/blah", ts.URL, id1)) assert.Equal(t, 200, code) cr = store.Comment{} err = json.Unmarshal([]byte(body), &cr) @@ -89,14 +89,14 @@ func TestAdmin_Pin(t *testing.T) { } func TestAdmin_Block(t *testing.T) { - srv, port := prep(t) + srv, ts := prep(t) assert.NotNil(t, srv) - defer cleanup(srv) + defer cleanup(ts) - c1 := store.Comment{Text: "test test #1", - Locator: store.Locator{SiteID: "radio-t", URL: "https://radio-t.com/blah"}, User: store.User{Name: "user1 name", ID: "user1"}} - c2 := store.Comment{Text: "test test #2", ParentID: "p1", - Locator: store.Locator{SiteID: "radio-t", URL: "https://radio-t.com/blah"}, User: store.User{Name: "user2", ID: "user2"}} + c1 := store.Comment{Text: "test test #1", Locator: store.Locator{SiteID: "radio-t", + URL: "https://radio-t.com/blah"}, User: store.User{Name: "user1 name", ID: "user1"}} + c2 := store.Comment{Text: "test test #2", ParentID: "p1", Locator: store.Locator{SiteID: "radio-t", + URL: "https://radio-t.com/blah"}, User: store.User{Name: "user2", ID: "user2"}} _, err := srv.DataService.Create(c1) assert.Nil(t, err) @@ -106,8 +106,9 @@ func TestAdmin_Block(t *testing.T) { block := func(val int) (code int, body []byte) { client := http.Client{} req, e := http.NewRequest(http.MethodPut, - fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/admin/user/%s?site=radio-t&block=%d", port, "user1", val), nil) + fmt.Sprintf("%s/api/v1/admin/user/%s?site=radio-t&block=%d", ts.URL, "user1", val), nil) assert.Nil(t, e) + withBasicAuth(req, "dev", "password") resp, e := client.Do(req) require.Nil(t, e) body, e = ioutil.ReadAll(resp.Body) @@ -125,7 +126,7 @@ func TestAdmin_Block(t *testing.T) { assert.Equal(t, true, j["block"]) assert.Equal(t, "radio-t", j["site_id"]) - res, code := get(t, fmt.Sprintf("http://127.0.0.1:%d/api/v1/find?site=radio-t&url=https://radio-t.com/blah&sort=+time", port)) + res, code := get(t, ts.URL+"/api/v1/find?site=radio-t&url=https://radio-t.com/blah&sort=+time") assert.Equal(t, 200, code) comments := []store.Comment{} err = json.Unmarshal([]byte(res), &comments) @@ -142,27 +143,29 @@ func TestAdmin_Block(t *testing.T) { } func TestAdmin_BlockedList(t *testing.T) { - srv, port := prep(t) + srv, ts := prep(t) assert.NotNil(t, srv) - defer cleanup(srv) + defer cleanup(ts) client := http.Client{} // block user1 req, err := http.NewRequest(http.MethodPut, - fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/admin/user/%s?site=radio-t&block=%d", port, "user1", 1), nil) + fmt.Sprintf("%s/api/v1/admin/user/%s?site=radio-t&block=%d", ts.URL, "user1", 1), nil) assert.Nil(t, err) + withBasicAuth(req, "dev", "password") _, err = client.Do(req) require.Nil(t, err) // block user2 req, err = http.NewRequest(http.MethodPut, - fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/admin/user/%s?site=radio-t&block=%d", port, "user2", 1), nil) + fmt.Sprintf("%s/api/v1/admin/user/%s?site=radio-t&block=%d", ts.URL, "user2", 1), nil) assert.Nil(t, err) + withBasicAuth(req, "dev", "password") _, err = client.Do(req) require.Nil(t, err) - res, code := get(t, fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/admin/blocked?site=radio-t", port)) + res, code := getWithAuth(t, ts.URL+"/api/v1/admin/blocked?site=radio-t") require.Equal(t, 200, code, res) users := []store.BlockedUser{} err = json.Unmarshal([]byte(res), &users) @@ -173,19 +176,19 @@ func TestAdmin_BlockedList(t *testing.T) { } func TestAdmin_Export(t *testing.T) { - srv, port := prep(t) + srv, ts := prep(t) assert.NotNil(t, srv) - defer cleanup(srv) + defer cleanup(ts) c1 := store.Comment{Text: "test test #1", Locator: store.Locator{SiteID: "radio-t", URL: "https://radio-t.com/blah1"}} c2 := store.Comment{Text: "test test #2", ParentID: "p1", Locator: store.Locator{SiteID: "radio-t", URL: "https://radio-t.com/blah2"}} - addComment(t, c1, port) - addComment(t, c2, port) + addComment(t, c1, ts) + addComment(t, c2, ts) - body, code := get(t, fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/admin/export?site=radio-t&mode=stream", port)) + body, code := getWithAuth(t, ts.URL+"/api/v1/admin/export?site=radio-t&mode=stream") assert.Equal(t, 200, code) assert.Equal(t, 2, strings.Count(body, "\n")) assert.Equal(t, 2, strings.Count(body, "\"text\"")) diff --git a/app/rest/api/import.go b/app/rest/api/import.go index 6945bd23..2f34da6d 100644 --- a/app/rest/api/import.go +++ b/app/rest/api/import.go @@ -24,26 +24,26 @@ type Import struct { NativeImporter migrator.Importer DisqusImporter migrator.Importer SecretKey string - - httpServer *http.Server } // Run the listener and request's router, activate rest server // this server doesn't have any authentication and SHOULDN'T BE EXPOSED in any way func (s *Import) Run(port int) { log.Printf("[INFO] activate import server on port %d", port) + router := s.routes() + httpServer := &http.Server{Addr: fmt.Sprintf("127.0.0.1:%d", port), Handler: router} + err := httpServer.ListenAndServe() + log.Printf("[WARN] http server terminated, %s", err) +} +func (s Import) routes() chi.Router { router := chi.NewRouter() router.Use(middleware.RealIP, Recoverer) router.Use(middleware.Throttle(1000), middleware.Timeout(60*time.Second)) router.Use(tollbooth_chi.LimitHandler(tollbooth.NewLimiter(10, nil))) router.Use(AppInfo("remark42-importer", s.Version), Ping, Logger(LogAll)) - router.Post("/api/v1/admin/import", s.importCtrl) - - s.httpServer = &http.Server{Addr: fmt.Sprintf("127.0.0.1:%d", port), Handler: router} - err := s.httpServer.ListenAndServe() - log.Printf("[WARN] http server terminated, %s", err) + return router } // POST /import?secret=key&site=site-id&provider=disqus|remark diff --git a/app/rest/api/import_test.go b/app/rest/api/import_test.go index 96600595..6d6e06e4 100644 --- a/app/rest/api/import_test.go +++ b/app/rest/api/import_test.go @@ -1,11 +1,9 @@ package api import ( - "context" - "fmt" "io/ioutil" - "math/rand" "net/http" + "net/http/httptest" "os" "strings" "testing" @@ -21,16 +19,17 @@ import ( ) func TestImport(t *testing.T) { - srv, port := prepImportSrv(t) + srv, ts := prepImportSrv(t) assert.NotNil(t, srv) - defer cleanupImportSrv(srv) + defer cleanupImportSrv(srv, ts) r := strings.NewReader(`{"id":"2aa0478c-df1b-46b1-b561-03d507cf482c","pid":"","text":"

test test #1

","user":{"name":"developer one","id":"dev","picture":"/api/v1/avatar/remark.image","profile":"https://remark42.com","admin":true,"ip":"ae12fe3b5f129b5cc4cdd2b136b7b7947c4d2741"},"locator":{"site":"radio-t","url":"https://radio-t.com/blah1"},"score":0,"votes":{},"time":"2018-04-30T01:37:00.849053725-05:00"} {"id":"83fd97fd-ff64-48d1-9fb7-ca7769c77037","pid":"p1","text":"

test test #2

","user":{"name":"developer one","id":"dev","picture":"/api/v1/avatar/remark.image","profile":"https://remark42.com","admin":true,"ip":"ae12fe3b5f129b5cc4cdd2b136b7b7947c4d2741"},"locator":{"site":"radio-t","url":"https://radio-t.com/blah2"},"score":0,"votes":{},"time":"2018-04-30T01:37:00.861387771-05:00"}`) - resp, err := http.Post(fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/admin/import?site=radio-t&provider=native&secret=123456", - port), "application/json", r) + client := &http.Client{Timeout: 1 * time.Second} + req, err := http.NewRequest("POST", ts.URL+"/api/v1/admin/import?site=radio-t&provider=native&secret=123456", r) assert.Nil(t, err) + resp, err := client.Do(req) assert.Equal(t, http.StatusCreated, resp.StatusCode) b, err := ioutil.ReadAll(resp.Body) @@ -39,46 +38,38 @@ func TestImport(t *testing.T) { } func TestImportRejected(t *testing.T) { - srv, port := prepImportSrv(t) + srv, ts := prepImportSrv(t) assert.NotNil(t, srv) - defer cleanupImportSrv(srv) + defer cleanupImportSrv(srv, ts) r := strings.NewReader(`{"id":"2aa0478c-df1b-46b1-b561-03d507cf482c","pid":"","text":"

test test #1

","user":{"name":"developer one","id":"dev","picture":"/api/v1/avatar/remark.image","profile":"https://remark42.com","admin":true,"ip":"ae12fe3b5f129b5cc4cdd2b136b7b7947c4d2741"},"locator":{"site":"radio-t","url":"https://radio-t.com/blah1"},"score":0,"votes":{},"time":"2018-04-30T01:37:00.849053725-05:00"} {"id":"83fd97fd-ff64-48d1-9fb7-ca7769c77037","pid":"p1","text":"

test test #2

","user":{"name":"developer one","id":"dev","picture":"/api/v1/avatar/remark.image","profile":"https://remark42.com","admin":true,"ip":"ae12fe3b5f129b5cc4cdd2b136b7b7947c4d2741"},"locator":{"site":"radio-t","url":"https://radio-t.com/blah2"},"score":0,"votes":{},"time":"2018-04-30T01:37:00.861387771-05:00"}`) - resp, err := http.Post(fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/admin/import?site=radio-t&provider=native&secret=badkey", - port), "application/json", r) + client := &http.Client{Timeout: 1 * time.Second} + req, err := http.NewRequest("POST", ts.URL+"/api/v1/admin/import?site=radio-t&provider=native&secret=XYZ", r) + assert.Nil(t, err) + resp, err := client.Do(req) assert.Nil(t, err) assert.Equal(t, http.StatusForbidden, resp.StatusCode) } -func prepImportSrv(t *testing.T) (srv *Import, port int) { +func prepImportSrv(t *testing.T) (svc *Import, ts *httptest.Server) { b, err := engine.NewBoltDB(bolt.Options{}, engine.BoltSite{FileName: testDb, SiteID: "radio-t"}) require.Nil(t, err) dataStore := &service.DataStore{Interface: b} - srv = &Import{ + svc = &Import{ DisqusImporter: &migrator.Disqus{DataStore: dataStore}, NativeImporter: &migrator.Remark{DataStore: dataStore}, Cache: &mockCache{}, SecretKey: "123456", } - portSetCh := make(chan bool) - - go func() { - port = rand.Intn(50000) + 1025 - portSetCh <- true - srv.Run(port) - }() - - <-portSetCh - - time.Sleep(100 * time.Millisecond) - return srv, port + routes := svc.routes() + ts = httptest.NewServer(routes) + return svc, ts } -func cleanupImportSrv(srv *Import) { - srv.httpServer.Close() - srv.httpServer.Shutdown(context.Background()) +func cleanupImportSrv(srv *Import, ts *httptest.Server) { + ts.Close() os.Remove(testDb) } diff --git a/app/rest/api/rest.go b/app/rest/api/rest.go index 20ece30e..2c87f4cc 100644 --- a/app/rest/api/rest.go +++ b/app/rest/api/rest.go @@ -60,18 +60,32 @@ func (s *Rest) Run(port int) { log.Printf("[DEBUG] admins %+v", s.Authenticator.Admins) } - s.adminService = admin{ - dataService: s.DataService, - exporter: s.Exporter, - cache: s.Cache, - } + router := s.routes() + s.httpServer = &http.Server{ + Addr: fmt.Sprintf(":%d", port), + Handler: router, + ReadHeaderTimeout: 5 * time.Second, + WriteTimeout: 5 * time.Second, + IdleTimeout: 30 * time.Second, + } + err := s.httpServer.ListenAndServe() + log.Printf("[WARN] http server terminated, %s", err) +} + +func (s *Rest) routes() chi.Router { router := chi.NewRouter() router.Use(middleware.RealIP, Recoverer) router.Use(middleware.Throttle(1000), middleware.Timeout(60*time.Second)) router.Use(AppInfo("remark42", s.Version), Ping) router.Use(context.ClearHandler) // if you aren't using gorilla/mux, you need to wrap your handlers with context.ClearHandler + s.adminService = admin{ + dataService: s.DataService, + exporter: s.Exporter, + cache: s.Cache, + } + // auth routes for all providers router.Route("/auth", func(r chi.Router) { r.Use(Logger(LogAll), tollbooth_chi.LimitHandler(tollbooth.NewLimiter(5, nil))) @@ -88,7 +102,7 @@ func (s *Rest) Run(port int) { Logger(LogNone), tollbooth_chi.LimitHandler(tollbooth.NewLimiter(100, nil)), } - router.Mount(s.Authenticator.AvatarProxy.Routes(avatarMiddlewares...)) // mount avatars controller to /api/v1/avatar/{file.img} + router.Mount(s.Authenticator.AvatarProxy.Routes(avatarMiddlewares...)) // mount avatars to /api/v1/avatar/{file.img} // api routes router.Route("/api/v1", func(rapi chi.Router) { @@ -128,16 +142,7 @@ func (s *Rest) Run(port int) { // file server for static content from /web addFileServer(router, "/web", http.Dir(s.WebRoot)) - - s.httpServer = &http.Server{ - Addr: fmt.Sprintf(":%d", port), - Handler: router, - ReadHeaderTimeout: 5 * time.Second, - WriteTimeout: 5 * time.Second, - IdleTimeout: 30 * time.Second, - } - err := s.httpServer.ListenAndServe() - log.Printf("[WARN] http server terminated, %s", err) + return router } // POST /comment - adds comment, resets all immutable fields diff --git a/app/rest/api/rest_test.go b/app/rest/api/rest_test.go index a150c2a2..ff5171bc 100644 --- a/app/rest/api/rest_test.go +++ b/app/rest/api/rest_test.go @@ -2,12 +2,12 @@ package api import ( "bytes" - "context" + "encoding/base64" "encoding/json" "fmt" "io/ioutil" - "math/rand" "net/http" + "net/http/httptest" "os" "strings" "testing" @@ -30,22 +30,22 @@ var testDb = "/tmp/test-remark.db" var testHTML = "/tmp/test-remark.html" func TestServer_Ping(t *testing.T) { - srv, port := prep(t) - assert.NotNil(t, srv) - defer cleanup(srv) + srv, ts := prep(t) + require.NotNil(t, srv) + defer cleanup(ts) - res, code := get(t, fmt.Sprintf("http://127.0.0.1:%d/api/v1/ping", port)) + res, code := get(t, ts.URL+"/api/v1/ping") assert.Equal(t, "pong", res) assert.Equal(t, 200, code) } func TestServer_Create(t *testing.T) { - srv, port := prep(t) + srv, ts := prep(t) require.NotNil(t, srv) - defer cleanup(srv) + defer cleanup(ts) - r := strings.NewReader(`{"text": "test 123", "locator":{"url": "https://radio-t.com/blah1", "site": "radio-t"}}`) - resp, err := http.Post(fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/comment", port), "application/json", r) + resp, err := post(t, ts.URL+"/api/v1/comment", + `{"text": "test 123", "locator":{"url": "https://radio-t.com/blah1", "site": "radio-t"}}`) assert.Nil(t, err) assert.Equal(t, http.StatusCreated, resp.StatusCode) @@ -61,13 +61,13 @@ func TestServer_Create(t *testing.T) { } func TestServer_CreateTooBig(t *testing.T) { - srv, port := prep(t) + srv, ts := prep(t) require.NotNil(t, srv) - defer cleanup(srv) + defer cleanup(ts) longComment := fmt.Sprintf(`{"text": "%4001s", "locator":{"url": "https://radio-t.com/blah1", "site": "radio-t"}}`, "Щ") - r := strings.NewReader(longComment) - resp, err := http.Post(fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/comment", port), "application/json", r) + + resp, err := post(t, ts.URL+"/api/v1/comment", longComment) assert.Nil(t, err) assert.Equal(t, http.StatusBadRequest, resp.StatusCode) b, err := ioutil.ReadAll(resp.Body) @@ -81,12 +81,11 @@ func TestServer_CreateTooBig(t *testing.T) { } func TestServer_Preview(t *testing.T) { - srv, port := prep(t) + srv, ts := prep(t) require.NotNil(t, srv) - defer cleanup(srv) + defer cleanup(ts) - r := strings.NewReader(`{"text": "test 123", "locator":{"url": "https://radio-t.com/blah1", "site": "radio-t"}}`) - resp, err := http.Post(fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/preview", port), "application/json", r) + resp, err := post(t, ts.URL+"/api/v1/preview", `{"text": "test 123", "locator":{"url": "https://radio-t.com/blah1", "site": "radio-t"}}`) assert.Nil(t, err) assert.Equal(t, http.StatusOK, resp.StatusCode) b, err := ioutil.ReadAll(resp.Body) @@ -95,16 +94,16 @@ func TestServer_Preview(t *testing.T) { } func TestServer_PreviewWithMD(t *testing.T) { - srv, port := prep(t) + srv, ts := prep(t) require.NotNil(t, srv) - defer cleanup(srv) + defer cleanup(ts) text := ` # h1 BKT func TestServer_Preview(t *testing.T) { -srv, port := prep(t) +srv, ts := prep(t) require.NotNil(t, srv) } BKT @@ -113,23 +112,23 @@ BKT j := fmt.Sprintf(`{"text": "%s", "locator":{"url": "https://radio-t.com/blah1", "site": "radio-t"}}`, text) j = strings.Replace(j, "\n", "\\n", -1) t.Log(j) - r := strings.NewReader(j) - resp, err := http.Post(fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/preview", port), "application/json", r) + + resp, err := post(t, ts.URL+"/api/v1/preview", j) assert.Nil(t, err) assert.Equal(t, http.StatusOK, resp.StatusCode) b, err := ioutil.ReadAll(resp.Body) assert.Nil(t, err) - assert.Equal(t, "

h1

\n\n
func TestServer_Preview(t *testing.T) {\nsrv, port := prep(t)\n  require.NotNil(t, srv)\n}\n
\n", string(b)) + assert.Equal(t, "

h1

\n\n
func TestServer_Preview(t *testing.T) {\nsrv, ts := prep(t)\n  require.NotNil(t, srv)\n}\n
\n", string(b)) } func TestServer_CreateAndGet(t *testing.T) { - srv, port := prep(t) + srv, ts := prep(t) assert.NotNil(t, srv) - defer cleanup(srv) + defer cleanup(ts) // create comment - r := strings.NewReader(`{"text": "**test** *123* http://radio-t.com", "locator":{"url": "https://radio-t.com/blah1", "site": "radio-t"}}`) - resp, err := http.Post(fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/comment", port), "application/json", r) + resp, err := post(t, ts.URL+"/api/v1/comment", + `{"text": "**test** *123* http://radio-t.com", "locator":{"url": "https://radio-t.com/blah1", "site": "radio-t"}}`) require.Nil(t, err) require.Equal(t, http.StatusCreated, resp.StatusCode) b, err := ioutil.ReadAll(resp.Body) @@ -141,7 +140,7 @@ func TestServer_CreateAndGet(t *testing.T) { id := c["id"].(string) // get created comment by id - res, code := get(t, fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/id/%s?site=radio-t&url=https://radio-t.com/blah1", port, id)) + res, code := getWithAuth(t, fmt.Sprintf("%s/api/v1/id/%s?site=radio-t&url=https://radio-t.com/blah1", ts.URL, id)) assert.Equal(t, 200, code) comment := store.Comment{} err = json.Unmarshal([]byte(res), &comment) @@ -155,11 +154,11 @@ func TestServer_CreateAndGet(t *testing.T) { } func TestServer_Find(t *testing.T) { - srv, port := prep(t) + srv, ts := prep(t) assert.NotNil(t, srv) - defer cleanup(srv) + defer cleanup(ts) - _, code := get(t, fmt.Sprintf("http://127.0.0.1:%d/api/v1/find?site=radio-t&url=https://radio-t.com/blah1", port)) + _, code := get(t, ts.URL+"/api/v1/find?site=radio-t&url=https://radio-t.com/blah1") assert.Equal(t, 400, code, "nothing in") c1 := store.Comment{Text: "test test #1", ParentID: "p1", @@ -167,12 +166,12 @@ func TestServer_Find(t *testing.T) { c2 := store.Comment{Text: "test test #2", ParentID: "p1", Locator: store.Locator{SiteID: "radio-t", URL: "https://radio-t.com/blah1"}} - id1 := addComment(t, c1, port) - id2 := addComment(t, c2, port) + id1 := addComment(t, c1, ts) + id2 := addComment(t, c2, ts) assert.NotEqual(t, id1, id2) // get sorted by +time - res, code := get(t, fmt.Sprintf("http://127.0.0.1:%d/api/v1/find?site=radio-t&url=https://radio-t.com/blah1&sort=+time", port)) + res, code := get(t, ts.URL+"/api/v1/find?site=radio-t&url=https://radio-t.com/blah1&sort=+time") assert.Equal(t, 200, code) comments := []store.Comment{} err := json.Unmarshal([]byte(res), &comments) @@ -182,7 +181,7 @@ func TestServer_Find(t *testing.T) { assert.Equal(t, id2, comments[1].ID) // get sorted by -time - res, code = get(t, fmt.Sprintf("http://127.0.0.1:%d/api/v1/find?site=radio-t&url=https://radio-t.com/blah1&sort=-time", port)) + res, code = get(t, ts.URL+"/api/v1/find?site=radio-t&url=https://radio-t.com/blah1&sort=-time") assert.Equal(t, 200, code) err = json.Unmarshal([]byte(res), &comments) assert.Nil(t, err) @@ -192,19 +191,19 @@ func TestServer_Find(t *testing.T) { } func TestServer_Update(t *testing.T) { - srv, port := prep(t) + srv, ts := prep(t) assert.NotNil(t, srv) - defer cleanup(srv) + defer cleanup(ts) c1 := store.Comment{Text: "test test #1", ParentID: "p1", Locator: store.Locator{SiteID: "radio-t", URL: "https://radio-t.com/blah1"}} - id := addComment(t, c1, port) + id := addComment(t, c1, ts) client := http.Client{} - req, err := http.NewRequest(http.MethodPut, - fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/comment/"+id+"?site=radio-t&url=https://radio-t.com/blah1", port), + req, err := http.NewRequest(http.MethodPut, ts.URL+"/api/v1/comment/"+id+"?site=radio-t&url=https://radio-t.com/blah1", strings.NewReader(`{"text":"updated text", "summary":"my edit"}`)) assert.Nil(t, err) + req = withBasicAuth(req, "dev", "password") b, err := client.Do(req) assert.Nil(t, err) body, err := ioutil.ReadAll(b.Body) @@ -222,7 +221,7 @@ func TestServer_Update(t *testing.T) { assert.True(t, time.Since(c2.Edit.Timestamp) < 1*time.Second) // read updated comment - res, code := get(t, fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/id/%s?site=radio-t&url=https://radio-t.com/blah1", port, id)) + res, code := getWithAuth(t, fmt.Sprintf("%s/api/v1/id/%s?site=radio-t&url=https://radio-t.com/blah1", ts.URL, id)) assert.Equal(t, 200, code) c3 := store.Comment{} err = json.Unmarshal([]byte(res), &c3) @@ -231,9 +230,9 @@ func TestServer_Update(t *testing.T) { } func TestServer_Last(t *testing.T) { - srv, port := prep(t) + srv, ts := prep(t) assert.NotNil(t, srv) - defer cleanup(srv) + defer cleanup(ts) c1 := store.Comment{Text: "test test #1", ParentID: "p1", Locator: store.Locator{SiteID: "radio-t", URL: "https://radio-t.com/blah1"}} @@ -241,11 +240,11 @@ func TestServer_Last(t *testing.T) { Locator: store.Locator{SiteID: "radio-t", URL: "https://radio-t.com/blah2"}} // add 3 comments - addComment(t, c1, port) - id1 := addComment(t, c1, port) - id2 := addComment(t, c2, port) + addComment(t, c1, ts) + id1 := addComment(t, c1, ts) + id2 := addComment(t, c2, ts) - res, code := get(t, fmt.Sprintf("http://127.0.0.1:%d/api/v1/last/2?site=radio-t", port)) + res, code := get(t, ts.URL+"/api/v1/last/2?site=radio-t") assert.Equal(t, 200, code) comments := []store.Comment{} err := json.Unmarshal([]byte(res), &comments) @@ -254,7 +253,7 @@ func TestServer_Last(t *testing.T) { assert.Equal(t, id1, comments[1].ID) assert.Equal(t, id2, comments[0].ID) - res, code = get(t, fmt.Sprintf("http://127.0.0.1:%d/api/v1/last/5?site=radio-t", port)) + res, code = get(t, ts.URL+"/api/v1/last/5?site=radio-t") assert.Equal(t, 200, code) err = json.Unmarshal([]byte(res), &comments) assert.Nil(t, err) @@ -262,9 +261,9 @@ func TestServer_Last(t *testing.T) { } func TestServer_FindUserComments(t *testing.T) { - srv, port := prep(t) + srv, ts := prep(t) assert.NotNil(t, srv) - defer cleanup(srv) + defer cleanup(ts) c1 := store.Comment{Text: "test test #1", Locator: store.Locator{SiteID: "radio-t", URL: "https://radio-t.com/blah1"}} @@ -272,14 +271,14 @@ func TestServer_FindUserComments(t *testing.T) { Locator: store.Locator{SiteID: "radio-t", URL: "https://radio-t.com/blah2"}} // add 3 comments - addComment(t, c1, port) - addComment(t, c2, port) - addComment(t, c2, port) + addComment(t, c1, ts) + addComment(t, c2, ts) + addComment(t, c2, ts) - _, code := get(t, fmt.Sprintf("http://127.0.0.1:%d/api/v1/comments?site=radio-t&user=blah", port)) + _, code := get(t, ts.URL+"/api/v1/comments?site=radio-t&user=blah") assert.Equal(t, 400, code, "noting for user blah") - res, code := get(t, fmt.Sprintf("http://127.0.0.1:%d/api/v1/comments?site=radio-t&user=dev", port)) + res, code := get(t, ts.URL+"/api/v1/comments?site=radio-t&user=dev") assert.Equal(t, 200, code) resp := struct { @@ -294,11 +293,11 @@ func TestServer_FindUserComments(t *testing.T) { } func TestServer_UserInfo(t *testing.T) { - srv, port := prep(t) + srv, ts := prep(t) assert.NotNil(t, srv) - defer cleanup(srv) + defer cleanup(ts) - body, code := get(t, fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/user?site=radio-t", port)) + body, code := getWithAuth(t, ts.URL+"/api/v1/user?site=radio-t") assert.Equal(t, 200, code) user := store.User{} err := json.Unmarshal([]byte(body), &user) @@ -308,24 +307,24 @@ func TestServer_UserInfo(t *testing.T) { } func TestServer_Vote(t *testing.T) { - srv, port := prep(t) + srv, ts := prep(t) assert.NotNil(t, srv) - defer cleanup(srv) + defer cleanup(ts) c1 := store.Comment{Text: "test test #1", Locator: store.Locator{SiteID: "radio-t", URL: "https://radio-t.com/blah"}} c2 := store.Comment{Text: "test test #2", ParentID: "p1", Locator: store.Locator{SiteID: "radio-t", URL: "https://radio-t.com/blah"}} - id1 := addComment(t, c1, port) - addComment(t, c2, port) + id1 := addComment(t, c1, ts) + addComment(t, c2, ts) vote := func(val int) int { client := http.Client{} req, err := http.NewRequest(http.MethodPut, - fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/vote/%s?site=radio-t&url=https://radio-t.com/blah&vote=%d", - port, id1, val), nil) + fmt.Sprintf("%s/api/v1/vote/%s?site=radio-t&url=https://radio-t.com/blah&vote=%d", ts.URL, id1, val), nil) assert.Nil(t, err) + req = withBasicAuth(req, "dev", "password") resp, err := client.Do(req) assert.Nil(t, err) return resp.StatusCode @@ -333,7 +332,7 @@ func TestServer_Vote(t *testing.T) { assert.Equal(t, 200, vote(1), "first vote allowed") assert.Equal(t, 400, vote(1), "second vote rejected") - body, code := get(t, fmt.Sprintf("http://127.0.0.1:%d/api/v1/id/%s?site=radio-t&url=https://radio-t.com/blah", port, id1)) + body, code := get(t, fmt.Sprintf("%s/api/v1/id/%s?site=radio-t&url=https://radio-t.com/blah", ts.URL, id1)) assert.Equal(t, 200, code) cr := store.Comment{} err := json.Unmarshal([]byte(body), &cr) @@ -342,40 +341,39 @@ func TestServer_Vote(t *testing.T) { assert.Equal(t, map[string]bool{"dev": true}, cr.Votes) assert.Equal(t, 200, vote(-1), "opposite vote allowed") - body, code = get(t, fmt.Sprintf("http://127.0.0.1:%d/api/v1/id/%s?site=radio-t&url=https://radio-t.com/blah", port, id1)) + body, code = get(t, fmt.Sprintf("%s/api/v1/id/%s?site=radio-t&url=https://radio-t.com/blah", ts.URL, id1)) assert.Equal(t, 200, code) cr = store.Comment{} err = json.Unmarshal([]byte(body), &cr) assert.Nil(t, err) assert.Equal(t, 0, cr.Score) assert.Equal(t, map[string]bool{}, cr.Votes) - } func TestServer_Count(t *testing.T) { - srv, port := prep(t) + srv, ts := prep(t) assert.NotNil(t, srv) - defer cleanup(srv) + defer cleanup(ts) c1 := store.Comment{Text: "test test #1", Locator: store.Locator{SiteID: "radio-t", URL: "https://radio-t.com/blah1"}} c2 := store.Comment{Text: "test test #2", ParentID: "p1", Locator: store.Locator{SiteID: "radio-t", URL: "https://radio-t.com/blah2"}} - addComment(t, c1, port) - addComment(t, c1, port) - addComment(t, c1, port) - addComment(t, c2, port) - addComment(t, c2, port) + addComment(t, c1, ts) + addComment(t, c1, ts) + addComment(t, c1, ts) + addComment(t, c2, ts) + addComment(t, c2, ts) - body, code := get(t, fmt.Sprintf("http://127.0.0.1:%d/api/v1/count?site=radio-t&url=https://radio-t.com/blah1", port)) + body, code := get(t, ts.URL+"/api/v1/count?site=radio-t&url=https://radio-t.com/blah1") assert.Equal(t, 200, code) j := JSON{} err := json.Unmarshal([]byte(body), &j) assert.Nil(t, err) assert.Equal(t, 3.0, j["count"]) - body, code = get(t, fmt.Sprintf("http://127.0.0.1:%d/api/v1/count?site=radio-t&url=https://radio-t.com/blah2", port)) + body, code = get(t, ts.URL+"/api/v1/count?site=radio-t&url=https://radio-t.com/blah2") assert.Equal(t, 200, code) err = json.Unmarshal([]byte(body), &j) assert.Nil(t, err) @@ -383,23 +381,22 @@ func TestServer_Count(t *testing.T) { } func TestServer_Counts(t *testing.T) { - srv, port := prep(t) + srv, ts := prep(t) assert.NotNil(t, srv) - defer cleanup(srv) + defer cleanup(ts) c1 := store.Comment{Text: "test test #1", Locator: store.Locator{SiteID: "radio-t", URL: "https://radio-t.com/blah1"}} c2 := store.Comment{Text: "test test #2", ParentID: "p1", Locator: store.Locator{SiteID: "radio-t", URL: "https://radio-t.com/blah2"}} - addComment(t, c1, port) - addComment(t, c1, port) - addComment(t, c1, port) - addComment(t, c2, port) - addComment(t, c2, port) + addComment(t, c1, ts) + addComment(t, c1, ts) + addComment(t, c1, ts) + addComment(t, c2, ts) + addComment(t, c2, ts) - r := strings.NewReader(`["https://radio-t.com/blah1","https://radio-t.com/blah2"]`) - resp, err := http.Post(fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/counts?site=radio-t", port), "application/json", r) + resp, err := post(t, ts.URL+"/api/v1/counts?site=radio-t", `["https://radio-t.com/blah1","https://radio-t.com/blah2"]`) assert.Nil(t, err) assert.Equal(t, http.StatusOK, resp.StatusCode) @@ -414,22 +411,22 @@ func TestServer_Counts(t *testing.T) { } func TestServer_List(t *testing.T) { - srv, port := prep(t) + srv, ts := prep(t) assert.NotNil(t, srv) - defer cleanup(srv) + defer cleanup(ts) c1 := store.Comment{Text: "test test #1", Locator: store.Locator{SiteID: "radio-t", URL: "https://radio-t.com/blah1"}} c2 := store.Comment{Text: "test test #2", ParentID: "p1", Locator: store.Locator{SiteID: "radio-t", URL: "https://radio-t.com/blah2"}} - addComment(t, c1, port) - addComment(t, c1, port) - addComment(t, c1, port) - addComment(t, c2, port) - addComment(t, c2, port) + addComment(t, c1, ts) + addComment(t, c1, ts) + addComment(t, c1, ts) + addComment(t, c2, ts) + addComment(t, c2, ts) - body, code := get(t, fmt.Sprintf("http://127.0.0.1:%d/api/v1/list?site=radio-t", port)) + body, code := get(t, ts.URL+"/api/v1/list?site=radio-t") assert.Equal(t, 200, code) pi := []store.PostInfo{} err := json.Unmarshal([]byte(body), &pi) @@ -438,11 +435,11 @@ func TestServer_List(t *testing.T) { } func TestServer_Config(t *testing.T) { - srv, port := prep(t) + srv, ts := prep(t) assert.NotNil(t, srv) - defer cleanup(srv) + defer cleanup(ts) - body, code := get(t, fmt.Sprintf("http://127.0.0.1:%d/api/v1/config?site=radio-t", port)) + body, code := get(t, ts.URL+"/api/v1/config?site=radio-t") assert.Equal(t, 200, code) j := JSON{} err := json.Unmarshal([]byte(body), &j) @@ -456,16 +453,16 @@ func TestServer_Config(t *testing.T) { } func TestServer_FileServer(t *testing.T) { - srv, port := prep(t) + srv, ts := prep(t) assert.NotNil(t, srv) - defer cleanup(srv) + defer cleanup(ts) - body, code := get(t, fmt.Sprintf("http://127.0.0.1:%d/web/test-remark.html", port)) + body, code := get(t, ts.URL+"/web/test-remark.html") assert.Equal(t, 200, code) assert.Equal(t, "some html", body) } -func prep(t *testing.T) (srv *Rest, port int) { +func prep(t *testing.T) (srv *Rest, ts *httptest.Server) { b, err := engine.NewBoltDB(bolt.Options{}, engine.BoltSite{FileName: testDb, SiteID: "radio-t"}) require.Nil(t, err) dataStore := service.DataStore{Interface: b, EditDuration: 5 * time.Minute, MaxCommentSize: 4000, Secret: "123456"} @@ -484,45 +481,57 @@ func prep(t *testing.T) (srv *Rest, port int) { } srv.ScoreThresholds.Low, srv.ScoreThresholds.Critical = -5, -10 - importSrv := &Import{ - DisqusImporter: &migrator.Disqus{DataStore: &dataStore}, - NativeImporter: &migrator.Remark{DataStore: &dataStore}, - Cache: &mockCache{}, - } - ioutil.WriteFile(testHTML, []byte("some html"), 0700) - portSetCh := make(chan bool) + ts = httptest.NewServer(srv.routes()) + return srv, ts +} - go func() { - port = rand.Intn(50000) + 1025 - portSetCh <- true - srv.Run(port) - }() - - <-portSetCh - - go func() { - importSrv.Run(port + 1) - }() - - time.Sleep(100 * time.Millisecond) - return srv, port +func withBasicAuth(r *http.Request, username, password string) *http.Request { + auth := username + ":" + password + r.Header.Add("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(auth))) + return r } func get(t *testing.T, url string) (string, int) { r, err := http.Get(url) - assert.Nil(t, err) + require.Nil(t, err) + defer r.Body.Close() + body, err := ioutil.ReadAll(r.Body) + require.Nil(t, err) + return string(body), r.StatusCode +} + +func getWithAuth(t *testing.T, url string) (string, int) { + client := &http.Client{Timeout: 5 * time.Second} + req, err := http.NewRequest("GET", url, nil) + require.Nil(t, err) + withBasicAuth(req, "dev", "password") + r, err := client.Do(req) + require.Nil(t, err) defer r.Body.Close() body, err := ioutil.ReadAll(r.Body) assert.Nil(t, err) return string(body), r.StatusCode } -func addComment(t *testing.T, c store.Comment, port int) string { +func post(t *testing.T, url string, body string) (*http.Response, error) { + client := &http.Client{Timeout: 5 * time.Second} + req, err := http.NewRequest("POST", url, strings.NewReader(body)) + assert.Nil(t, err) + withBasicAuth(req, "dev", "password") + return client.Do(req) +} + +func addComment(t *testing.T, c store.Comment, ts *httptest.Server) string { b, err := json.Marshal(c) assert.Nil(t, err, "can't marshal comment %+v", c) - resp, err := http.Post(fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/comment", port), "application/json", bytes.NewBuffer(b)) + + client := &http.Client{Timeout: 5 * time.Second} + req, err := http.NewRequest("POST", ts.URL+"/api/v1/comment", bytes.NewBuffer(b)) + assert.Nil(t, err) + withBasicAuth(req, "dev", "password") + resp, err := client.Do(req) assert.Nil(t, err) assert.Equal(t, http.StatusCreated, resp.StatusCode) b, err = ioutil.ReadAll(resp.Body) @@ -535,9 +544,8 @@ func addComment(t *testing.T, c store.Comment, port int) string { return crResp["id"].(string) } -func cleanup(srv *Rest) { - srv.httpServer.Close() - srv.httpServer.Shutdown(context.Background()) +func cleanup(ts *httptest.Server) { + ts.Close() os.Remove(testDb) os.Remove(testHTML) } diff --git a/app/rest/api/rss_test.go b/app/rest/api/rss_test.go index 704d6107..964468ae 100644 --- a/app/rest/api/rss_test.go +++ b/app/rest/api/rss_test.go @@ -12,21 +12,27 @@ import ( ) func TestServer_RssPost(t *testing.T) { - srv, port := prep(t) + srv, ts := prep(t) assert.NotNil(t, srv) - defer cleanup(srv) + defer cleanup(ts) waitOnMinChange() // add one more comment r := strings.NewReader(`{"text": "test 123", "locator":{"url": "https://radio-t.com/blah1", "site": "radio-t"}}`) - resp, err := http.Post(fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/comment", port), "application/json", r) + + client := &http.Client{Timeout: 5 * time.Second} + req, err := http.NewRequest("POST", ts.URL+"/api/v1/comment", r) + assert.Nil(t, err) + withBasicAuth(req, "dev", "password") + + resp, err := client.Do(req) assert.Nil(t, err) assert.Equal(t, http.StatusCreated, resp.StatusCode) pubDate := time.Now().Format(time.RFC1123Z) - res, code := get(t, fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/rss/post?site=radio-t&url=https://radio-t.com/blah1", port)) + res, code := get(t, ts.URL+"/api/v1/rss/post?site=radio-t&url=https://radio-t.com/blah1") assert.Equal(t, 200, code) assert.Nil(t, err) @@ -53,25 +59,33 @@ func TestServer_RssPost(t *testing.T) { } func TestServer_RssSite(t *testing.T) { - srv, port := prep(t) + srv, ts := prep(t) assert.NotNil(t, srv) - defer cleanup(srv) + defer cleanup(ts) waitOnMinChange() pubDate := time.Now().Format(time.RFC1123Z) + client := &http.Client{Timeout: 5 * time.Second} + r := strings.NewReader(`{"text": "test 123", "locator":{"url": "https://radio-t.com/blah10", "site": "radio-t"}}`) - resp, err := http.Post(fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/comment", port), "application/json", r) + req, err := http.NewRequest("POST", ts.URL+"/api/v1/comment", r) + assert.Nil(t, err) + withBasicAuth(req, "dev", "password") + resp, err := client.Do(req) assert.Nil(t, err) assert.Equal(t, http.StatusCreated, resp.StatusCode) r = strings.NewReader(`{"text": "xyz test", "locator":{"url": "https://radio-t.com/blah11", "site": "radio-t"}}`) - resp, err = http.Post(fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/comment", port), "application/json", r) + req, err = http.NewRequest("POST", ts.URL+"/api/v1/comment", r) + assert.Nil(t, err) + withBasicAuth(req, "dev", "password") + resp, err = client.Do(req) assert.Nil(t, err) assert.Equal(t, http.StatusCreated, resp.StatusCode) - res, code := get(t, fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/rss/site?site=radio-t", port)) + res, code := get(t, ts.URL+"/api/v1/rss/site?site=radio-t") assert.Equal(t, 200, code) assert.Nil(t, err) diff --git a/app/rest/auth/auth_test.go b/app/rest/auth/auth_test.go index 17680f65..f71d3396 100644 --- a/app/rest/auth/auth_test.go +++ b/app/rest/auth/auth_test.go @@ -25,7 +25,7 @@ func TestAuthRequired(t *testing.T) { client := &http.Client{Timeout: 1 * time.Second} req, err := http.NewRequest("GET", server.URL+"/auth", nil) - req.Header.Add("Authorization", "Basic "+basicAuth("dev", "123456")) + req = withBasicAuth(req, "dev", "123456") resp, err := client.Do(req) require.NoError(t, err) assert.Equal(t, 201, resp.StatusCode, "valid auth user") @@ -36,7 +36,7 @@ func TestAuthRequired(t *testing.T) { assert.Equal(t, 401, resp.StatusCode, "no auth user") req, err = http.NewRequest("GET", server.URL+"/auth", nil) - req.Header.Add("Authorization", "Basic "+basicAuth("dev", "ZZZZ123456")) + req = withBasicAuth(req, "dev", "xyz") resp, err = client.Do(req) require.NoError(t, err) assert.Equal(t, 401, resp.StatusCode, "wrong auth creds") @@ -54,7 +54,7 @@ func TestAuthNotRequired(t *testing.T) { client := &http.Client{Timeout: 1 * time.Second} req, err := http.NewRequest("GET", server.URL+"/auth", nil) - req.Header.Add("Authorization", "Basic "+basicAuth("dev", "123456")) + req = withBasicAuth(req, "dev", "123456") resp, err := client.Do(req) require.NoError(t, err) assert.Equal(t, 201, resp.StatusCode, "valid auth user") @@ -65,7 +65,7 @@ func TestAuthNotRequired(t *testing.T) { assert.Equal(t, 201, resp.StatusCode, "no auth user") req, err = http.NewRequest("GET", server.URL+"/auth", nil) - req.Header.Add("Authorization", "Basic "+basicAuth("dev", "ZZZZ123456")) + req = withBasicAuth(req, "dev", "ZZZZ123456") resp, err = client.Do(req) require.NoError(t, err) assert.Equal(t, 201, resp.StatusCode, "wrong auth creds") @@ -83,20 +83,21 @@ func TestAdminRequired(t *testing.T) { client := &http.Client{Timeout: 1 * time.Second} req, err := http.NewRequest("GET", server.URL+"/auth", nil) - req.Header.Add("Authorization", "Basic "+basicAuth("dev", "123456")) + req = withBasicAuth(req, "dev", "123456") resp, err := client.Do(req) require.NoError(t, err) assert.Equal(t, 201, resp.StatusCode, "valid auth user, admin") devUser.Admin = false req, err = http.NewRequest("GET", server.URL+"/auth", nil) - req.Header.Add("Authorization", "Basic "+basicAuth("dev", "123456")) + req = withBasicAuth(req, "dev", "123456") resp, err = client.Do(req) require.NoError(t, err) assert.Equal(t, 403, resp.StatusCode, "valid auth user, not admin") } -func basicAuth(username, password string) string { +func withBasicAuth(r *http.Request, username, password string) *http.Request { auth := username + ":" + password - return base64.StdEncoding.EncodeToString([]byte(auth)) + r.Header.Add("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(auth))) + return r }