单元测试

This commit is contained in:
richjohnrambo
2026-08-14 23:37:31 +08:00
parent 170bbdca76
commit 04c7a148e1
4 changed files with 138 additions and 29 deletions
+82
View File
@@ -1,15 +1,84 @@
package main
import (
"encoding/base64"
"net/http/httptest"
"testing"
"time"
"github.com/golang/mock/gomock"
"github.com/tinode/chat/server/auth"
"github.com/tinode/chat/server/auth/mock_auth"
"github.com/tinode/chat/server/store"
"github.com/tinode/chat/server/store/mock_store"
"github.com/tinode/chat/server/store/types"
)
func TestAuthFileRequestFromSessionRequiresTenant(t *testing.T) {
oldSessionStore := globals.sessionStore
globals.sessionStore = NewSessionStore(time.Minute)
defer func() { globals.sessionStore = oldSessionStore }()
sess, _ := globals.sessionStore.NewSession(httptest.NewRecorder(), "file-test-sid")
sess.uid = types.Uid(42)
if _, _, _, err := authFileRequest("", "", sess.sid, ""); err != types.ErrFailed {
t.Fatalf("session without tenant: got %v, want %v", err, types.ErrFailed)
}
sess.tenantID = types.TenantID(7)
principal, challenge, _, err := authFileRequest("", "", sess.sid, "")
if err != nil {
t.Fatal(err)
}
if challenge != nil {
t.Fatal("unexpected challenge")
}
if principal.TenantID != sess.tenantID || principal.UID != sess.uid {
t.Fatalf("principal mismatch: got %+v, want tenant=%d uid=%s", principal, sess.tenantID, sess.uid)
}
}
func TestAuthFileRequestFromTokenReturnsPrincipal(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
oldStore := store.Store
defer func() { store.Store = oldStore }()
mockStore := mock_store.NewMockPersistentStorageInterface(ctrl)
tokenAuth := mock_auth.NewMockAuthHandler(ctrl)
mockStore.EXPECT().GetLogicalAuthHandler("token").Return(tokenAuth)
tokenAuth.EXPECT().IsInitialized().Return(true)
tokenAuth.EXPECT().Authenticate(auth.AuthContext{RemoteAddr: "203.0.113.10"}, []byte("token-1")).
Return(&auth.Rec{TenantID: 7, Uid: 42, AuthLevel: auth.LevelAuth}, nil, nil)
store.Store = mockStore
principal, challenge, _, err := authFileRequest("token", base64.StdEncoding.EncodeToString([]byte("token-1")), "", "203.0.113.10")
if err != nil {
t.Fatal(err)
}
if challenge != nil {
t.Fatal("unexpected challenge")
}
if principal.TenantID != 7 || principal.UID != 42 {
t.Fatalf("principal mismatch: %#v", principal)
}
}
func TestAuthFileRequestAllowsUnauthenticatedNewAccountPath(t *testing.T) {
principal, challenge, _, err := authFileRequest("", "", "", "")
if err != nil {
t.Fatal(err)
}
if challenge != nil {
t.Fatal("unexpected challenge")
}
if !principal.TenantID.IsZero() || !principal.UID.IsZero() {
t.Fatalf("principal should be empty for unauthenticated request: %+v", principal)
}
}
func TestAuthorizeLargeFileDownloadDenied(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
@@ -31,6 +100,19 @@ func TestAuthorizeLargeFileDownloadDenied(t *testing.T) {
}
}
func TestAuthorizeLargeFileDownloadRejectsCrossTenant(t *testing.T) {
fd := &types.FileDef{
ObjHeader: types.ObjHeader{Id: types.Uid(100).String(), UpdatedAt: time.Date(2026, 8, 13, 9, 0, 0, 0, time.UTC)},
TenantID: 8,
Status: types.UploadCompleted,
MimeType: "text/plain",
Location: "notes.txt",
}
if err := authorizeLargeFileDownload(7, 42, "", fd); err != types.ErrNotFound {
t.Fatalf("expected not found for cross-tenant file, got %v", err)
}
}
func TestContentDispositionAttachmentSanitizesName(t *testing.T) {
fd := &types.FileDef{
ObjHeader: types.ObjHeader{Id: types.Uid(100).String()},