You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cloudreve/routers/router_test.go

242 lines
7.9 KiB

5 years ago
package routers
import (
"bytes"
"database/sql"
"encoding/json"
"errors"
"github.com/DATA-DOG/go-sqlmock"
"github.com/HFO4/cloudreve/middleware"
"github.com/HFO4/cloudreve/models"
"github.com/HFO4/cloudreve/pkg/serializer"
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
5 years ago
"github.com/mojocn/base64Captcha"
5 years ago
"github.com/stretchr/testify/assert"
"net/http"
"net/http/httptest"
"testing"
)
var mock sqlmock.Sqlmock
// TestMain 初始化数据库Mock
func TestMain(m *testing.M) {
// 设置gin为测试模式
gin.SetMode(gin.TestMode)
var db *sql.DB
var err error
db, mock, err = sqlmock.New()
if err != nil {
panic("An error was not expected when opening a stub database connection")
}
model.DB, _ = gorm.Open("mysql", db)
defer db.Close()
m.Run()
}
5 years ago
func TestPing(t *testing.T) {
asserts := assert.New(t)
router := InitRouter()
w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/Api/V3/Ping", nil)
router.ServeHTTP(w, req)
assert.Equal(t, 200, w.Code)
asserts.Contains(w.Body.String(), "Pong")
}
5 years ago
func TestCaptcha(t *testing.T) {
asserts := assert.New(t)
router := InitRouter()
w := httptest.NewRecorder()
req, _ := http.NewRequest(
"GET",
"/Api/V3/Captcha",
nil,
)
router.ServeHTTP(w, req)
asserts.Equal(200, w.Code)
asserts.Contains(w.Body.String(), "base64")
}
func TestUserSession(t *testing.T) {
asserts := assert.New(t)
router := InitRouter()
w := httptest.NewRecorder()
5 years ago
// 创建测试用验证码
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,
}
testCases := []struct {
settingRows *sqlmock.Rows
userRows *sqlmock.Rows
policyRows *sqlmock.Rows
reqBody string
expected interface{}
}{
// 登录信息正确,不需要验证码
{
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", "{}"), policyRows: sqlmock.NewRows([]string{"name", "type", "options"}).
AddRow("默认上传策略", "local", "{\"op_name\":\"123\"}"),
reqBody: `{"userName":"admin@cloudreve.org","captchaCode":"captchaCode","Password":"admin"}`,
expected: serializer.BuildUserResponse(model.User{
Email: "admin@cloudreve.org",
Nick: "admin",
}),
},
5 years ago
// 登录信息正确,需要验证码,验证码错误
{
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", "{}"),
policyRows: sqlmock.NewRows([]string{"name", "type", "options"}).
AddRow("默认上传策略", "local", "{\"op_name\":\"123\"}"),
5 years ago
reqBody: `{"userName":"admin@cloudreve.org","captchaCode":"captchaCode","Password":"admin"}`,
expected: serializer.ParamErr("验证码错误", nil),
},
// 邮箱正确密码错误
{
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", "{}"),
policyRows: sqlmock.NewRows([]string{"name", "type", "options"}).
AddRow("默认上传策略", "local", "{\"op_name\":\"123\"}"),
reqBody: `{"userName":"admin@cloudreve.org","captchaCode":"captchaCode","Password":"admin123"}`,
expected: serializer.Err(401, "用户邮箱或密码错误", nil),
},
//邮箱格式不正确
{
reqBody: `{"userName":"admin@cloudreve","captchaCode":"captchaCode","Password":"admin123"}`,
expected: serializer.Err(40001, "邮箱格式不正确", errors.New("Key: 'UserLoginService.UserName' Error:Field validation for 'UserName' failed on the 'email' tag")),
},
// 用户被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),
policyRows: sqlmock.NewRows([]string{"name", "type", "options"}).
AddRow("默认上传策略", "local", "{\"op_name\":\"123\"}"),
reqBody: `{"userName":"admin@cloudreve.org","captchaCode":"captchaCode","Password":"admin"}`,
expected: serializer.Err(403, "该账号已被封禁", nil),
},
// 用户未激活
{
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),
policyRows: sqlmock.NewRows([]string{"name", "type", "options"}).
AddRow("默认上传策略", "local", "{\"op_name\":\"123\"}"),
reqBody: `{"userName":"admin@cloudreve.org","captchaCode":"captchaCode","Password":"admin"}`,
expected: serializer.Err(403, "该账号未激活", nil),
},
}
5 years ago
for k, testCase := range testCases {
if testCase.settingRows != nil {
mock.ExpectQuery("^SELECT (.+)").WillReturnRows(testCase.settingRows)
}
if testCase.userRows != nil {
mock.ExpectQuery("^SELECT (.+)").WillReturnRows(testCase.userRows)
}
if testCase.policyRows != nil {
mock.ExpectQuery("^SELECT \\* FROM `(.+)` WHERE `(.+)`\\.`deleted_at` IS NULL AND \\(\\(`policies`.`id` = 1\\)\\)(.+)$").WillReturnRows(testCase.policyRows)
}
req, _ := http.NewRequest(
"POST",
"/Api/V3/User/Session",
bytes.NewReader([]byte(testCase.reqBody)),
)
router.ServeHTTP(w, req)
asserts.Equal(200, w.Code)
expectedJSON, _ := json.Marshal(testCase.expected)
5 years ago
asserts.JSONEq(string(expectedJSON), w.Body.String(), "测试用例:%d", k)
w.Body.Reset()
asserts.NoError(mock.ExpectationsWereMet())
model.ClearCache()
}
}
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",
"/Api/V3/User/Me",
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()
}
}