Cloudreve/routers/router_test.go

299 lines
9.1 KiB
Go
Raw Normal View History

2019-11-11 06:20:33 -05:00
package routers
import (
2019-11-12 01:45:27 -05:00
"bytes"
2019-11-12 03:18:58 -05:00
"encoding/json"
"errors"
2019-11-12 01:45:27 -05:00
"github.com/DATA-DOG/go-sqlmock"
2019-11-16 03:11:37 -05:00
"github.com/HFO4/cloudreve/middleware"
"github.com/HFO4/cloudreve/models"
"github.com/HFO4/cloudreve/pkg/serializer"
2019-11-12 01:45:27 -05:00
"github.com/jinzhu/gorm"
2019-11-13 05:34:29 -05:00
"github.com/mojocn/base64Captcha"
2019-11-11 06:20:33 -05:00
"github.com/stretchr/testify/assert"
"net/http"
"net/http/httptest"
"testing"
)
func TestPing(t *testing.T) {
asserts := assert.New(t)
router := InitRouter()
w := httptest.NewRecorder()
2019-11-23 03:58:56 -05:00
req, _ := http.NewRequest("GET", "/api/v3/site/ping", nil)
2019-11-11 06:20:33 -05:00
router.ServeHTTP(w, req)
assert.Equal(t, 200, w.Code)
asserts.Contains(w.Body.String(), "Pong")
}
2019-11-12 01:45:27 -05:00
2019-11-13 05:34:29 -05:00
func TestCaptcha(t *testing.T) {
asserts := assert.New(t)
router := InitRouter()
w := httptest.NewRecorder()
req, _ := http.NewRequest(
"GET",
2019-11-23 03:58:56 -05:00
"/api/v3/captcha",
2019-11-13 05:34:29 -05:00
nil,
)
router.ServeHTTP(w, req)
asserts.Equal(200, w.Code)
asserts.Contains(w.Body.String(), "base64")
}
2019-11-12 01:45:27 -05:00
func TestUserSession(t *testing.T) {
asserts := assert.New(t)
router := InitRouter()
w := httptest.NewRecorder()
2019-11-13 05:34:29 -05:00
// 创建测试用验证码
var configD = base64Captcha.ConfigDigit{
Height: 80,
Width: 240,
MaxSkew: 0.7,
DotCount: 80,
CaptchaLen: 1,
}
idKeyD, _ := base64Captcha.GenerateCaptcha("", configD)
middleware.ContextMock = map[string]interface{}{
"captchaID": idKeyD,
}
2019-11-12 01:45:27 -05:00
testCases := []struct {
settingRows *sqlmock.Rows
userRows *sqlmock.Rows
2019-11-14 01:51:59 -05:00
policyRows *sqlmock.Rows
2019-11-12 01:45:27 -05:00
reqBody string
2019-11-12 03:18:58 -05:00
expected interface{}
2019-11-12 01:45:27 -05:00
}{
// 登录信息正确,不需要验证码
{
settingRows: sqlmock.NewRows([]string{"name", "value", "type"}).
AddRow("login_captcha", "0", "login"),
userRows: sqlmock.NewRows([]string{"email", "nick", "password", "options"}).
2019-11-14 01:51:59 -05:00
AddRow("admin@cloudreve.org", "admin", "CKLmDKa1C9SD64vU:76adadd4fd4bad86959155f6f7bc8993c94e7adf", "{}"), policyRows: sqlmock.NewRows([]string{"name", "type", "options"}).
AddRow("默认上传策略", "local", "{\"op_name\":\"123\"}"),
2019-11-12 03:18:58 -05:00
reqBody: `{"userName":"admin@cloudreve.org","captchaCode":"captchaCode","Password":"admin"}`,
expected: serializer.BuildUserResponse(model.User{
Email: "admin@cloudreve.org",
Nick: "admin",
}),
2019-11-12 01:45:27 -05:00
},
2019-11-13 05:34:29 -05:00
// 登录信息正确,需要验证码,验证码错误
{
settingRows: sqlmock.NewRows([]string{"name", "value", "type"}).
AddRow("login_captcha", "1", "login"),
userRows: sqlmock.NewRows([]string{"email", "nick", "password", "options"}).
AddRow("admin@cloudreve.org", "admin", "CKLmDKa1C9SD64vU:76adadd4fd4bad86959155f6f7bc8993c94e7adf", "{}"),
2019-11-14 01:51:59 -05:00
policyRows: sqlmock.NewRows([]string{"name", "type", "options"}).
AddRow("默认上传策略", "local", "{\"op_name\":\"123\"}"),
2019-11-13 05:34:29 -05:00
reqBody: `{"userName":"admin@cloudreve.org","captchaCode":"captchaCode","Password":"admin"}`,
expected: serializer.ParamErr("验证码错误", nil),
},
2019-11-12 01:45:27 -05:00
// 邮箱正确密码错误
{
settingRows: sqlmock.NewRows([]string{"name", "value", "type"}).
AddRow("login_captcha", "0", "login"),
userRows: sqlmock.NewRows([]string{"email", "nick", "password", "options"}).
AddRow("admin@cloudreve.org", "admin", "CKLmDKa1C9SD64vU:76adadd4fd4bad86959155f6f7bc8993c94e7adf", "{}"),
2019-11-14 01:51:59 -05:00
policyRows: sqlmock.NewRows([]string{"name", "type", "options"}).
AddRow("默认上传策略", "local", "{\"op_name\":\"123\"}"),
2019-11-12 01:45:27 -05:00
reqBody: `{"userName":"admin@cloudreve.org","captchaCode":"captchaCode","Password":"admin123"}`,
2019-11-12 03:18:58 -05:00
expected: serializer.Err(401, "用户邮箱或密码错误", nil),
2019-11-12 01:45:27 -05:00
},
//邮箱格式不正确
{
reqBody: `{"userName":"admin@cloudreve","captchaCode":"captchaCode","Password":"admin123"}`,
2019-11-12 03:18:58 -05:00
expected: serializer.Err(40001, "邮箱格式不正确", errors.New("Key: 'UserLoginService.UserName' Error:Field validation for 'UserName' failed on the 'email' tag")),
2019-11-12 01:45:27 -05:00
},
// 用户被Ban
{
settingRows: sqlmock.NewRows([]string{"name", "value", "type"}).
AddRow("login_captcha", "0", "login"),
userRows: sqlmock.NewRows([]string{"email", "nick", "password", "options", "status"}).
AddRow("admin@cloudreve.org", "admin", "CKLmDKa1C9SD64vU:76adadd4fd4bad86959155f6f7bc8993c94e7adf", "{}", model.Baned),
2019-11-14 01:51:59 -05:00
policyRows: sqlmock.NewRows([]string{"name", "type", "options"}).
AddRow("默认上传策略", "local", "{\"op_name\":\"123\"}"),
2019-11-12 01:45:27 -05:00
reqBody: `{"userName":"admin@cloudreve.org","captchaCode":"captchaCode","Password":"admin"}`,
2019-11-12 03:18:58 -05:00
expected: serializer.Err(403, "该账号已被封禁", nil),
2019-11-12 01:45:27 -05:00
},
// 用户未激活
{
settingRows: sqlmock.NewRows([]string{"name", "value", "type"}).
AddRow("login_captcha", "0", "login"),
userRows: sqlmock.NewRows([]string{"email", "nick", "password", "options", "status"}).
AddRow("admin@cloudreve.org", "admin", "CKLmDKa1C9SD64vU:76adadd4fd4bad86959155f6f7bc8993c94e7adf", "{}", model.NotActivicated),
2019-11-14 01:51:59 -05:00
policyRows: sqlmock.NewRows([]string{"name", "type", "options"}).
AddRow("默认上传策略", "local", "{\"op_name\":\"123\"}"),
2019-11-12 01:45:27 -05:00
reqBody: `{"userName":"admin@cloudreve.org","captchaCode":"captchaCode","Password":"admin"}`,
2019-11-12 03:18:58 -05:00
expected: serializer.Err(403, "该账号未激活", nil),
2019-11-12 01:45:27 -05:00
},
}
2019-11-13 05:34:29 -05:00
for k, testCase := range testCases {
2019-11-12 01:45:27 -05:00
if testCase.settingRows != nil {
mock.ExpectQuery("^SELECT (.+)").WillReturnRows(testCase.settingRows)
}
if testCase.userRows != nil {
mock.ExpectQuery("^SELECT (.+)").WillReturnRows(testCase.userRows)
}
2019-11-14 01:51:59 -05:00
if testCase.policyRows != nil {
mock.ExpectQuery("^SELECT \\* FROM `(.+)` WHERE `(.+)`\\.`deleted_at` IS NULL AND \\(\\(`policies`.`id` = 1\\)\\)(.+)$").WillReturnRows(testCase.policyRows)
}
2019-11-12 01:45:27 -05:00
req, _ := http.NewRequest(
"POST",
2019-11-23 03:58:56 -05:00
"/api/v3/user/session",
2019-11-12 01:45:27 -05:00
bytes.NewReader([]byte(testCase.reqBody)),
)
router.ServeHTTP(w, req)
2019-11-12 03:53:32 -05:00
asserts.Equal(200, w.Code)
expectedJSON, _ := json.Marshal(testCase.expected)
2019-11-13 05:34:29 -05:00
asserts.JSONEq(string(expectedJSON), w.Body.String(), "测试用例:%d", k)
2019-11-12 03:18:58 -05:00
2019-11-12 01:45:27 -05:00
w.Body.Reset()
asserts.NoError(mock.ExpectationsWereMet())
model.ClearCache()
}
}
2019-11-12 03:53:32 -05:00
func TestSessionAuthCheck(t *testing.T) {
asserts := assert.New(t)
router := InitRouter()
w := httptest.NewRecorder()
mock.ExpectQuery("^SELECT (.+)").WillReturnRows(sqlmock.NewRows([]string{"email", "nick", "password", "options"}).
AddRow("admin@cloudreve.org", "admin", "CKLmDKa1C9SD64vU:76adadd4fd4bad86959155f6f7bc8993c94e7adf", "{}"))
expectedUser, _ := model.GetUserByID(1)
testCases := []struct {
userRows *sqlmock.Rows
sessionMock map[string]interface{}
contextMock map[string]interface{}
expected interface{}
}{
// 未登录
{
expected: serializer.CheckLogin(),
},
// 登录正常
{
userRows: sqlmock.NewRows([]string{"email", "nick", "password", "options"}).
AddRow("admin@cloudreve.org", "admin", "CKLmDKa1C9SD64vU:76adadd4fd4bad86959155f6f7bc8993c94e7adf", "{}"),
sessionMock: map[string]interface{}{"user_id": 1},
expected: serializer.BuildUserResponse(expectedUser),
},
// UID不存在
{
userRows: sqlmock.NewRows([]string{"email", "nick", "password", "options"}),
sessionMock: map[string]interface{}{"user_id": -1},
expected: serializer.CheckLogin(),
},
}
for _, testCase := range testCases {
req, _ := http.NewRequest(
"GET",
2019-11-23 03:58:56 -05:00
"/api/v3/user/me",
2019-11-12 03:53:32 -05:00
nil,
)
if testCase.userRows != nil {
mock.ExpectQuery("^SELECT (.+)").WillReturnRows(testCase.userRows)
}
middleware.ContextMock = testCase.contextMock
middleware.SessionMock = testCase.sessionMock
router.ServeHTTP(w, req)
expectedJSON, _ := json.Marshal(testCase.expected)
asserts.Equal(200, w.Code)
asserts.JSONEq(string(expectedJSON), w.Body.String())
asserts.NoError(mock.ExpectationsWereMet())
w.Body.Reset()
}
}
2019-11-23 02:09:46 -05:00
func TestSiteConfigRoute(t *testing.T) {
switchToMemDB()
asserts := assert.New(t)
router := InitRouter()
w := httptest.NewRecorder()
req, _ := http.NewRequest(
"GET",
2019-11-23 03:58:56 -05:00
"/api/v3/site/config",
2019-11-23 02:09:46 -05:00
nil,
)
router.ServeHTTP(w, req)
asserts.Equal(200, w.Code)
asserts.Contains(w.Body.String(), "Cloudreve")
w.Body.Reset()
// 消除无效值
model.DB.Model(&model.Setting{
Model: gorm.Model{
ID: 2,
},
}).UpdateColumn("name", "siteName_b")
req, _ = http.NewRequest(
"GET",
2019-11-23 03:58:56 -05:00
"/api/v3/site/config",
2019-11-23 02:09:46 -05:00
nil,
)
router.ServeHTTP(w, req)
asserts.Equal(200, w.Code)
asserts.Contains(w.Body.String(), "\"title\":\"\"")
model.DB.Model(&model.Setting{
Model: gorm.Model{
ID: 2,
},
}).UpdateColumn("name", "siteName")
}
func TestListDirectoryRoute(t *testing.T) {
switchToMemDB()
asserts := assert.New(t)
router := InitRouter()
w := httptest.NewRecorder()
// 成功
req, _ := http.NewRequest(
"GET",
"/api/v3/directory?path=/",
nil,
)
middleware.SessionMock = map[string]interface{}{"user_id": 1}
router.ServeHTTP(w, req)
asserts.Equal(200, w.Code)
resJSON := &serializer.Response{}
err := json.Unmarshal(w.Body.Bytes(), resJSON)
asserts.NoError(err)
asserts.Equal(0, resJSON.Code)
w.Body.Reset()
// 缺少参数
req, _ = http.NewRequest(
"GET",
"/api/v3/directory",
nil,
)
middleware.SessionMock = map[string]interface{}{"user_id": 1}
router.ServeHTTP(w, req)
asserts.Equal(200, w.Code)
resJSON = &serializer.Response{}
err = json.Unmarshal(w.Body.Bytes(), resJSON)
asserts.NoError(err)
asserts.NotEqual(0, resJSON.Code)
}