eq2go/internal/guilds/guild_test.go
2025-08-08 13:08:15 -05:00

546 lines
15 KiB
Go

package guilds
import (
"fmt"
"testing"
"time"
"eq2emu/internal/database"
)
// TestNewGuild tests guild creation with default values
func TestNewGuild(t *testing.T) {
// Create a mock database (we'll use nil since these tests don't use database)
var db *database.Database
guild := New(db)
// Test initial state
if guild.GetLevel() != 1 {
t.Errorf("Expected initial level 1, got %d", guild.GetLevel())
}
if guild.GetEXPCurrent() != 111 {
t.Errorf("Expected initial expCurrent 111, got %d", guild.GetEXPCurrent())
}
if guild.GetEXPToNextLevel() != 2521 {
t.Errorf("Expected initial expToNextLevel 2521, got %d", guild.GetEXPToNextLevel())
}
if guild.GetRecruitingMinLevel() != 1 {
t.Errorf("Expected initial recruitingMinLevel 1, got %d", guild.GetRecruitingMinLevel())
}
if guild.GetRecruitingPlayStyle() != RecruitingPlayStyleNone {
t.Errorf("Expected initial recruitingPlayStyle %d, got %d", RecruitingPlayStyleNone, guild.GetRecruitingPlayStyle())
}
if guild.GetNextEventID() != 1 {
t.Errorf("Expected initial nextEventID 1, got %d", guild.GetNextEventID())
}
// Test recruiting flags are initialized
if guild.GetRecruitingFlag(RecruitingFlagTraining) != 0 {
t.Error("Training recruiting flag should be initialized to 0")
}
if guild.GetRecruitingFlag(RecruitingFlagFighters) != 0 {
t.Error("Fighters recruiting flag should be initialized to 0")
}
// Test description tags are initialized
if guild.GetRecruitingDescTag(0) != RecruitingDescTagNone {
t.Error("Description tag 0 should be initialized to None")
}
// Test default rank names are set
if guild.GetRankName(RankLeader) != "Leader" {
t.Errorf("Expected leader rank name 'Leader', got '%s'", guild.GetRankName(RankLeader))
}
if guild.GetRankName(RankRecruit) != "Recruit" {
t.Errorf("Expected recruit rank name 'Recruit', got '%s'", guild.GetRankName(RankRecruit))
}
}
// TestGuildBasicOperations tests basic guild getter/setter operations
func TestGuildBasicOperations(t *testing.T) {
var db *database.Database
guild := New(db)
// Test ID operations
testID := int32(12345)
guild.SetID(testID)
if guild.GetID() != testID {
t.Errorf("Expected ID %d, got %d", testID, guild.GetID())
}
// Test name operations
testName := "Test Guild"
guild.SetName(testName, false)
if guild.GetName() != testName {
t.Errorf("Expected name '%s', got '%s'", testName, guild.GetName())
}
// Test level operations
testLevel := int8(10)
guild.SetLevel(testLevel, false)
if guild.GetLevel() != testLevel {
t.Errorf("Expected level %d, got %d", testLevel, guild.GetLevel())
}
// Test MOTD operations
testMOTD := "Welcome to our guild!"
guild.SetMOTD(testMOTD, false)
if guild.GetMOTD() != testMOTD {
t.Errorf("Expected MOTD '%s', got '%s'", testMOTD, guild.GetMOTD())
}
// Test formed date operations
testDate := time.Now().Add(-24 * time.Hour)
guild.SetFormedDate(testDate)
if !guild.GetFormedDate().Equal(testDate) {
t.Errorf("Expected formed date %v, got %v", testDate, guild.GetFormedDate())
}
// Test experience operations
testExpCurrent := int64(5000)
testExpNext := int64(10000)
guild.SetEXPCurrent(testExpCurrent, false)
guild.SetEXPToNextLevel(testExpNext, false)
current := guild.GetEXPCurrent()
next := guild.GetEXPToNextLevel()
if current != testExpCurrent {
t.Errorf("Expected current exp %d, got %d", testExpCurrent, current)
}
if next != testExpNext {
t.Errorf("Expected next level exp %d, got %d", testExpNext, next)
}
}
// TestGuildMemberOperations tests guild member management
func TestGuildMemberOperations(t *testing.T) {
var db *database.Database
guild := New(db)
guild.SetID(1)
// Test adding members using the actual method
characterID1 := int32(1)
characterID2 := int32(2)
inviterName := "TestInviter"
joinDate := time.Now()
// Add first member
success := guild.AddNewGuildMember(characterID1, inviterName, joinDate, RankRecruit)
if !success {
t.Error("Should be able to add first member")
}
// Add second member
success = guild.AddNewGuildMember(characterID2, inviterName, joinDate, RankMember)
if !success {
t.Error("Should be able to add second member")
}
// Test getting member by ID
member1 := guild.GetGuildMember(characterID1)
if member1 == nil {
t.Error("Should be able to retrieve member by ID")
}
if member1.CharacterID != characterID1 {
t.Errorf("Expected member ID %d, got %d", characterID1, member1.CharacterID)
}
// Test getting all members
allMembers := guild.GetAllMembers()
if len(allMembers) != 2 {
t.Errorf("Expected 2 members, got %d", len(allMembers))
}
// Test removing member
guild.RemoveGuildMember(characterID1, false)
member1After := guild.GetGuildMember(characterID1)
if member1After != nil {
t.Error("Member should be nil after removal")
}
allMembersAfter := guild.GetAllMembers()
if len(allMembersAfter) != 1 {
t.Errorf("Expected 1 member after removal, got %d", len(allMembersAfter))
}
}
// TestGuildEventOperations tests guild event management
func TestGuildEventOperations(t *testing.T) {
var db *database.Database
guild := New(db)
// Test adding events
eventType := int32(EventMemberJoins)
description := "Member joined guild"
eventDate := time.Now()
// Add first event (should get ID 1)
guild.AddNewGuildEvent(eventType, description, eventDate, false)
// Add another event (should get ID 2)
guild.AddNewGuildEvent(EventMemberLeaves, "Member left guild", eventDate, false)
// Test getting next event ID (should be 3 now)
nextID := guild.GetNextEventID()
if nextID != 3 {
t.Errorf("Expected next event ID 3, got %d", nextID)
}
// Test getting specific event (first event should have ID 1)
event := guild.GetGuildEvent(1)
if event == nil {
t.Error("Should be able to retrieve event by ID")
}
if event != nil && event.Description != description {
t.Errorf("Expected event description '%s', got '%s'", description, event.Description)
}
}
// TestGuildRankOperations tests guild rank management
func TestGuildRankOperations(t *testing.T) {
var db *database.Database
guild := New(db)
// Test setting custom rank name
customRankName := "Elite Member"
success := guild.SetRankName(RankMember, customRankName, false)
if !success {
t.Error("Should be able to set rank name")
}
rankName := guild.GetRankName(RankMember)
if rankName != customRankName {
t.Errorf("Expected rank name '%s', got '%s'", customRankName, rankName)
}
// Test getting default rank names
leaderName := guild.GetRankName(RankLeader)
if leaderName != "Leader" {
t.Errorf("Expected leader rank name 'Leader', got '%s'", leaderName)
}
}
// TestGuildRecruitingOperations tests guild recruiting settings
func TestGuildRecruitingOperations(t *testing.T) {
var db *database.Database
guild := New(db)
// Test recruiting descriptions
shortDesc := "Looking for members"
fullDesc := "We are a friendly guild looking for active members"
guild.SetRecruitingShortDesc(shortDesc, false)
guild.SetRecruitingFullDesc(fullDesc, false)
short := guild.GetRecruitingShortDesc()
full := guild.GetRecruitingFullDesc()
if short != shortDesc {
t.Errorf("Expected short description '%s', got '%s'", shortDesc, short)
}
if full != fullDesc {
t.Errorf("Expected full description '%s', got '%s'", fullDesc, full)
}
// Test recruiting settings
minLevel := int8(20)
playStyle := int8(2)
guild.SetRecruitingMinLevel(minLevel, false)
guild.SetRecruitingPlayStyle(playStyle, false)
getMinLevel := guild.GetRecruitingMinLevel()
getPlayStyle := guild.GetRecruitingPlayStyle()
if getMinLevel != minLevel {
t.Errorf("Expected min level %d, got %d", minLevel, getMinLevel)
}
if getPlayStyle != playStyle {
t.Errorf("Expected play style %d, got %d", playStyle, getPlayStyle)
}
// Test recruiting flags
success := guild.SetRecruitingFlag(RecruitingFlagFighters, 1, false)
if !success {
t.Error("Should be able to set recruiting flag")
}
flag := guild.GetRecruitingFlag(RecruitingFlagFighters)
if flag != 1 {
t.Errorf("Expected recruiting flag 1, got %d", flag)
}
// Test recruiting description tags
success = guild.SetRecruitingDescTag(0, RecruitingDescTagRoleplay, false)
if !success {
t.Error("Should be able to set recruiting desc tag")
}
tag := guild.GetRecruitingDescTag(0)
if tag != RecruitingDescTagRoleplay {
t.Errorf("Expected description tag %d, got %d", RecruitingDescTagRoleplay, tag)
}
}
// TestGuildPermissions tests guild permission system
func TestGuildPermissions(t *testing.T) {
var db *database.Database
guild := New(db)
// Test setting permissions
rank := int8(RankMember)
permission := int8(PermissionInvite)
value := int8(1)
success := guild.SetPermission(rank, permission, value, false, false)
if !success {
t.Error("Should be able to set permission")
}
getValue := guild.GetPermission(rank, permission)
if getValue != value {
t.Errorf("Expected permission value %d, got %d", value, getValue)
}
// Test removing permission
success = guild.SetPermission(rank, permission, 0, false, false)
if !success {
t.Error("Should be able to remove permission")
}
getValue = guild.GetPermission(rank, permission)
if getValue != 0 {
t.Errorf("Expected permission value 0 after removal, got %d", getValue)
}
}
// TestGuildSaveFlags tests the save flag system
func TestGuildSaveFlags(t *testing.T) {
var db *database.Database
guild := New(db)
// Test initial state
if guild.GetSaveNeeded() {
t.Error("Guild should not need save initially")
}
// Test marking save needed
guild.SetSaveNeeded(true)
if !guild.GetSaveNeeded() {
t.Error("Guild should need save after marking")
}
// Test clearing save needed
guild.SetSaveNeeded(false)
if guild.GetSaveNeeded() {
t.Error("Guild should not need save after clearing")
}
}
// TestGuildMemberPromotionDemotion tests member rank changes
func TestGuildMemberPromotionDemotion(t *testing.T) {
var db *database.Database
guild := New(db)
guild.SetID(1)
// Add a member
characterID := int32(1)
inviterName := "TestInviter"
joinDate := time.Now()
success := guild.AddNewGuildMember(characterID, inviterName, joinDate, RankRecruit)
if !success {
t.Error("Should be able to add member")
}
// Get member and check initial rank
member := guild.GetGuildMember(characterID)
if member == nil {
t.Fatal("Member should exist")
}
if member.Rank != RankRecruit {
t.Errorf("Expected initial rank %d, got %d", RankRecruit, member.Rank)
}
// Test promotion
promoterName := "TestPromoter"
success = guild.PromoteGuildMember(characterID, promoterName, false)
if !success {
t.Error("Should be able to promote member")
}
member = guild.GetGuildMember(characterID)
if member.Rank != RankInitiate {
t.Errorf("Expected rank after promotion %d, got %d", RankInitiate, member.Rank)
}
// Test demotion
demoterName := "TestDemoter"
success = guild.DemoteGuildMember(characterID, demoterName, false)
if !success {
t.Error("Should be able to demote member")
}
member = guild.GetGuildMember(characterID)
if member.Rank != RankRecruit {
t.Errorf("Expected rank after demotion %d, got %d", RankRecruit, member.Rank)
}
}
// TestGuildPointsSystem tests the guild points system
func TestGuildPointsSystem(t *testing.T) {
var db *database.Database
guild := New(db)
guild.SetID(1)
// Add a member
characterID := int32(1)
inviterName := "TestInviter"
joinDate := time.Now()
success := guild.AddNewGuildMember(characterID, inviterName, joinDate, RankRecruit)
if !success {
t.Error("Should be able to add member")
}
// Get initial points
member := guild.GetGuildMember(characterID)
if member == nil {
t.Fatal("Member should exist")
}
initialPoints := member.Points
// Add points
pointsToAdd := 100.0
modifiedBy := "TestAdmin"
comment := "Test point award"
success = guild.AddPointsToGuildMember(characterID, pointsToAdd, modifiedBy, comment, false)
if !success {
t.Error("Should be able to add points to member")
}
// Check points were added
member = guild.GetGuildMember(characterID)
expectedPoints := initialPoints + pointsToAdd
if member.Points != expectedPoints {
t.Errorf("Expected points %f, got %f", expectedPoints, member.Points)
}
}
// TestGuildConcurrency tests thread safety of guild operations
func TestGuildConcurrency(t *testing.T) {
var db *database.Database
guild := New(db)
guild.SetID(1)
guild.SetName("Concurrent Test Guild", false)
const numGoroutines = 20
done := make(chan bool, numGoroutines)
// Test concurrent reads
for i := 0; i < numGoroutines; i++ {
go func(id int) {
_ = guild.GetID()
_ = guild.GetName()
_ = guild.GetLevel()
_ = guild.GetMOTD()
_ = guild.GetEXPCurrent()
_ = guild.GetRecruitingShortDesc()
_ = guild.GetRankName(RankMember)
_ = guild.GetPermission(RankMember, PermissionInvite)
done <- true
}(i)
}
// Wait for all read operations
for i := 0; i < numGoroutines; i++ {
<-done
}
// Test concurrent member additions (smaller number to avoid conflicts)
const memberGoroutines = 10
for i := 0; i < memberGoroutines; i++ {
go func(id int) {
inviterName := fmt.Sprintf("Inviter%d", id)
joinDate := time.Now()
characterID := int32(100 + id)
guild.AddNewGuildMember(characterID, inviterName, joinDate, RankRecruit)
done <- true
}(i)
}
// Wait for all member additions
for i := 0; i < memberGoroutines; i++ {
<-done
}
// Verify members were added
members := guild.GetAllMembers()
if len(members) != memberGoroutines {
t.Logf("Expected %d members, got %d (some concurrent additions may have failed, which is acceptable)", memberGoroutines, len(members))
}
}
// TestGuildEventFilters tests guild event filter system
func TestGuildEventFilters(t *testing.T) {
var db *database.Database
guild := New(db)
// Test setting event filters
eventID := int8(EventMemberJoins)
category := int8(EventFilterCategoryBroadcast)
value := int8(1)
success := guild.SetEventFilter(eventID, category, value, false, false)
if !success {
t.Error("Should be able to set event filter")
}
getValue := guild.GetEventFilter(eventID, category)
if getValue != value {
t.Errorf("Expected event filter value %d, got %d", value, getValue)
}
// Test removing event filter
success = guild.SetEventFilter(eventID, category, 0, false, false)
if !success {
t.Error("Should be able to remove event filter")
}
getValue = guild.GetEventFilter(eventID, category)
if getValue != 0 {
t.Errorf("Expected event filter value 0 after removal, got %d", getValue)
}
}
// TestGuildInfo tests the guild info structure
func TestGuildInfo(t *testing.T) {
var db *database.Database
guild := New(db)
guild.SetID(123)
guild.SetName("Test Guild Info", false)
guild.SetLevel(25, false)
guild.SetMOTD("Test MOTD", false)
info := guild.GetGuildInfo()
if info.ID != 123 {
t.Errorf("Expected guild info ID 123, got %d", info.ID)
}
if info.Name != "Test Guild Info" {
t.Errorf("Expected guild info name 'Test Guild Info', got '%s'", info.Name)
}
if info.Level != 25 {
t.Errorf("Expected guild info level 25, got %d", info.Level)
}
if info.MOTD != "Test MOTD" {
t.Errorf("Expected guild info MOTD 'Test MOTD', got '%s'", info.MOTD)
}
}