baseline: OpenMU upstream b5a0961 (fresh source)
This commit is contained in:
205
tests/MUnique.OpenMU.Tests/Party/PartyManagerTest.cs
Normal file
205
tests/MUnique.OpenMU.Tests/Party/PartyManagerTest.cs
Normal file
@@ -0,0 +1,205 @@
|
||||
// <copyright file="PartyManagerTest.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.Tests;
|
||||
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using MUnique.OpenMU.DataModel.Configuration;
|
||||
using MUnique.OpenMU.GameLogic;
|
||||
using MUnique.OpenMU.Persistence.InMemory;
|
||||
using MUnique.OpenMU.PlugIns;
|
||||
|
||||
/// <summary>
|
||||
/// Tests for <see cref="PartyManager"/>.
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class PartyManagerTest
|
||||
{
|
||||
private const byte MaxPartySize = 5;
|
||||
|
||||
private PartyManager _partyManager = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Sets up a fresh <see cref="PartyManager"/> before each test.
|
||||
/// </summary>
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
this._partyManager = new PartyManager(MaxPartySize, new NullLogger<Party>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that <see cref="PartyManager.CreateParty"/> returns a party with the configured max size.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void CreateParty_RespectsMaxPartySize()
|
||||
{
|
||||
var party = this._partyManager.CreateParty();
|
||||
Assert.That(party.MaxPartySize, Is.EqualTo(MaxPartySize));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that a member added to the party is present in the party list.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async ValueTask CreateParty_AddedMemberIsInPartyList()
|
||||
{
|
||||
var member = await this.CreatePartyMemberAsync().ConfigureAwait(false);
|
||||
var party = this._partyManager.CreateParty();
|
||||
|
||||
await party.AddAsync(member).ConfigureAwait(false);
|
||||
|
||||
Assert.That(party.PartyList, Contains.Item(member));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that <see cref="PartyManager.OnMemberReconnectedAsync"/> does nothing
|
||||
/// when the member has no cached party.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async ValueTask OnMemberReconnected_DoesNothingWhenNoCachedParty()
|
||||
{
|
||||
var member = await this.CreatePartyMemberAsync().ConfigureAwait(false);
|
||||
|
||||
await this._partyManager.OnMemberReconnectedAsync(member).ConfigureAwait(false);
|
||||
|
||||
Assert.That(member.Party, Is.Null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that when a member is kicked the party list no longer contains them.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async ValueTask KickedMember_IsRemovedFromPartyList()
|
||||
{
|
||||
var (party, _, member2) = await this.CreatePartyWithTwoMembersAsync().ConfigureAwait(false);
|
||||
|
||||
await party.KickPlayerAsync(GetPartyMemberIndex(party, member2)).ConfigureAwait(false);
|
||||
|
||||
Assert.That(party.PartyList, Is.Not.Contains(member2));
|
||||
Assert.That(member2.Party, Is.Null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that <see cref="Party.LeaveTemporarilyAsync"/> replaces a live member
|
||||
/// with an <see cref="OfflinePartyMember"/> snapshot.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async ValueTask LeaveTemporarily_ReplacesWithOfflineSnapshot()
|
||||
{
|
||||
var (party, member1, _) = await this.CreatePartyWithTwoMembersAsync().ConfigureAwait(false);
|
||||
|
||||
await party.LeaveTemporarilyAsync(member1).ConfigureAwait(false);
|
||||
|
||||
Assert.That(party.PartyList[0], Is.InstanceOf<OfflinePartyMember>());
|
||||
Assert.That(party.PartyList[0].Name, Is.EqualTo(member1.Name));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that <see cref="PartyManager.OnMemberReconnectedAsync"/> restores the live member
|
||||
/// from an <see cref="OfflinePartyMember"/> snapshot.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async ValueTask OnMemberReconnected_RestoresLiveMember()
|
||||
{
|
||||
var (party, member1, _) = await this.CreatePartyWithTwoMembersAsync().ConfigureAwait(false);
|
||||
var originalName = member1.Name;
|
||||
|
||||
// Member disconnects - replaced with offline snapshot
|
||||
await party.LeaveTemporarilyAsync(member1).ConfigureAwait(false);
|
||||
|
||||
// Member reconnects - restored from snapshot
|
||||
await this._partyManager.OnMemberReconnectedAsync(member1).ConfigureAwait(false);
|
||||
|
||||
Assert.That(party.PartyList[0], Is.SameAs(member1));
|
||||
Assert.That(party.PartyList[0].Name, Is.EqualTo(originalName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that after reconnect, the live member's Party reference is restored.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async ValueTask OnMemberReconnected_RestoresPartyReference()
|
||||
{
|
||||
var (party, member1, _) = await this.CreatePartyWithTwoMembersAsync().ConfigureAwait(false);
|
||||
|
||||
await party.LeaveTemporarilyAsync(member1).ConfigureAwait(false);
|
||||
await this._partyManager.OnMemberReconnectedAsync(member1).ConfigureAwait(false);
|
||||
|
||||
Assert.That(member1.Party, Is.SameAs(party));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that the offline snapshot preserves the disconnected member's name.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async ValueTask LeaveTemporarily_SnapshotPreservesName()
|
||||
{
|
||||
var (party, member1, _) = await this.CreatePartyWithTwoMembersAsync().ConfigureAwait(false);
|
||||
|
||||
await party.LeaveTemporarilyAsync(member1).ConfigureAwait(false);
|
||||
|
||||
Assert.That(party.PartyList[0].Name, Is.EqualTo(member1.Name));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that <see cref="Party.ReplaceMemberAsync"/> preserves the party master status
|
||||
/// when replacing the master.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async ValueTask ReplaceMember_PreservesMasterStatus()
|
||||
{
|
||||
var (party, member1, _) = await this.CreatePartyWithTwoMembersAsync().ConfigureAwait(false);
|
||||
|
||||
// member1 is master (first member added)
|
||||
var snapshot = new OfflinePartyMember(member1);
|
||||
await party.ReplaceMemberAsync(member1, snapshot).ConfigureAwait(false);
|
||||
|
||||
Assert.That(party.PartyMaster, Is.SameAs(snapshot));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that <see cref="Party.ReplaceMemberAsync"/> clears the old member's party reference.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async ValueTask ReplaceMember_ClearsOldMemberPartyReference()
|
||||
{
|
||||
var (party, member1, _) = await this.CreatePartyWithTwoMembersAsync().ConfigureAwait(false);
|
||||
|
||||
var snapshot = new OfflinePartyMember(member1);
|
||||
await party.ReplaceMemberAsync(member1, snapshot).ConfigureAwait(false);
|
||||
|
||||
Assert.That(member1.Party, Is.Null);
|
||||
}
|
||||
|
||||
private async ValueTask<(Party Party, Player Member1, Player Member2)> CreatePartyWithTwoMembersAsync()
|
||||
{
|
||||
var member1 = await this.CreatePartyMemberAsync().ConfigureAwait(false);
|
||||
var member2 = await this.CreatePartyMemberAsync().ConfigureAwait(false);
|
||||
var party = this._partyManager.CreateParty();
|
||||
await party.AddAsync(member1).ConfigureAwait(false);
|
||||
await party.AddAsync(member2).ConfigureAwait(false);
|
||||
return (party, member1, member2);
|
||||
}
|
||||
|
||||
private static byte GetPartyMemberIndex(Party party, IPartyMember member)
|
||||
{
|
||||
for (byte index = 0; index < party.PartyList.Count; index++)
|
||||
{
|
||||
if (party.PartyList[index] == member)
|
||||
{
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
throw new ArgumentException("The member is not part of the party.", nameof(member));
|
||||
}
|
||||
|
||||
private async ValueTask<Player> CreatePartyMemberAsync()
|
||||
{
|
||||
var result = await PlayerTestHelper.CreatePlayerAsync(GameContextTestHelper.CreateGameContext()).ConfigureAwait(false);
|
||||
await result.PlayerState.TryAdvanceToAsync(PlayerState.EnteredWorld).ConfigureAwait(false);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
408
tests/MUnique.OpenMU.Tests/Party/PartyTest.cs
Normal file
408
tests/MUnique.OpenMU.Tests/Party/PartyTest.cs
Normal file
@@ -0,0 +1,408 @@
|
||||
// <copyright file="PartyTest.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.Tests;
|
||||
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Moq;
|
||||
using MUnique.OpenMU.DataModel.Configuration;
|
||||
using MUnique.OpenMU.GameLogic;
|
||||
using MUnique.OpenMU.GameLogic.MuHelper;
|
||||
using MUnique.OpenMU.GameLogic.PlayerActions.Party;
|
||||
using MUnique.OpenMU.GameLogic.Views.Party;
|
||||
using MUnique.OpenMU.GameServer;
|
||||
using MUnique.OpenMU.Interfaces;
|
||||
using MUnique.OpenMU.Pathfinding;
|
||||
using MUnique.OpenMU.Persistence.InMemory;
|
||||
using MUnique.OpenMU.PlugIns;
|
||||
|
||||
/// <summary>
|
||||
/// Tests the party functions.
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class PartyTest
|
||||
{
|
||||
private readonly PartyKickAction _kickAction = new();
|
||||
|
||||
/// <summary>
|
||||
/// Tests if an added party member gets added to the party list.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async ValueTask PartyMemberAddAsync()
|
||||
{
|
||||
var partyMember = await this.CreatePartyMemberAsync().ConfigureAwait(false);
|
||||
var party = new Party(new PartyManager(5, new NullLogger<Party>()), 5, new NullLogger<Party>());
|
||||
await party.AddAsync(partyMember).ConfigureAwait(false);
|
||||
|
||||
Assert.That(party.PartyList, Contains.Item(partyMember));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests a kick request by a non-party-master for another player, which should fail.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async ValueTask PartyMemberKickFailByNonMasterAsync()
|
||||
{
|
||||
var party = await this.CreatePartyWithMembersAsync(3).ConfigureAwait(false);
|
||||
var partyMember2 = (Player)party.PartyList[1];
|
||||
var partyMember3 = party.PartyList[2];
|
||||
|
||||
await this._kickAction.KickPlayerAsync(partyMember2, GetPartyMemberIndex(party, partyMember3)).ConfigureAwait(false);
|
||||
Assert.That(party.PartyList, Contains.Item(partyMember3));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if the player is kicking himself works, even if the player is no party master.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async ValueTask PartyMemberKickHimselfAsync()
|
||||
{
|
||||
var party = await this.CreatePartyWithMembersAsync(3).ConfigureAwait(false);
|
||||
var partyMember2 = party.PartyList[1];
|
||||
|
||||
await this._kickAction.KickPlayerAsync((Player)partyMember2, GetPartyMemberIndex(party, partyMember2)).ConfigureAwait(false);
|
||||
Assert.That(party.PartyList, Is.Not.Contains(partyMember2));
|
||||
Assert.That(party.PartyList, Has.Count.EqualTo(2));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if another player can be kicked by the party master.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async ValueTask PartyMemberKickByMasterAsync()
|
||||
{
|
||||
var party = await this.CreatePartyWithMembersAsync(3).ConfigureAwait(false);
|
||||
var partyMaster = (Player)party.PartyList[0];
|
||||
var partyMember = (Player)party.PartyList[1];
|
||||
|
||||
await this._kickAction.KickPlayerAsync(partyMaster, GetPartyMemberIndex(party, partyMember)).ConfigureAwait(false);
|
||||
Assert.That(party.PartyList, Is.Not.Contains(partyMember));
|
||||
Assert.That(party.PartyList, Has.Count.EqualTo(2));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if the party disbands when the master kicks himself.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async ValueTask PartyMasterKicksHimselfAsync()
|
||||
{
|
||||
var party = await this.CreatePartyWithMembersAsync(3).ConfigureAwait(false);
|
||||
var partyMaster = party.PartyList[0];
|
||||
var partyMember = party.PartyList[1];
|
||||
|
||||
await this._kickAction.KickPlayerAsync((Player)partyMaster, GetPartyMemberIndex(party, partyMaster)).ConfigureAwait(false);
|
||||
|
||||
// Master leaves the party; the remaining 2 members stay.
|
||||
Assert.That(partyMaster.Party, Is.Null);
|
||||
Assert.That(party.PartyList, Does.Not.Contain(partyMaster));
|
||||
Assert.That(partyMember.Party, Is.SameAs(party));
|
||||
Assert.That(party.PartyList, Has.Count.EqualTo(2));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if the party automatically closes when one player is left.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async ValueTask PartyAutoCloseAsync()
|
||||
{
|
||||
var partyMember1 = await this.CreatePartyMemberAsync().ConfigureAwait(false);
|
||||
var party = new Party(new PartyManager(5, new NullLogger<Party>()), 5, new NullLogger<Party>());
|
||||
await party.AddAsync(partyMember1).ConfigureAwait(false);
|
||||
var partyMember1Index = (byte)(party.PartyList.Count - 1);
|
||||
var partyMember2 = await this.CreatePartyMemberAsync().ConfigureAwait(false);
|
||||
await party.AddAsync(partyMember2).ConfigureAwait(false);
|
||||
var partyMember2Index = (byte)(party.PartyList.Count - 1);
|
||||
|
||||
await this._kickAction.KickPlayerAsync(partyMember1, partyMember2Index).ConfigureAwait(false);
|
||||
Assert.That(partyMember1.Party, Is.Null);
|
||||
Assert.That(partyMember2.Party, Is.Null);
|
||||
Assert.That(party.PartyList, Is.Null.Or.Empty);
|
||||
|
||||
Mock.Get(partyMember1.ViewPlugIns.GetPlugIn<IPartyMemberRemovedPlugIn>()!).Verify(v => v!.PartyMemberRemovedAsync(partyMember1Index), Times.Once);
|
||||
Mock.Get(partyMember2.ViewPlugIns.GetPlugIn<IPartyMemberRemovedPlugIn>()!).Verify(v => v!.PartyMemberRemovedAsync(partyMember2Index), Times.Once);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests the adding of party members.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async ValueTask PartyHandlerAddAsync()
|
||||
{
|
||||
var handler = new PartyRequestAction();
|
||||
var player = await this.CreatePartyMemberAsync().ConfigureAwait(false);
|
||||
var toRequest = await this.CreatePartyMemberAsync().ConfigureAwait(false);
|
||||
player.Observers.Add(toRequest);
|
||||
|
||||
await handler.HandlePartyRequestAsync(player, toRequest).ConfigureAwait(false);
|
||||
|
||||
Mock.Get(toRequest.ViewPlugIns.GetPlugIn<IShowPartyRequestPlugIn>()!).Verify(v => v!.ShowPartyRequestAsync(player), Times.Once);
|
||||
Assert.That(toRequest.LastPartyRequester, Is.SameAs(player));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if the party gets created after the requested player responses with accepting the party.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async ValueTask PartyResponseAcceptNewPartyAsync()
|
||||
{
|
||||
var handler = new PartyResponseAction();
|
||||
var player = await this.CreatePartyMemberAsync().ConfigureAwait(false);
|
||||
var requester = await this.CreatePartyMemberAsync().ConfigureAwait(false);
|
||||
player.LastPartyRequester = requester;
|
||||
await player.PlayerState.TryAdvanceToAsync(PlayerState.PartyRequest).ConfigureAwait(false);
|
||||
|
||||
await handler.HandleResponseAsync(player, true).ConfigureAwait(false);
|
||||
Assert.That(player.Party, Is.Not.Null);
|
||||
Assert.That(player.Party!.PartyMaster, Is.SameAs(requester));
|
||||
Assert.That(player.LastPartyRequester, Is.Null);
|
||||
Assert.That(player.Party.PartyList, Contains.Item(player));
|
||||
Mock.Get(player.ViewPlugIns.GetPlugIn<IUpdatePartyListPlugIn>()!).Verify(v => v!.UpdatePartyListAsync(), Times.AtLeastOnce);
|
||||
Mock.Get(requester.ViewPlugIns.GetPlugIn<IUpdatePartyListPlugIn>()!).Verify(v => v!.UpdatePartyListAsync(), Times.AtLeastOnce);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if a request to a player which is already in a party (however this happened...)
|
||||
/// does not cause the player to be added to the other party.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async ValueTask PartyResponseAcceptExistingPartyAsync()
|
||||
{
|
||||
var handler = new PartyResponseAction();
|
||||
|
||||
// first put the player in a party with another player
|
||||
var player = await this.CreatePartyMemberAsync().ConfigureAwait(false);
|
||||
player.LastPartyRequester = await this.CreatePartyMemberAsync().ConfigureAwait(false);
|
||||
await player.PlayerState.TryAdvanceToAsync(PlayerState.PartyRequest).ConfigureAwait(false);
|
||||
await handler.HandleResponseAsync(player, true).ConfigureAwait(false);
|
||||
|
||||
// now another player will try to request party from the player, which should fail
|
||||
var requester = await this.CreatePartyMemberAsync().ConfigureAwait(false);
|
||||
player.LastPartyRequester = requester;
|
||||
await handler.HandleResponseAsync(player, true).ConfigureAwait(false);
|
||||
Assert.That(player.Party!.PartyList, Is.Not.Contains(requester));
|
||||
Assert.That(player.LastPartyRequester, Is.Null);
|
||||
Assert.That(requester.Party, Is.Null);
|
||||
Mock.Get(player.ViewPlugIns.GetPlugIn<IShowPartyRequestPlugIn>()!).Verify(v => v!.ShowPartyRequestAsync(requester), Times.Never);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if a party request is auto-accepted when <see cref="IMuHelperSettings.AutoAcceptFriend"/> is true
|
||||
/// and the requester is a friend.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async ValueTask PartyRequestAutoAcceptByFriendAsync()
|
||||
{
|
||||
var friendServer = new Mock<IFriendServer>();
|
||||
friendServer.Setup(f => f.IsFriendAsync(It.IsAny<string>(), It.IsAny<string>())).ReturnsAsync(true);
|
||||
var gameContext = PartyTest.CreateGameServerContext(friendServer.Object);
|
||||
var player = await PlayerTestHelper.CreatePlayerAsync(gameContext).ConfigureAwait(false);
|
||||
var toRequest = await PlayerTestHelper.CreatePlayerAsync(gameContext).ConfigureAwait(false);
|
||||
player.SelectedCharacter!.Name = "Requester";
|
||||
toRequest.SelectedCharacter!.Name = "Receiver";
|
||||
player.Observers.Add(toRequest);
|
||||
|
||||
var settingsMock = new Mock<IMuHelperSettings>();
|
||||
settingsMock.Setup(s => s.AutoAcceptFriend).Returns(true);
|
||||
toRequest.MuHelperSettings = settingsMock.Object;
|
||||
|
||||
var handler = new PartyRequestAction();
|
||||
await handler.HandlePartyRequestAsync(player, toRequest).ConfigureAwait(false);
|
||||
|
||||
Assert.That(player.Party, Is.Not.Null);
|
||||
Assert.That(toRequest.Party, Is.SameAs(player.Party));
|
||||
Mock.Get(toRequest.ViewPlugIns.GetPlugIn<IShowPartyRequestPlugIn>()!).Verify(v => v!.ShowPartyRequestAsync(player), Times.Never);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if a party request still shows the dialog when <see cref="IMuHelperSettings.AutoAcceptFriend"/>
|
||||
/// is true but the requester is not a friend.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async ValueTask PartyRequestAutoAcceptByFriendNotFriendAsync()
|
||||
{
|
||||
var friendServer = new Mock<IFriendServer>();
|
||||
friendServer.Setup(f => f.IsFriendAsync(It.IsAny<string>(), It.IsAny<string>())).ReturnsAsync(false);
|
||||
var gameContext = PartyTest.CreateGameServerContext(friendServer.Object);
|
||||
var player = await PlayerTestHelper.CreatePlayerAsync(gameContext).ConfigureAwait(false);
|
||||
var toRequest = await PlayerTestHelper.CreatePlayerAsync(gameContext).ConfigureAwait(false);
|
||||
player.SelectedCharacter!.Name = "Requester";
|
||||
toRequest.SelectedCharacter!.Name = "Receiver";
|
||||
player.Observers.Add(toRequest);
|
||||
|
||||
var settingsMock = new Mock<IMuHelperSettings>();
|
||||
settingsMock.Setup(s => s.AutoAcceptFriend).Returns(true);
|
||||
toRequest.MuHelperSettings = settingsMock.Object;
|
||||
|
||||
var handler = new PartyRequestAction();
|
||||
await handler.HandlePartyRequestAsync(player, toRequest).ConfigureAwait(false);
|
||||
|
||||
Assert.That(player.Party, Is.Null);
|
||||
Mock.Get(toRequest.ViewPlugIns.GetPlugIn<IShowPartyRequestPlugIn>()!).Verify(v => v!.ShowPartyRequestAsync(player), Times.Once);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if a party request is auto-accepted when <see cref="IMuHelperSettings.AutoAcceptGuild"/> is true
|
||||
/// and both players are members of the same guild.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async ValueTask PartyRequestAutoAcceptByGuildAsync()
|
||||
{
|
||||
var gameContext = GameContextTestHelper.CreateGameContext();
|
||||
var player = await PlayerTestHelper.CreatePlayerAsync(gameContext).ConfigureAwait(false);
|
||||
var toRequest = await PlayerTestHelper.CreatePlayerAsync(gameContext).ConfigureAwait(false);
|
||||
player.Observers.Add(toRequest);
|
||||
|
||||
var guildId = 1u;
|
||||
player.GuildStatus = new GuildMemberStatus(guildId, GuildPosition.GuildMaster);
|
||||
toRequest.GuildStatus = new GuildMemberStatus(guildId, GuildPosition.NormalMember);
|
||||
|
||||
var settingsMock = new Mock<IMuHelperSettings>();
|
||||
settingsMock.Setup(s => s.AutoAcceptGuild).Returns(true);
|
||||
toRequest.MuHelperSettings = settingsMock.Object;
|
||||
|
||||
var handler = new PartyRequestAction();
|
||||
await handler.HandlePartyRequestAsync(player, toRequest).ConfigureAwait(false);
|
||||
|
||||
Assert.That(player.Party, Is.Not.Null);
|
||||
Assert.That(toRequest.Party, Is.SameAs(player.Party));
|
||||
Mock.Get(toRequest.ViewPlugIns.GetPlugIn<IShowPartyRequestPlugIn>()!).Verify(v => v!.ShowPartyRequestAsync(player), Times.Never);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if a party request still shows the dialog when <see cref="IMuHelperSettings.AutoAcceptGuild"/>
|
||||
/// is true but the players are in different guilds.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async ValueTask PartyRequestAutoAcceptByGuildDifferentGuildAsync()
|
||||
{
|
||||
var gameContext = GameContextTestHelper.CreateGameContext();
|
||||
var player = await PlayerTestHelper.CreatePlayerAsync(gameContext).ConfigureAwait(false);
|
||||
var toRequest = await PlayerTestHelper.CreatePlayerAsync(gameContext).ConfigureAwait(false);
|
||||
player.Observers.Add(toRequest);
|
||||
|
||||
player.GuildStatus = new GuildMemberStatus(1u, GuildPosition.GuildMaster);
|
||||
toRequest.GuildStatus = new GuildMemberStatus(2u, GuildPosition.NormalMember);
|
||||
|
||||
var settingsMock = new Mock<IMuHelperSettings>();
|
||||
settingsMock.Setup(s => s.AutoAcceptGuild).Returns(true);
|
||||
toRequest.MuHelperSettings = settingsMock.Object;
|
||||
|
||||
var handler = new PartyRequestAction();
|
||||
await handler.HandlePartyRequestAsync(player, toRequest).ConfigureAwait(false);
|
||||
|
||||
Assert.That(player.Party, Is.Null);
|
||||
Mock.Get(toRequest.ViewPlugIns.GetPlugIn<IShowPartyRequestPlugIn>()!).Verify(v => v!.ShowPartyRequestAsync(player), Times.Once);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that a party request is not auto-accepted when no relevant flags are set.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async ValueTask PartyRequestAutoAcceptNoFlagsAsync()
|
||||
{
|
||||
var friendServer = new Mock<IFriendServer>();
|
||||
var gameContext = PartyTest.CreateGameServerContext(friendServer.Object);
|
||||
var player = await PlayerTestHelper.CreatePlayerAsync(gameContext).ConfigureAwait(false);
|
||||
var toRequest = await PlayerTestHelper.CreatePlayerAsync(gameContext).ConfigureAwait(false);
|
||||
player.SelectedCharacter!.Name = "Requester";
|
||||
toRequest.SelectedCharacter!.Name = "Receiver";
|
||||
player.Observers.Add(toRequest);
|
||||
|
||||
var settingsMock = new Mock<IMuHelperSettings>();
|
||||
toRequest.MuHelperSettings = settingsMock.Object;
|
||||
|
||||
var handler = new PartyRequestAction();
|
||||
await handler.HandlePartyRequestAsync(player, toRequest).ConfigureAwait(false);
|
||||
|
||||
Assert.That(player.Party, Is.Null);
|
||||
Mock.Get(toRequest.ViewPlugIns.GetPlugIn<IShowPartyRequestPlugIn>()!).Verify(v => v!.ShowPartyRequestAsync(player), Times.Once);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that a party request is not auto-accepted when MuHelperSettings is null.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async ValueTask PartyRequestAutoAcceptNoSettingsAsync()
|
||||
{
|
||||
var friendServer = new Mock<IFriendServer>();
|
||||
var gameContext = PartyTest.CreateGameServerContext(friendServer.Object);
|
||||
var player = await PlayerTestHelper.CreatePlayerAsync(gameContext).ConfigureAwait(false);
|
||||
var toRequest = await PlayerTestHelper.CreatePlayerAsync(gameContext).ConfigureAwait(false);
|
||||
player.Observers.Add(toRequest);
|
||||
|
||||
var handler = new PartyRequestAction();
|
||||
await handler.HandlePartyRequestAsync(player, toRequest).ConfigureAwait(false);
|
||||
|
||||
Assert.That(player.Party, Is.Null);
|
||||
Mock.Get(toRequest.ViewPlugIns.GetPlugIn<IShowPartyRequestPlugIn>()!).Verify(v => v!.ShowPartyRequestAsync(player), Times.Once);
|
||||
}
|
||||
|
||||
private static IGameServerContext CreateGameServerContext(IFriendServer friendServer)
|
||||
{
|
||||
var contextProvider = new InMemoryPersistenceContextProvider();
|
||||
var context = contextProvider.CreateNewContext();
|
||||
var gameConfiguration = context.CreateNew<MUnique.OpenMU.Persistence.BasicModel.GameConfiguration>();
|
||||
gameConfiguration.MaximumPartySize = 5;
|
||||
gameConfiguration.RecoveryInterval = int.MaxValue;
|
||||
gameConfiguration.MaximumInventoryMoney = int.MaxValue;
|
||||
var mapDef = context.CreateNew<MUnique.OpenMU.Persistence.BasicModel.GameMapDefinition>();
|
||||
mapDef.Number = 0;
|
||||
mapDef.TerrainData = new byte[ushort.MaxValue + 3];
|
||||
gameConfiguration.Maps.Add(mapDef);
|
||||
|
||||
var mapInitializer = new MapInitializer(gameConfiguration, new NullLogger<MapInitializer>(), NullDropGenerator.Instance, null);
|
||||
|
||||
var gameServer = new GameServerContext(
|
||||
new GameServerDefinition
|
||||
{
|
||||
GameConfiguration = gameConfiguration,
|
||||
ServerConfiguration = new GameServerConfiguration(),
|
||||
},
|
||||
new Mock<IGuildServer>().Object,
|
||||
new Mock<IEventPublisher>().Object,
|
||||
new Mock<ILoginServer>().Object,
|
||||
friendServer,
|
||||
new InMemoryPersistenceContextProvider(),
|
||||
mapInitializer,
|
||||
new NullLoggerFactory(),
|
||||
new PlugInManager(new List<PlugInConfiguration>(), new NullLoggerFactory(), null, null),
|
||||
NullDropGenerator.Instance,
|
||||
new ConfigurationChangeMediator());
|
||||
mapInitializer.PlugInManager = gameServer.PlugInManager;
|
||||
mapInitializer.PathFinderPool = gameServer.PathFinderPool;
|
||||
return gameServer;
|
||||
}
|
||||
|
||||
private async ValueTask<Player> CreatePartyMemberAsync()
|
||||
{
|
||||
var result = await PlayerTestHelper.CreatePlayerAsync(GameContextTestHelper.CreateGameContext()).ConfigureAwait(false);
|
||||
await result.PlayerState.TryAdvanceToAsync(PlayerState.EnteredWorld).ConfigureAwait(false);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static byte GetPartyMemberIndex(Party party, IPartyMember member)
|
||||
{
|
||||
for (byte index = 0; index < party.PartyList.Count; index++)
|
||||
{
|
||||
if (party.PartyList[index] == member)
|
||||
{
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
throw new ArgumentException("The member is not part of the party.", nameof(member));
|
||||
}
|
||||
|
||||
private async ValueTask<Party> CreatePartyWithMembersAsync(int numberOfMembers)
|
||||
{
|
||||
var party = new Party(new PartyManager(5, new NullLogger<Party>()), 5, new NullLogger<Party>());
|
||||
for (ushort i = 0; i < numberOfMembers; i++)
|
||||
{
|
||||
var partyMember = await this.CreatePartyMemberAsync().ConfigureAwait(false);
|
||||
await party.AddAsync(partyMember).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return party;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user