259 lines
7.2 KiB
Go
259 lines
7.2 KiB
Go
package api
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/gotify/server/auth/password"
|
|
"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"
|
|
)
|
|
|
|
func TestUserSuite(t *testing.T) {
|
|
suite.Run(t, new(UserSuite))
|
|
}
|
|
|
|
type UserSuite struct {
|
|
suite.Suite
|
|
db *test.Database
|
|
a *UserAPI
|
|
ctx *gin.Context
|
|
recorder *httptest.ResponseRecorder
|
|
}
|
|
|
|
func (s *UserSuite) BeforeTest(suiteName, testName string) {
|
|
mode.Set(mode.TestDev)
|
|
s.recorder = httptest.NewRecorder()
|
|
s.ctx, _ = gin.CreateTestContext(s.recorder)
|
|
s.db = test.NewDB(s.T())
|
|
s.a = &UserAPI{DB: s.db}
|
|
}
|
|
|
|
func (s *UserSuite) AfterTest(suiteName, testName string) {
|
|
s.db.Close()
|
|
}
|
|
|
|
func (s *UserSuite) Test_GetUsers() {
|
|
first := s.db.NewUser(2)
|
|
second := s.db.NewUser(5)
|
|
|
|
s.a.GetUsers(s.ctx)
|
|
|
|
assert.Equal(s.T(), 200, s.recorder.Code)
|
|
test.BodyEquals(s.T(), []*model.UserExternal{externalOf(first), externalOf(second)}, s.recorder)
|
|
}
|
|
|
|
func (s *UserSuite) Test_GetCurrentUser() {
|
|
user := s.db.NewUser(5)
|
|
|
|
test.WithUser(s.ctx, 5)
|
|
s.a.GetCurrentUser(s.ctx)
|
|
|
|
assert.Equal(s.T(), 200, s.recorder.Code)
|
|
test.BodyEquals(s.T(), externalOf(user), s.recorder)
|
|
}
|
|
|
|
func (s *UserSuite) Test_GetUserByID() {
|
|
user := s.db.NewUser(2)
|
|
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: "2"}}
|
|
|
|
s.a.GetUserByID(s.ctx)
|
|
|
|
assert.Equal(s.T(), 200, s.recorder.Code)
|
|
test.BodyEquals(s.T(), externalOf(user), s.recorder)
|
|
}
|
|
|
|
func (s *UserSuite) Test_GetUserByID_InvalidID() {
|
|
s.db.User(2)
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: "abc"}}
|
|
|
|
s.a.GetUserByID(s.ctx)
|
|
|
|
assert.Equal(s.T(), 400, s.recorder.Code)
|
|
}
|
|
|
|
func (s *UserSuite) Test_GetUserByID_UnknownUser() {
|
|
s.db.User(2)
|
|
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: "3"}}
|
|
|
|
s.a.GetUserByID(s.ctx)
|
|
|
|
assert.Equal(s.T(), 404, s.recorder.Code)
|
|
}
|
|
|
|
func (s *UserSuite) Test_DeleteUserByID_InvalidID() {
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: "abc"}}
|
|
|
|
s.a.DeleteUserByID(s.ctx)
|
|
|
|
assert.Equal(s.T(), 400, s.recorder.Code)
|
|
}
|
|
|
|
func (s *UserSuite) Test_DeleteUserByID_UnknownUser() {
|
|
s.db.User(2)
|
|
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: "3"}}
|
|
|
|
s.a.DeleteUserByID(s.ctx)
|
|
|
|
assert.Equal(s.T(), 404, s.recorder.Code)
|
|
}
|
|
|
|
func (s *UserSuite) Test_DeleteUserByID() {
|
|
s.db.User(2)
|
|
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: "2"}}
|
|
|
|
s.a.DeleteUserByID(s.ctx)
|
|
|
|
assert.Equal(s.T(), 200, s.recorder.Code)
|
|
s.db.AssertUserNotExist(2)
|
|
}
|
|
|
|
func (s *UserSuite) Test_CreateUser() {
|
|
s.ctx.Request = httptest.NewRequest("POST", "/user", strings.NewReader(`{"name": "tom", "pass": "mylittlepony", "admin": true}`))
|
|
s.ctx.Request.Header.Set("Content-Type", "application/json")
|
|
|
|
s.a.CreateUser(s.ctx)
|
|
|
|
user := &model.UserExternal{ID: 1, Name: "tom", Admin: true}
|
|
test.BodyEquals(s.T(), user, s.recorder)
|
|
assert.Equal(s.T(), 200, s.recorder.Code)
|
|
|
|
created := s.db.GetUserByName("tom")
|
|
assert.NotNil(s.T(), created)
|
|
assert.True(s.T(), password.ComparePassword(created.Pass, []byte("mylittlepony")))
|
|
}
|
|
|
|
func (s *UserSuite) Test_CreateUser_NoPassword() {
|
|
s.ctx.Request = httptest.NewRequest("POST", "/user", strings.NewReader(`{"name": "tom", "pass": "", "admin": true}`))
|
|
s.ctx.Request.Header.Set("Content-Type", "application/json")
|
|
|
|
s.a.CreateUser(s.ctx)
|
|
|
|
assert.Equal(s.T(), 400, s.recorder.Code)
|
|
}
|
|
|
|
func (s *UserSuite) Test_CreateUser_NoName() {
|
|
s.ctx.Request = httptest.NewRequest("POST", "/user", strings.NewReader(`{"name": "", "pass": "asd", "admin": true}`))
|
|
s.ctx.Request.Header.Set("Content-Type", "application/json")
|
|
|
|
s.a.CreateUser(s.ctx)
|
|
|
|
assert.Equal(s.T(), 400, s.recorder.Code)
|
|
}
|
|
|
|
func (s *UserSuite) Test_CreateUser_NameAlreadyExists() {
|
|
s.db.NewUserWithName(1, "tom")
|
|
|
|
s.ctx.Request = httptest.NewRequest("POST", "/user", strings.NewReader(`{"name": "tom", "pass": "mylittlepony", "admin": true}`))
|
|
s.ctx.Request.Header.Set("Content-Type", "application/json")
|
|
|
|
s.a.CreateUser(s.ctx)
|
|
|
|
assert.Equal(s.T(), 400, s.recorder.Code)
|
|
}
|
|
|
|
func (s *UserSuite) Test_UpdateUserByID_InvalidID() {
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: "abc"}}
|
|
|
|
s.ctx.Request = httptest.NewRequest("POST", "/user/abc", strings.NewReader(`{"name": "tom", "pass": "", "admin": false}`))
|
|
s.ctx.Request.Header.Set("Content-Type", "application/json")
|
|
|
|
s.a.UpdateUserByID(s.ctx)
|
|
|
|
assert.Equal(s.T(), 400, s.recorder.Code)
|
|
}
|
|
|
|
func (s *UserSuite) Test_UpdateUserByID_UnknownUser() {
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: "2"}}
|
|
|
|
s.ctx.Request = httptest.NewRequest("POST", "/user/2", strings.NewReader(`{"name": "tom", "pass": "", "admin": false}`))
|
|
s.ctx.Request.Header.Set("Content-Type", "application/json")
|
|
|
|
s.a.UpdateUserByID(s.ctx)
|
|
|
|
assert.Equal(s.T(), 404, s.recorder.Code)
|
|
}
|
|
|
|
func (s *UserSuite) Test_UpdateUserByID_UpdateNotPassword() {
|
|
s.db.CreateUser(&model.User{ID: 2, Name: "nico", Pass: password.CreatePassword("old", 5)})
|
|
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: "2"}}
|
|
|
|
s.ctx.Request = httptest.NewRequest("POST", "/user/2", strings.NewReader(`{"name": "tom", "pass": "", "admin": true}`))
|
|
s.ctx.Request.Header.Set("Content-Type", "application/json")
|
|
|
|
s.a.UpdateUserByID(s.ctx)
|
|
|
|
assert.Equal(s.T(), 200, s.recorder.Code)
|
|
user := s.db.GetUserByID(2)
|
|
assert.NotNil(s.T(), user)
|
|
assert.True(s.T(), password.ComparePassword(user.Pass, []byte("old")))
|
|
}
|
|
|
|
func (s *UserSuite) Test_UpdateUserByID_UpdatePassword() {
|
|
s.db.CreateUser(&model.User{ID: 2, Name: "tom", Pass: password.CreatePassword("old", 5)})
|
|
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: "2"}}
|
|
|
|
s.ctx.Request = httptest.NewRequest("POST", "/user/2", strings.NewReader(`{"name": "tom", "pass": "new", "admin": true}`))
|
|
s.ctx.Request.Header.Set("Content-Type", "application/json")
|
|
|
|
s.a.UpdateUserByID(s.ctx)
|
|
|
|
assert.Equal(s.T(), 200, s.recorder.Code)
|
|
user := s.db.GetUserByID(2)
|
|
assert.NotNil(s.T(), user)
|
|
assert.True(s.T(), password.ComparePassword(user.Pass, []byte("new")))
|
|
}
|
|
|
|
func (s *UserSuite) Test_UpdatePassword() {
|
|
s.db.CreateUser(&model.User{ID: 1, Name: "jmattheis", Pass: password.CreatePassword("old", 5)})
|
|
|
|
test.WithUser(s.ctx, 1)
|
|
s.ctx.Request = httptest.NewRequest("POST", "/user/current/password", strings.NewReader(`{"pass": "new"}`))
|
|
s.ctx.Request.Header.Set("Content-Type", "application/json")
|
|
|
|
s.a.ChangePassword(s.ctx)
|
|
|
|
assert.Equal(s.T(), 200, s.recorder.Code)
|
|
user := s.db.GetUserByID(1)
|
|
assert.NotNil(s.T(), user)
|
|
assert.True(s.T(), password.ComparePassword(user.Pass, []byte("new")))
|
|
}
|
|
|
|
func (s *UserSuite) Test_UpdatePassword_EmptyPassword() {
|
|
s.db.CreateUser(&model.User{ID: 1, Name: "jmattheis", Pass: password.CreatePassword("old", 5)})
|
|
|
|
test.WithUser(s.ctx, 1)
|
|
s.ctx.Request = httptest.NewRequest("POST", "/user/current/password", strings.NewReader(`{"pass":""}`))
|
|
s.ctx.Request.Header.Set("Content-Type", "application/json")
|
|
|
|
s.a.ChangePassword(s.ctx)
|
|
|
|
assert.Equal(s.T(), 400, s.recorder.Code)
|
|
user := s.db.GetUserByID(1)
|
|
assert.NotNil(s.T(), user)
|
|
assert.True(s.T(), password.ComparePassword(user.Pass, []byte("old")))
|
|
}
|
|
|
|
func externalOf(user *model.User) *model.UserExternal {
|
|
return &model.UserExternal{Name: user.Name, Admin: user.Admin, ID: user.ID}
|
|
}
|
|
|
|
func (s *UserSuite) expectJSON(json string) {
|
|
assert.Equal(s.T(), 200, s.recorder.Code)
|
|
bytes, _ := ioutil.ReadAll(s.recorder.Body)
|
|
|
|
assert.JSONEq(s.T(), json, string(bytes))
|
|
}
|