341 lines
8.7 KiB
Go
341 lines
8.7 KiB
Go
package chat
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"eq2emu/internal/database"
|
|
)
|
|
|
|
func TestNew(t *testing.T) {
|
|
db, err := database.NewSQLite("file::memory:?mode=memory&cache=shared")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create test database: %v", err)
|
|
}
|
|
defer db.Close()
|
|
|
|
// Test creating a new channel
|
|
channel := New(db)
|
|
if channel == nil {
|
|
t.Fatal("New returned nil")
|
|
}
|
|
|
|
if !channel.IsNew() {
|
|
t.Error("New channel should be marked as new")
|
|
}
|
|
|
|
// Test setting values
|
|
channel.ID = 1001
|
|
channel.Name = "Test Channel"
|
|
channel.ChannelType = ChannelTypeCustom
|
|
|
|
if channel.GetID() != 1001 {
|
|
t.Errorf("Expected GetID() to return 1001, got %d", channel.GetID())
|
|
}
|
|
|
|
if channel.GetName() != "Test Channel" {
|
|
t.Errorf("Expected GetName() to return 'Test Channel', got %s", channel.GetName())
|
|
}
|
|
|
|
if channel.GetType() != ChannelTypeCustom {
|
|
t.Errorf("Expected GetType() to return %d, got %d", ChannelTypeCustom, channel.GetType())
|
|
}
|
|
}
|
|
|
|
func TestNewWithData(t *testing.T) {
|
|
db, err := database.NewSQLite("file::memory:?mode=memory&cache=shared")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create test database: %v", err)
|
|
}
|
|
defer db.Close()
|
|
|
|
channel := NewWithData(100, "Auction", ChannelTypeWorld, db)
|
|
if channel == nil {
|
|
t.Fatal("NewWithData returned nil")
|
|
}
|
|
|
|
if channel.GetID() != 100 {
|
|
t.Errorf("Expected ID 100, got %d", channel.GetID())
|
|
}
|
|
|
|
if channel.GetName() != "Auction" {
|
|
t.Errorf("Expected name 'Auction', got '%s'", channel.GetName())
|
|
}
|
|
|
|
if channel.GetType() != ChannelTypeWorld {
|
|
t.Errorf("Expected type %d, got %d", ChannelTypeWorld, channel.GetType())
|
|
}
|
|
|
|
if !channel.IsNew() {
|
|
t.Error("NewWithData should create new channel")
|
|
}
|
|
}
|
|
|
|
func TestChannelGettersAndSetters(t *testing.T) {
|
|
db, _ := database.NewSQLite("file::memory:?mode=memory&cache=shared")
|
|
defer db.Close()
|
|
|
|
channel := NewWithData(123, "Test Channel", ChannelTypeCustom, db)
|
|
|
|
// Test getters
|
|
if id := channel.GetID(); id != 123 {
|
|
t.Errorf("GetID() = %v, want 123", id)
|
|
}
|
|
|
|
if name := channel.GetName(); name != "Test Channel" {
|
|
t.Errorf("GetName() = %v, want Test Channel", name)
|
|
}
|
|
|
|
if channelType := channel.GetType(); channelType != ChannelTypeCustom {
|
|
t.Errorf("GetType() = %v, want %d", channelType, ChannelTypeCustom)
|
|
}
|
|
|
|
// Test setters
|
|
channel.SetName("Modified Channel")
|
|
if channel.GetName() != "Modified Channel" {
|
|
t.Errorf("SetName failed: got %v, want Modified Channel", channel.GetName())
|
|
}
|
|
|
|
channel.SetType(ChannelTypeWorld)
|
|
if channel.GetType() != ChannelTypeWorld {
|
|
t.Errorf("SetType failed: got %v, want %d", channel.GetType(), ChannelTypeWorld)
|
|
}
|
|
|
|
channel.SetLevelRestriction(10)
|
|
if channel.LevelRestriction != 10 {
|
|
t.Errorf("SetLevelRestriction failed: got %v, want 10", channel.LevelRestriction)
|
|
}
|
|
|
|
channel.SetPassword("secret")
|
|
if !channel.HasPassword() {
|
|
t.Error("HasPassword should return true after setting password")
|
|
}
|
|
|
|
if !channel.PasswordMatches("secret") {
|
|
t.Error("PasswordMatches should return true for correct password")
|
|
}
|
|
|
|
if channel.PasswordMatches("wrong") {
|
|
t.Error("PasswordMatches should return false for incorrect password")
|
|
}
|
|
}
|
|
|
|
func TestChannelMembership(t *testing.T) {
|
|
db, _ := database.NewSQLite("file::memory:?mode=memory&cache=shared")
|
|
defer db.Close()
|
|
|
|
channel := NewWithData(100, "Test", ChannelTypeCustom, db)
|
|
|
|
// Test empty channel
|
|
if !channel.IsEmpty() {
|
|
t.Error("New channel should be empty")
|
|
}
|
|
|
|
if channel.GetNumClients() != 0 {
|
|
t.Errorf("GetNumClients() = %v, want 0", channel.GetNumClients())
|
|
}
|
|
|
|
// Test joining channel
|
|
err := channel.JoinChannel(1001)
|
|
if err != nil {
|
|
t.Errorf("JoinChannel failed: %v", err)
|
|
}
|
|
|
|
if !channel.IsInChannel(1001) {
|
|
t.Error("IsInChannel should return true after joining")
|
|
}
|
|
|
|
if channel.IsEmpty() {
|
|
t.Error("Channel should not be empty after member joins")
|
|
}
|
|
|
|
if channel.GetNumClients() != 1 {
|
|
t.Errorf("GetNumClients() = %v, want 1", channel.GetNumClients())
|
|
}
|
|
|
|
// Test duplicate join
|
|
err = channel.JoinChannel(1001)
|
|
if err == nil {
|
|
t.Error("JoinChannel should fail for duplicate member")
|
|
}
|
|
|
|
// Test adding another member
|
|
err = channel.JoinChannel(1002)
|
|
if err != nil {
|
|
t.Errorf("JoinChannel failed: %v", err)
|
|
}
|
|
|
|
if channel.GetNumClients() != 2 {
|
|
t.Errorf("GetNumClients() = %v, want 2", channel.GetNumClients())
|
|
}
|
|
|
|
// Test getting members
|
|
members := channel.GetMembers()
|
|
if len(members) != 2 {
|
|
t.Errorf("GetMembers() returned %d members, want 2", len(members))
|
|
}
|
|
|
|
// Test leaving channel
|
|
err = channel.LeaveChannel(1001)
|
|
if err != nil {
|
|
t.Errorf("LeaveChannel failed: %v", err)
|
|
}
|
|
|
|
if channel.IsInChannel(1001) {
|
|
t.Error("IsInChannel should return false after leaving")
|
|
}
|
|
|
|
if channel.GetNumClients() != 1 {
|
|
t.Errorf("GetNumClients() = %v, want 1", channel.GetNumClients())
|
|
}
|
|
|
|
// Test leaving non-member
|
|
err = channel.LeaveChannel(9999)
|
|
if err == nil {
|
|
t.Error("LeaveChannel should fail for non-member")
|
|
}
|
|
}
|
|
|
|
func TestChannelRestrictions(t *testing.T) {
|
|
db, _ := database.NewSQLite("file::memory:?mode=memory&cache=shared")
|
|
defer db.Close()
|
|
|
|
channel := NewWithData(100, "Restricted", ChannelTypeWorld, db)
|
|
|
|
// Test level restrictions
|
|
channel.SetLevelRestriction(10)
|
|
if !channel.CanJoinChannelByLevel(10) {
|
|
t.Error("CanJoinChannelByLevel should return true for exact minimum")
|
|
}
|
|
if !channel.CanJoinChannelByLevel(15) {
|
|
t.Error("CanJoinChannelByLevel should return true for above minimum")
|
|
}
|
|
if channel.CanJoinChannelByLevel(5) {
|
|
t.Error("CanJoinChannelByLevel should return false for below minimum")
|
|
}
|
|
|
|
// Test race restrictions (bitmask)
|
|
channel.SetRacesAllowed(1 << 1) // Only race ID 1 allowed
|
|
if !channel.CanJoinChannelByRace(1) {
|
|
t.Error("CanJoinChannelByRace should return true for allowed race")
|
|
}
|
|
if channel.CanJoinChannelByRace(2) {
|
|
t.Error("CanJoinChannelByRace should return false for disallowed race")
|
|
}
|
|
|
|
// Test class restrictions (bitmask)
|
|
channel.SetClassesAllowed(1 << 5) // Only class ID 5 allowed
|
|
if !channel.CanJoinChannelByClass(5) {
|
|
t.Error("CanJoinChannelByClass should return true for allowed class")
|
|
}
|
|
if channel.CanJoinChannelByClass(1) {
|
|
t.Error("CanJoinChannelByClass should return false for disallowed class")
|
|
}
|
|
|
|
// Test ValidateJoin
|
|
err := channel.ValidateJoin(15, 1, 5, "")
|
|
if err != nil {
|
|
t.Errorf("ValidateJoin should succeed for valid player: %v", err)
|
|
}
|
|
|
|
err = channel.ValidateJoin(5, 1, 5, "")
|
|
if err == nil {
|
|
t.Error("ValidateJoin should fail for insufficient level")
|
|
}
|
|
|
|
err = channel.ValidateJoin(15, 2, 5, "")
|
|
if err == nil {
|
|
t.Error("ValidateJoin should fail for disallowed race")
|
|
}
|
|
|
|
err = channel.ValidateJoin(15, 1, 1, "")
|
|
if err == nil {
|
|
t.Error("ValidateJoin should fail for disallowed class")
|
|
}
|
|
|
|
// Test password validation
|
|
channel.SetPassword("secret")
|
|
err = channel.ValidateJoin(15, 1, 5, "secret")
|
|
if err != nil {
|
|
t.Errorf("ValidateJoin should succeed with correct password: %v", err)
|
|
}
|
|
|
|
err = channel.ValidateJoin(15, 1, 5, "wrong")
|
|
if err == nil {
|
|
t.Error("ValidateJoin should fail with incorrect password")
|
|
}
|
|
}
|
|
|
|
func TestChannelInfo(t *testing.T) {
|
|
db, _ := database.NewSQLite("file::memory:?mode=memory&cache=shared")
|
|
defer db.Close()
|
|
|
|
channel := NewWithData(100, "Info Test", ChannelTypeWorld, db)
|
|
channel.SetPassword("secret")
|
|
channel.SetLevelRestriction(10)
|
|
channel.JoinChannel(1001)
|
|
channel.JoinChannel(1002)
|
|
|
|
info := channel.GetChannelInfo()
|
|
|
|
if info.Name != "Info Test" {
|
|
t.Errorf("ChannelInfo.Name = %v, want Info Test", info.Name)
|
|
}
|
|
|
|
if !info.HasPassword {
|
|
t.Error("ChannelInfo.HasPassword should be true")
|
|
}
|
|
|
|
if info.MemberCount != 2 {
|
|
t.Errorf("ChannelInfo.MemberCount = %v, want 2", info.MemberCount)
|
|
}
|
|
|
|
if info.LevelRestriction != 10 {
|
|
t.Errorf("ChannelInfo.LevelRestriction = %v, want 10", info.LevelRestriction)
|
|
}
|
|
|
|
if info.ChannelType != ChannelTypeWorld {
|
|
t.Errorf("ChannelInfo.ChannelType = %v, want %d", info.ChannelType, ChannelTypeWorld)
|
|
}
|
|
}
|
|
|
|
func TestChannelCopy(t *testing.T) {
|
|
db, _ := database.NewSQLite("file::memory:?mode=memory&cache=shared")
|
|
defer db.Close()
|
|
|
|
original := NewWithData(500, "Original Channel", ChannelTypeWorld, db)
|
|
original.SetPassword("secret")
|
|
original.SetLevelRestriction(15)
|
|
original.JoinChannel(1001)
|
|
|
|
copy := original.Copy()
|
|
|
|
if copy == nil {
|
|
t.Fatal("Copy returned nil")
|
|
}
|
|
|
|
if copy == original {
|
|
t.Error("Copy returned same pointer as original")
|
|
}
|
|
|
|
if copy.GetID() != original.GetID() {
|
|
t.Errorf("Copy ID = %v, want %v", copy.GetID(), original.GetID())
|
|
}
|
|
|
|
if copy.GetName() != original.GetName() {
|
|
t.Errorf("Copy Name = %v, want %v", copy.GetName(), original.GetName())
|
|
}
|
|
|
|
if copy.Password != original.Password {
|
|
t.Errorf("Copy Password = %v, want %v", copy.Password, original.Password)
|
|
}
|
|
|
|
if !copy.IsNew() {
|
|
t.Error("Copy should always be marked as new")
|
|
}
|
|
|
|
// Verify modification independence
|
|
copy.SetName("Modified Copy")
|
|
if original.GetName() == "Modified Copy" {
|
|
t.Error("Modifying copy affected original")
|
|
}
|
|
} |