yumi-golang/internal/router/user_badge_routes_test.go
2026-05-15 19:42:02 +08:00

200 lines
6.0 KiB
Go

package router
import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"time"
"chatapp3-golang/internal/config"
"chatapp3-golang/internal/integration"
"chatapp3-golang/internal/model"
"chatapp3-golang/internal/repo"
"chatapp3-golang/internal/service/userbadge"
"github.com/gin-gonic/gin"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
type userBadgeAuthStub struct{}
func (userBadgeAuthStub) AuthenticateToken(context.Context, string) (integration.UserCredential, error) {
return integration.UserCredential{UserID: 123, SysOrigin: "LIKEI"}, nil
}
func (userBadgeAuthStub) AuthenticateConsoleToken(context.Context, string) (integration.ConsoleAccount, error) {
return integration.ConsoleAccount{}, nil
}
func TestUserBadgeCurrentRoute(t *testing.T) {
gin.SetMode(gin.TestMode)
db := newRouterUserBadgeDB(t)
now := time.Now().Add(time.Hour)
if err := db.Create(&model.UserBadgeBackpack{
ID: 1,
UserID: 123,
BadgeID: 501,
ExpireType: "TEMPORARY",
ExpireTime: now,
UseProps: true,
UpdateTime: time.Now(),
}).Error; err != nil {
t.Fatalf("create backpack: %v", err)
}
if err := db.Create(&model.SysBadgeConfig{
ID: 501,
Type: "ACTIVITY",
BadgeName: "Activity Badge",
BadgeKey: "ACTIVITY_BADGE",
}).Error; err != nil {
t.Fatalf("create badge config: %v", err)
}
if err := db.Create(&model.SysBadgePictureConfig{
ID: 601,
BadgeConfigID: 501,
SysOrigin: "LIKEI",
SelectURL: "https://cdn.example.com/activity.png",
}).Error; err != nil {
t.Fatalf("create badge picture: %v", err)
}
service := userbadge.NewService(db)
engine := NewRouter(config.Config{}, &repo.Repository{}, userBadgeAuthStub{}, Services{UserBadge: service})
req := httptest.NewRequest(http.MethodGet, "/app/user/badge/current", nil)
req.Header.Set("Authorization", "Bearer token")
rec := httptest.NewRecorder()
engine.ServeHTTP(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("status = %d body = %s", rec.Code, rec.Body.String())
}
var payload map[string]any
if err := json.Unmarshal(rec.Body.Bytes(), &payload); err != nil {
t.Fatalf("decode response: %v", err)
}
data, ok := payload["data"].(map[string]any)
if !ok {
t.Fatalf("data missing: %#v", payload)
}
shortBadges, ok := data["shortBadges"].([]any)
if !ok || len(shortBadges) != 1 {
t.Fatalf("shortBadges = %#v", data["shortBadges"])
}
item, ok := shortBadges[0].(map[string]any)
if !ok || item["type"] != "SHORT" || item["badgeId"] != "501" {
t.Fatalf("short badge item = %#v", shortBadges[0])
}
}
func TestUserBadgeCurrentRouteRequiresAuth(t *testing.T) {
gin.SetMode(gin.TestMode)
service := userbadge.NewService(newRouterUserBadgeDB(t))
engine := NewRouter(config.Config{}, &repo.Repository{}, userBadgeAuthStub{}, Services{UserBadge: service})
req := httptest.NewRequest(http.MethodGet, "/app/user/badge/current", nil)
rec := httptest.NewRecorder()
engine.ServeHTTP(rec, req)
if rec.Code != http.StatusUnauthorized {
t.Fatalf("status = %d body = %s, want 401", rec.Code, rec.Body.String())
}
}
func TestUserBadgeOtherRoute(t *testing.T) {
gin.SetMode(gin.TestMode)
db := newRouterUserBadgeDB(t)
targetUserID := int64(456)
if err := db.Create(&model.UserBadgeBackpack{
ID: 2,
UserID: targetUserID,
BadgeID: 502,
ExpireType: "TEMPORARY",
ExpireTime: time.Now().Add(time.Hour),
UseProps: true,
UpdateTime: time.Now(),
}).Error; err != nil {
t.Fatalf("create backpack: %v", err)
}
if err := db.Create(&model.SysBadgeConfig{
ID: 502,
Type: "ACHIEVEMENT",
BadgeName: "Achievement Badge",
BadgeKey: "ACHIEVEMENT_BADGE",
}).Error; err != nil {
t.Fatalf("create badge config: %v", err)
}
if err := db.Create(&model.SysBadgePictureConfig{
ID: 602,
BadgeConfigID: 502,
SysOrigin: "LIKEI",
SelectURL: "https://cdn.example.com/achievement.png",
}).Error; err != nil {
t.Fatalf("create badge picture: %v", err)
}
service := userbadge.NewService(db)
engine := NewRouter(config.Config{}, &repo.Repository{}, userBadgeAuthStub{}, Services{UserBadge: service})
req := httptest.NewRequest(http.MethodGet, "/app/user/badge/other?userId=456", nil)
req.Header.Set("Authorization", "Bearer token")
rec := httptest.NewRecorder()
engine.ServeHTTP(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("status = %d body = %s", rec.Code, rec.Body.String())
}
var payload map[string]any
if err := json.Unmarshal(rec.Body.Bytes(), &payload); err != nil {
t.Fatalf("decode response: %v", err)
}
data, ok := payload["data"].(map[string]any)
if !ok {
t.Fatalf("data missing: %#v", payload)
}
if data["userId"] != float64(targetUserID) {
t.Fatalf("userId = %#v, want target user", data["userId"])
}
shortBadges, ok := data["shortBadges"].([]any)
if !ok || len(shortBadges) != 1 {
t.Fatalf("shortBadges = %#v", data["shortBadges"])
}
item, ok := shortBadges[0].(map[string]any)
if !ok || item["sourceType"] != "ACHIEVEMENT" || item["badgeId"] != "502" {
t.Fatalf("short badge item = %#v", shortBadges[0])
}
}
func TestUserBadgeOtherRouteRequiresTargetUser(t *testing.T) {
gin.SetMode(gin.TestMode)
service := userbadge.NewService(newRouterUserBadgeDB(t))
engine := NewRouter(config.Config{}, &repo.Repository{}, userBadgeAuthStub{}, Services{UserBadge: service})
req := httptest.NewRequest(http.MethodGet, "/app/user/badge/other", nil)
req.Header.Set("Authorization", "Bearer token")
rec := httptest.NewRecorder()
engine.ServeHTTP(rec, req)
if rec.Code != http.StatusBadRequest {
t.Fatalf("status = %d body = %s, want 400", rec.Code, rec.Body.String())
}
}
func newRouterUserBadgeDB(t *testing.T) *gorm.DB {
t.Helper()
db, err := gorm.Open(sqlite.Open("file:"+t.Name()+"?mode=memory&cache=shared"), &gorm.Config{})
if err != nil {
t.Fatalf("open sqlite: %v", err)
}
if err := db.AutoMigrate(
&model.UserVipState{},
&model.UserBadgeBackpack{},
&model.SysBadgeConfig{},
&model.SysBadgePictureConfig{},
); err != nil {
t.Fatalf("migrate sqlite: %v", err)
}
return db
}