sharded-gotify/router/router_test.go

167 lines
5.1 KiB
Go

package router
import (
"bytes"
"fmt"
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/gin-gonic/gin/json"
"github.com/gotify/server/config"
"github.com/gotify/server/mode"
"github.com/gotify/server/model"
"github.com/gotify/server/test"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
)
var (
client = &http.Client{}
forbiddenJSON = `{"error":"Forbidden", "errorCode":403, "errorDescription":"you are not allowed to access this api"}`
)
func TestIntegrationSuite(t *testing.T) {
suite.Run(t, new(IntegrationSuite))
}
type IntegrationSuite struct {
suite.Suite
db *test.Database
server *httptest.Server
closable func()
}
func (s *IntegrationSuite) BeforeTest(string, string) {
mode.Set(mode.TestDev)
var err error
s.db = test.NewDBWithDefaultUser(s.T())
assert.Nil(s.T(), err)
g, closable := Create(s.db.GormDatabase, &model.VersionInfo{Version: "1.0.0", BuildDate: "2018-02-20-17:30:47", Commit: "asdasds"}, &config.Configuration{PassStrength: 5})
s.closable = closable
s.server = httptest.NewServer(g)
}
func (s *IntegrationSuite) AfterTest(string, string) {
s.closable()
s.db.Close()
s.server.Close()
}
func (s *IntegrationSuite) TestVersionInfo() {
req := s.newRequest("GET", "version", "")
doRequestAndExpect(s.T(), req, 200, `{"version":"1.0.0", "commit":"asdasds", "buildDate":"2018-02-20-17:30:47"}`)
}
func (s *IntegrationSuite) TestHeaderInDev() {
mode.Set(mode.TestDev)
req := s.newRequest("GET", "version", "")
res, err := client.Do(req)
assert.Nil(s.T(), err)
assert.NotEmpty(s.T(), res.Header.Get("Access-Control-Allow-Origin"))
}
func (s *IntegrationSuite) TestHeaderInProd() {
mode.Set(mode.Prod)
req := s.newRequest("GET", "version", "")
res, err := client.Do(req)
assert.Nil(s.T(), err)
assert.Empty(s.T(), res.Header.Get("Access-Control-Allow-Origin"))
}
func (s *IntegrationSuite) TestOptionsRequest() {
req := s.newRequest("OPTIONS", "version", "")
res, err := client.Do(req)
assert.Nil(s.T(), err)
assert.Equal(s.T(), res.StatusCode, 200)
}
func (s *IntegrationSuite) TestSendMessage() {
req := s.newRequest("POST", "application", `{"name": "backup-server"}`)
req.SetBasicAuth("admin", "pw")
res, err := client.Do(req)
assert.Nil(s.T(), err)
assert.Equal(s.T(), 200, res.StatusCode)
token := &model.Application{}
json.NewDecoder(res.Body).Decode(token)
assert.Equal(s.T(), "backup-server", token.Name)
req = s.newRequest("POST", "message", `{"message": "backup done", "title": "backup done"}`)
req.Header.Add("X-Gotify-Key", token.Token)
res, err = client.Do(req)
assert.Nil(s.T(), err)
assert.Equal(s.T(), 200, res.StatusCode)
req = s.newRequest("GET", "message", "")
req.SetBasicAuth("admin", "pw")
res, err = client.Do(req)
assert.Nil(s.T(), err)
assert.Equal(s.T(), 200, res.StatusCode)
msgs := &model.PagedMessages{}
json.NewDecoder(res.Body).Decode(&msgs)
assert.Len(s.T(), msgs.Messages, 1)
msg := msgs.Messages[0]
assert.Equal(s.T(), "backup done", msg.Message)
assert.Equal(s.T(), "backup done", msg.Title)
assert.Equal(s.T(), uint(1), msg.ID)
assert.Equal(s.T(), token.ID, msg.ApplicationID)
}
func (s *IntegrationSuite) TestAuthentication() {
req := s.newRequest("GET", "current/user", "")
req.SetBasicAuth("admin", "pw")
doRequestAndExpect(s.T(), req, 200, `{"id": 1, "name": "admin", "admin": true}`)
req = s.newRequest("GET", "current/user", "")
req.SetBasicAuth("jmattheis", "pw")
doRequestAndExpect(s.T(), req, 401, `{"error":"Unauthorized", "errorCode":401, "errorDescription":"you need to provide a valid access token or user credentials to access this api"}`)
req = s.newRequest("POST", "user", `{"name": "normal", "pass": "secret"}`)
req.SetBasicAuth("admin", "pw")
doRequestAndExpect(s.T(), req, 200, `{"id": 2, "name": "normal", "admin": false}`)
req = s.newRequest("POST", "user", `{"name": "normal2", "pass": "secret"}`)
req.SetBasicAuth("normal", "secret")
doRequestAndExpect(s.T(), req, 403, forbiddenJSON)
req = s.newRequest("POST", "message", `{"message": "backup done", "title": "backup"}`)
req.SetBasicAuth("normal", "secret")
doRequestAndExpect(s.T(), req, 403, forbiddenJSON)
req = s.newRequest("GET", "current/user", "")
req.SetBasicAuth("normal", "secret")
doRequestAndExpect(s.T(), req, 200, `{"id": 2, "name": "normal", "admin": false}`)
req = s.newRequest("POST", "client", `{"name": "android-client"}`)
req.SetBasicAuth("normal", "secret")
res, err := client.Do(req)
assert.Nil(s.T(), err)
assert.Equal(s.T(), 200, res.StatusCode)
token := &model.Application{}
json.NewDecoder(res.Body).Decode(token)
assert.Equal(s.T(), "android-client", token.Name)
}
func (s *IntegrationSuite) newRequest(method, url string, body string) *http.Request {
req, err := http.NewRequest(method, fmt.Sprintf("%s/%s", s.server.URL, url), strings.NewReader(body))
req.Header.Add("Content-Type", "application/json")
assert.Nil(s.T(), err)
return req
}
func doRequestAndExpect(t *testing.T, req *http.Request, code int, json string) {
res, err := client.Do(req)
assert.Nil(t, err)
buf := new(bytes.Buffer)
buf.ReadFrom(res.Body)
assert.Equal(t, code, res.StatusCode)
assert.JSONEq(t, json, buf.String())
}