mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-06 15:46:37 +08:00
refactor(architecture): eliminate internal package and complete cordis single-owner model and repository migration
- Physically purged all legacy internal/ packages, centralized pkg/model/ and pkg/repository/ - Migrated domain models and database repositories into self-contained owner plugins (user, auth, message_gateway, admin, upload, risk_control) - Decoupled cross-plugin interactions via pure core/contracts and typed EventBus - Ensured 100% test coverage pass, zero data races (-race clean), and 0 lint issues in make code-check
This commit is contained in:
@@ -0,0 +1,227 @@
|
||||
// Copyright 2026 Arctel.net
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/Rain-kl/Wavelet/pkg/testhelper"
|
||||
userdomain "github.com/Rain-kl/Wavelet/plugins/domain/user"
|
||||
)
|
||||
|
||||
func TestResetPasswdCmd_WithUserAndPassword(t *testing.T) {
|
||||
dbConn, _, cleanup := testhelper.SetupTestEnvironment(t)
|
||||
defer cleanup()
|
||||
|
||||
// Seed test user
|
||||
user := userdomain.User{
|
||||
ID: 1001,
|
||||
Username: "testuser1",
|
||||
Nickname: "Test User 1",
|
||||
Email: "test1@example.com",
|
||||
IsActive: true,
|
||||
LastLoginAt: time.Now(),
|
||||
}
|
||||
_ = user.SetEncryptedPassword("oldpassword")
|
||||
if err := dbConn.Create(&user).Error; err != nil {
|
||||
t.Fatalf("failed to create test user: %v", err)
|
||||
}
|
||||
|
||||
// Create access token to test invalidation/deletion
|
||||
token := userdomain.AccessToken{
|
||||
ID: 1,
|
||||
UserID: user.ID,
|
||||
Name: "testtoken",
|
||||
TokenHash: "somehash",
|
||||
MaskedToken: "some...",
|
||||
}
|
||||
if err := dbConn.Create(&token).Error; err != nil {
|
||||
t.Fatalf("failed to create access token: %v", err)
|
||||
}
|
||||
|
||||
// Override PreRun to bypass goose migrations in unit tests
|
||||
oldPreRun := resetPasswdCmd.PreRun
|
||||
resetPasswdCmd.PreRun = nil
|
||||
defer func() { resetPasswdCmd.PreRun = oldPreRun }()
|
||||
|
||||
// Execute command with args
|
||||
rootCmd.SetArgs([]string{"reset-passwd", "--user", "testuser1", "--password", "newpassword123"})
|
||||
|
||||
// Capture output
|
||||
oldStdout := os.Stdout
|
||||
r, w, _ := os.Pipe()
|
||||
os.Stdout = w
|
||||
|
||||
err := rootCmd.Execute()
|
||||
w.Close()
|
||||
os.Stdout = oldStdout
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("command execute failed: %v", err)
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
_, _ = io.Copy(&buf, r)
|
||||
output := buf.String()
|
||||
|
||||
if !bytes.Contains([]byte(output), []byte("成功重置密码!")) {
|
||||
t.Errorf("expected output to contain success message, got: %s", output)
|
||||
}
|
||||
|
||||
// Verify password in DB
|
||||
var dbUser userdomain.User
|
||||
if err := dbConn.Where("id = ?", user.ID).First(&dbUser).Error; err != nil {
|
||||
t.Fatalf("failed to query user from DB: %v", err)
|
||||
}
|
||||
if !dbUser.CheckPassword("newpassword123") {
|
||||
t.Errorf("password was not updated correctly in DB")
|
||||
}
|
||||
|
||||
// Verify token deleted
|
||||
var count int64
|
||||
dbConn.Model(&userdomain.AccessToken{}).Where("user_id = ?", user.ID).Count(&count)
|
||||
if count != 0 {
|
||||
t.Errorf("expected access tokens to be deleted, got %d", count)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResetPasswdCmd_WithUserAndRandomPassword(t *testing.T) {
|
||||
dbConn, _, cleanup := testhelper.SetupTestEnvironment(t)
|
||||
defer cleanup()
|
||||
|
||||
// Seed test user
|
||||
user := userdomain.User{
|
||||
ID: 1002,
|
||||
Username: "testuser2",
|
||||
Nickname: "Test User 2",
|
||||
Email: "test2@example.com",
|
||||
IsActive: true,
|
||||
LastLoginAt: time.Now(),
|
||||
}
|
||||
_ = user.SetEncryptedPassword("oldpassword")
|
||||
if err := dbConn.Create(&user).Error; err != nil {
|
||||
t.Fatalf("failed to create test user: %v", err)
|
||||
}
|
||||
|
||||
// Override PreRun
|
||||
oldPreRun := resetPasswdCmd.PreRun
|
||||
resetPasswdCmd.PreRun = nil
|
||||
defer func() { resetPasswdCmd.PreRun = oldPreRun }()
|
||||
|
||||
// Reset flags
|
||||
usernameFlag = ""
|
||||
passwordFlag = ""
|
||||
|
||||
// Execute command with args (no --password)
|
||||
rootCmd.SetArgs([]string{"reset-passwd", "--user", "testuser2"})
|
||||
|
||||
// Capture output
|
||||
oldStdout := os.Stdout
|
||||
r, w, _ := os.Pipe()
|
||||
os.Stdout = w
|
||||
|
||||
err := rootCmd.Execute()
|
||||
w.Close()
|
||||
os.Stdout = oldStdout
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("command execute failed: %v", err)
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
_, _ = io.Copy(&buf, r)
|
||||
output := buf.String()
|
||||
|
||||
if !bytes.Contains([]byte(output), []byte("成功重置密码!")) {
|
||||
t.Errorf("expected output to contain success message, got: %s", output)
|
||||
}
|
||||
|
||||
// Verify password in DB (should be updated and not equal to old one)
|
||||
var dbUser userdomain.User
|
||||
if err := dbConn.Where("id = ?", user.ID).First(&dbUser).Error; err != nil {
|
||||
t.Fatalf("failed to query user from DB: %v", err)
|
||||
}
|
||||
if dbUser.CheckPassword("oldpassword") {
|
||||
t.Errorf("expected password to change, but it matches the old one")
|
||||
}
|
||||
}
|
||||
|
||||
func TestResetPasswdCmd_InteractiveMode(t *testing.T) {
|
||||
dbConn, _, cleanup := testhelper.SetupTestEnvironment(t)
|
||||
defer cleanup()
|
||||
|
||||
// Seed test user
|
||||
user := userdomain.User{
|
||||
ID: 1003,
|
||||
Username: "testuser3",
|
||||
Nickname: "Test User 3",
|
||||
Email: "test3@example.com",
|
||||
IsActive: true,
|
||||
LastLoginAt: time.Now(),
|
||||
}
|
||||
_ = user.SetEncryptedPassword("oldpassword")
|
||||
if err := dbConn.Create(&user).Error; err != nil {
|
||||
t.Fatalf("failed to create test user: %v", err)
|
||||
}
|
||||
|
||||
// Override PreRun
|
||||
oldPreRun := resetPasswdCmd.PreRun
|
||||
resetPasswdCmd.PreRun = nil
|
||||
defer func() { resetPasswdCmd.PreRun = oldPreRun }()
|
||||
|
||||
// Mock stdin
|
||||
inR, inW, err := os.Pipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer inR.Close()
|
||||
defer inW.Close()
|
||||
|
||||
oldStdin := os.Stdin
|
||||
os.Stdin = inR
|
||||
defer func() { os.Stdin = oldStdin }()
|
||||
|
||||
// Write username to stdin
|
||||
_, _ = inW.WriteString("testuser3\n")
|
||||
inW.Close()
|
||||
|
||||
// Reset flags
|
||||
usernameFlag = ""
|
||||
passwordFlag = ""
|
||||
rootCmd.SetArgs([]string{"reset-passwd"})
|
||||
|
||||
// Capture output
|
||||
oldStdout := os.Stdout
|
||||
r, w, _ := os.Pipe()
|
||||
os.Stdout = w
|
||||
|
||||
err = rootCmd.Execute()
|
||||
w.Close()
|
||||
os.Stdout = oldStdout
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("command execute failed: %v", err)
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
_, _ = io.Copy(&buf, r)
|
||||
output := buf.String()
|
||||
|
||||
if !bytes.Contains([]byte(output), []byte("成功重置密码!")) {
|
||||
t.Errorf("expected output to contain success message, got: %s", output)
|
||||
}
|
||||
|
||||
// Verify user password changed in DB
|
||||
var dbUser userdomain.User
|
||||
if err := dbConn.Where("id = ?", user.ID).First(&dbUser).Error; err != nil {
|
||||
t.Fatalf("failed to query user from DB: %v", err)
|
||||
}
|
||||
if dbUser.CheckPassword("oldpassword") {
|
||||
t.Errorf("expected password to change, but it matches the old one")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user