mirror of
https://github.com/gotify/server.git
synced 2024-01-28 15:20:56 +03:00
234 lines
6.2 KiB
Go
234 lines
6.2 KiB
Go
package api
|
|
|
|
import (
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/gotify/server/v2/mode"
|
|
"github.com/gotify/server/v2/model"
|
|
"github.com/gotify/server/v2/test"
|
|
"github.com/gotify/server/v2/test/testdb"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/suite"
|
|
)
|
|
|
|
var (
|
|
firstClientToken = "Caaaaaaaaaaaaaa"
|
|
secondClientToken = "Cbbbbbbbbbbbbbb"
|
|
)
|
|
|
|
func TestClientSuite(t *testing.T) {
|
|
suite.Run(t, new(ClientSuite))
|
|
}
|
|
|
|
type ClientSuite struct {
|
|
suite.Suite
|
|
db *testdb.Database
|
|
a *ClientAPI
|
|
ctx *gin.Context
|
|
recorder *httptest.ResponseRecorder
|
|
notified bool
|
|
}
|
|
|
|
var originalGenerateClientToken func() string
|
|
|
|
func (s *ClientSuite) BeforeTest(suiteName, testName string) {
|
|
originalGenerateClientToken = generateClientToken
|
|
generateClientToken = test.Tokens(firstClientToken, secondClientToken)
|
|
mode.Set(mode.TestDev)
|
|
s.recorder = httptest.NewRecorder()
|
|
s.db = testdb.NewDB(s.T())
|
|
s.ctx, _ = gin.CreateTestContext(s.recorder)
|
|
withURL(s.ctx, "http", "example.com")
|
|
s.notified = false
|
|
s.a = &ClientAPI{DB: s.db, NotifyDeleted: s.notify}
|
|
}
|
|
|
|
func (s *ClientSuite) notify(uint, string) {
|
|
s.notified = true
|
|
}
|
|
|
|
func (s *ClientSuite) AfterTest(suiteName, testName string) {
|
|
generateClientToken = originalGenerateClientToken
|
|
s.db.Close()
|
|
}
|
|
|
|
func (s *ClientSuite) Test_ensureClientHasCorrectJsonRepresentation() {
|
|
actual := &model.Client{ID: 1, UserID: 2, Token: "Casdasfgeeg", Name: "myclient"}
|
|
test.JSONEquals(s.T(), actual, `{"id":1,"token":"Casdasfgeeg","name":"myclient","lastUsed":null}`)
|
|
}
|
|
|
|
func (s *ClientSuite) Test_CreateClient_mapAllParameters() {
|
|
s.db.User(5)
|
|
|
|
test.WithUser(s.ctx, 5)
|
|
s.withFormData("name=custom_name&description=description_text")
|
|
|
|
s.a.CreateClient(s.ctx)
|
|
|
|
expected := &model.Client{ID: 1, Token: firstClientToken, UserID: 5, Name: "custom_name"}
|
|
assert.Equal(s.T(), 200, s.recorder.Code)
|
|
if clients, err := s.db.GetClientsByUser(5); assert.NoError(s.T(), err) {
|
|
assert.Contains(s.T(), clients, expected)
|
|
}
|
|
}
|
|
|
|
func (s *ClientSuite) Test_CreateClient_ignoresReadOnlyPropertiesInParams() {
|
|
s.db.User(5)
|
|
test.WithUser(s.ctx, 5)
|
|
|
|
s.withFormData("name=myclient&ID=45&Token=12341234&UserID=333")
|
|
|
|
s.a.CreateClient(s.ctx)
|
|
expected := &model.Client{ID: 1, UserID: 5, Token: firstClientToken, Name: "myclient"}
|
|
|
|
assert.Equal(s.T(), 200, s.recorder.Code)
|
|
if clients, err := s.db.GetClientsByUser(5); assert.NoError(s.T(), err) {
|
|
assert.Contains(s.T(), clients, expected)
|
|
}
|
|
}
|
|
|
|
func (s *ClientSuite) Test_CreateClient_expectBadRequestOnEmptyName() {
|
|
s.db.User(5)
|
|
|
|
test.WithUser(s.ctx, 5)
|
|
s.withFormData("name=&description=description_text")
|
|
|
|
s.a.CreateClient(s.ctx)
|
|
|
|
assert.Equal(s.T(), 400, s.recorder.Code)
|
|
if clients, err := s.db.GetClientsByUser(5); assert.NoError(s.T(), err) {
|
|
assert.Empty(s.T(), clients)
|
|
}
|
|
}
|
|
|
|
func (s *ClientSuite) Test_DeleteClient_expectNotFoundOnCurrentUserIsNotOwner() {
|
|
s.db.User(5).Client(7)
|
|
s.db.User(2)
|
|
|
|
test.WithUser(s.ctx, 2)
|
|
s.ctx.Request = httptest.NewRequest("DELETE", "/token/7", nil)
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: "7"}}
|
|
|
|
s.a.DeleteClient(s.ctx)
|
|
|
|
assert.Equal(s.T(), 404, s.recorder.Code)
|
|
s.db.AssertClientExist(7)
|
|
}
|
|
|
|
func (s *ClientSuite) Test_CreateClient_returnsClientWithID() {
|
|
s.db.User(5)
|
|
|
|
test.WithUser(s.ctx, 5)
|
|
s.withFormData("name=custom_name")
|
|
|
|
s.a.CreateClient(s.ctx)
|
|
|
|
expected := &model.Client{ID: 1, Token: firstClientToken, Name: "custom_name", UserID: 5}
|
|
assert.Equal(s.T(), 200, s.recorder.Code)
|
|
test.BodyEquals(s.T(), expected, s.recorder)
|
|
}
|
|
|
|
func (s *ClientSuite) Test_CreateClient_withExistingToken() {
|
|
s.db.User(5).ClientWithToken(1, firstClientToken)
|
|
|
|
test.WithUser(s.ctx, 5)
|
|
s.withFormData("name=custom_name")
|
|
|
|
s.a.CreateClient(s.ctx)
|
|
|
|
expected := &model.Client{ID: 2, Token: secondClientToken, Name: "custom_name", UserID: 5}
|
|
assert.Equal(s.T(), 200, s.recorder.Code)
|
|
test.BodyEquals(s.T(), expected, s.recorder)
|
|
}
|
|
|
|
func (s *ClientSuite) Test_GetClients() {
|
|
userBuilder := s.db.User(5)
|
|
first := userBuilder.NewClientWithToken(1, "perfper")
|
|
second := userBuilder.NewClientWithToken(2, "asdasd")
|
|
|
|
test.WithUser(s.ctx, 5)
|
|
s.ctx.Request = httptest.NewRequest("GET", "/tokens", nil)
|
|
|
|
s.a.GetClients(s.ctx)
|
|
|
|
assert.Equal(s.T(), 200, s.recorder.Code)
|
|
test.BodyEquals(s.T(), []*model.Client{first, second}, s.recorder)
|
|
}
|
|
|
|
func (s *ClientSuite) Test_DeleteClient_expectNotFound() {
|
|
s.db.User(5)
|
|
|
|
test.WithUser(s.ctx, 5)
|
|
s.ctx.Request = httptest.NewRequest("DELETE", "/token/"+firstClientToken, nil)
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: "8"}}
|
|
|
|
s.a.DeleteClient(s.ctx)
|
|
|
|
assert.Equal(s.T(), 404, s.recorder.Code)
|
|
}
|
|
|
|
func (s *ClientSuite) Test_DeleteClient() {
|
|
s.db.User(5).Client(8)
|
|
|
|
test.WithUser(s.ctx, 5)
|
|
s.ctx.Request = httptest.NewRequest("DELETE", "/token/"+firstClientToken, nil)
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: "8"}}
|
|
|
|
assert.False(s.T(), s.notified)
|
|
|
|
s.a.DeleteClient(s.ctx)
|
|
|
|
assert.Equal(s.T(), 200, s.recorder.Code)
|
|
s.db.AssertClientNotExist(8)
|
|
assert.True(s.T(), s.notified)
|
|
}
|
|
|
|
func (s *ClientSuite) Test_UpdateClient_expectSuccess() {
|
|
s.db.User(5).NewClientWithToken(1, firstClientToken)
|
|
|
|
test.WithUser(s.ctx, 5)
|
|
s.withFormData("name=firefox")
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: "1"}}
|
|
s.a.UpdateClient(s.ctx)
|
|
|
|
expected := &model.Client{
|
|
ID: 1,
|
|
Token: firstClientToken,
|
|
UserID: 5,
|
|
Name: "firefox",
|
|
}
|
|
|
|
assert.Equal(s.T(), 200, s.recorder.Code)
|
|
if client, err := s.db.GetClientByID(1); assert.NoError(s.T(), err) {
|
|
assert.Equal(s.T(), expected, client)
|
|
}
|
|
}
|
|
|
|
func (s *ClientSuite) Test_UpdateClient_expectNotFound() {
|
|
test.WithUser(s.ctx, 5)
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: "2"}}
|
|
s.a.UpdateClient(s.ctx)
|
|
|
|
assert.Equal(s.T(), 404, s.recorder.Code)
|
|
}
|
|
|
|
func (s *ClientSuite) Test_UpdateClient_WithMissingAttributes_expectBadRequest() {
|
|
test.WithUser(s.ctx, 5)
|
|
s.a.UpdateClient(s.ctx)
|
|
|
|
assert.Equal(s.T(), 400, s.recorder.Code)
|
|
}
|
|
|
|
func (s *ClientSuite) withFormData(formData string) {
|
|
s.ctx.Request = httptest.NewRequest("POST", "/token", strings.NewReader(formData))
|
|
s.ctx.Request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
}
|
|
|
|
func withURL(ctx *gin.Context, scheme, host string) {
|
|
ctx.Set("location", &url.URL{Scheme: scheme, Host: host})
|
|
}
|