单元测试
This commit is contained in:
@@ -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()},
|
||||
|
||||
Reference in New Issue
Block a user