Summary
Create comprehensive unit and integration tests for all Castle Siege and Guild Alliance features. Tests should cover core logic independently of network packets and UI.
Prerequisites
- All preceding issues 720 - 733 should be implemented before full test coverage.
- Individual phases should be tested as they are completed.
Background
OpenMU tests are in the tests/ directory:
MUnique.OpenMU.Tests — main game logic tests.
MUnique.OpenMU.Network.Packets.Tests — packet serialization tests.
MUnique.OpenMU.Persistence.Initialization.Tests — initialization tests.
Tests use xUnit and Moq/NSubstitute patterns.
Requirements
1. Guild Alliance Tests — New file: tests/MUnique.OpenMU.Tests/GuildAllianceTests.cs
| Test |
Description |
CreateAlliance_ShouldSucceed |
Two guild masters can form an alliance |
CreateAlliance_MaxSizeExceeded_ShouldFail |
Cannot exceed max alliance size |
CreateAlliance_AlreadyInAlliance_ShouldFail |
Guild already in an alliance cannot join another |
RemoveAllianceGuild_ShouldSucceed |
Alliance master can remove a member guild |
RemoveAllianceGuild_NotMaster_ShouldFail |
Non-master cannot remove guilds |
DisbandAlliance_ShouldClearAll |
Disbanding clears alliance on all members |
GetGuildRelationship_Union |
Guilds in same alliance return Union |
GetGuildRelationship_Rival |
Hostile guilds return Rival |
GetGuildRelationship_Rival_TransitiveHostility |
Hostility is transitive through alliances |
IsAllianceMaster_SelfReferencing |
Guild with AllianceGuild == self is master |
ForEachAlliancePlayer_IteratesAllMembers |
Correctly iterates online alliance players |
2. Castle Siege State Machine Tests — New file: tests/MUnique.OpenMU.Tests/CastleSiege/CastleSiegeStateTests.cs
| Test |
Description |
CalculateCurrentState_MidWeek_FindsCorrectState |
Correctly identifies the current state from schedule |
CalculateCurrentState_WeekWrap_HandlesCorrectly |
Handles schedule that wraps around the week |
StateTransition_DurationExpired_AdvancesToNext |
Auto-transition when time expires |
EndCycle_TransitionsToRegisterGuild |
EndCycle loops to RegisterGuild, not Idle1 |
ForceChangeState_OverridesDuration |
Admin force changes work correctly |
IsEventRunning_OnlyDuringStart |
True only during Start state |
NotificationTiming_RegisterGuild_Every30Min |
Notifications fire at correct intervals |
NotificationTiming_Ready_Countdown |
Countdown notifications at 30min and last 5 min |
3. Guild Selection Tests — New file: tests/MUnique.OpenMU.Tests/CastleSiege/CastleSiegeGuildSelectorTests.cs
| Test |
Description |
ScoreCalculation_CorrectFormula |
(marks * 5) + members + (level / 4) |
SortOrder_HigherScoreFirst |
Guilds sorted by score descending |
SortOrder_TieBreaker_EarlierRegistration |
Earlier registration wins ties |
TopN_Selection |
Only top N guilds become attackers |
CastleOwner_BecomesDefense |
Owner guild automatically assigned Defense |
AllianceMembers_SameSide |
Alliance members get same side as master |
FilterZeroMarks |
Guilds with 0 marks are excluded |
FilterZeroMembers |
Guilds with 0 members are excluded |
4. Crown Mechanics Tests — New file: tests/MUnique.OpenMU.Tests/CastleSiege/CastleSiegeCrownTests.cs
| Test |
Description |
CheckMiddleWinner_AllThreeSameSide_AccumulatesTime |
Time increments when conditions met |
CheckMiddleWinner_DifferentSides_DoesNotAccumulate |
No time if players on different sides |
CheckMiddleWinner_MissingSwitch_DoesNotAccumulate |
No time if a switch is empty |
CheckMiddleWinner_DefenseSide_DoesNotCapture |
Defense side cannot capture crown |
CheckMiddleWinner_TimeReached_TriggersCapture |
Capture fires when time threshold met |
ChangeWinnerGuild_SwapsSides |
Defense and attack sides swap correctly |
ChangeWinnerGuild_KillsLifeStones |
All Life Stones destroyed on capture |
ChangeWinnerGuild_ResetsCrown |
Crown time and user reset after capture |
CrownAccessState_Fail_CapsAccumulatedTime |
On fail, time capped at threshold - 1 |
SwitchInfo_BothSameSide_UnlocksCrown |
Crown unlocked when both switches same side |
SwitchInfo_DifferentSides_LocksCrown |
Crown locked when switches on different sides |
5. Tax System Tests — New file: tests/MUnique.OpenMU.Tests/CastleSiege/CastleSiegeTaxTests.cs
| Test |
Description |
ChaosTax_AppliedToCraftingCost |
Crafting cost includes chaos tax |
StoreTax_AppliedToShopPrice |
Shop price includes store tax |
HuntTax_ChargedOnEntry |
Hunt tax deducted on LoT entry |
OwnerGuild_Exempt |
Owner guild members pay no tax |
AllianceMembers_Exempt |
Alliance members pay no tax |
NonMember_PaysTax |
Non-alliance players pay full tax |
TaxRateChange_ValidRange_Succeeds |
Valid rate changes accepted |
TaxRateChange_OutOfRange_Fails |
Invalid rates rejected |
TaxReset_OnOwnershipChange |
Taxes reset to 0 on new owner |
TributeMoney_Accumulates |
Tax revenue adds to tribute money |
TributeWithdraw_DeductsFromBalance |
Withdrawal reduces tribute balance |
6. NPC Upgrade Tests — New file: tests/MUnique.OpenMU.Tests/CastleSiege/CastleSiegeNpcUpgradeTests.cs
| Test |
Description |
Upgrade_BelowMaxLevel_Succeeds |
Upgrade from level 0 to 1 works |
Upgrade_AtMaxLevel_Fails |
Cannot exceed level 3 |
Upgrade_NotOwner_Fails |
Non-owner guild cannot upgrade |
Upgrade_DuringBattle_Fails |
Cannot upgrade during Start state |
Upgrade_InsufficientZen_Fails |
Rejected if not enough Zen |
Upgrade_InsufficientJewels_Fails |
Rejected if not enough Jewels of Guardian |
Buy_DeadNpc_Succeeds |
Can re-purchase a destroyed NPC |
Buy_AliveNpc_Fails |
Cannot buy an already alive NPC |
Repair_RestoresFullHp |
Repair brings NPC to max HP |
7. Registration Tests — New file: tests/MUnique.OpenMU.Tests/CastleSiege/CastleSiegeRegistrationTests.cs
| Test |
Description |
Register_ValidGuild_Succeeds |
Valid registration accepted |
Register_WrongState_Fails |
Cannot register outside RegisterGuild state |
Register_NotGuildMaster_Fails |
Non-master cannot register |
Register_InsufficientLevel_Fails |
Below min level rejected |
Register_InsufficientMembers_Fails |
Too few members rejected |
Register_AlreadyRegistered_Fails |
Duplicate registration rejected |
Register_CastleOwner_Fails |
Owner cannot register (auto-defender) |
MarkRegistration_ConsumesItem |
Emblem of Lord consumed from inventory |
MarkRegistration_IncrementsCount |
Mark count increases correctly |
8. Participant Reward Tests — New file: tests/MUnique.OpenMU.Tests/CastleSiege/CastleSiegeRewardTests.cs
| Test |
Description |
Reward_SufficientTime_Granted |
Player with enough time gets reward |
Reward_InsufficientTime_Denied |
Player below threshold gets no reward |
Reward_OfflinePlayer_Queued |
Offline participant's reward is queued |
GuildScore_WinnerGetsPoints |
Winning guild gets configured score |
GuildScore_AllianceMembersGetPoints |
Alliance members get their score |
Files to Create
| File |
Description |
tests/MUnique.OpenMU.Tests/GuildAllianceTests.cs |
Alliance unit tests |
tests/MUnique.OpenMU.Tests/CastleSiege/CastleSiegeStateTests.cs |
State machine tests |
tests/MUnique.OpenMU.Tests/CastleSiege/CastleSiegeGuildSelectorTests.cs |
Selection tests |
tests/MUnique.OpenMU.Tests/CastleSiege/CastleSiegeCrownTests.cs |
Crown mechanics tests |
tests/MUnique.OpenMU.Tests/CastleSiege/CastleSiegeTaxTests.cs |
Tax system tests |
tests/MUnique.OpenMU.Tests/CastleSiege/CastleSiegeNpcUpgradeTests.cs |
NPC upgrade tests |
tests/MUnique.OpenMU.Tests/CastleSiege/CastleSiegeRegistrationTests.cs |
Registration tests |
tests/MUnique.OpenMU.Tests/CastleSiege/CastleSiegeRewardTests.cs |
Reward tests |
Acceptance Criteria