mirror of
https://github.com/JogmansonReal/Radicade.git
synced 2026-10-26 23:49:02 -07:00
Radicade Public Code
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RadicadeServer.API.Storefront;
|
||||
using RadicadeServer.DB;
|
||||
using RadicadeServer.Extensions;
|
||||
using RadicadeServer.RecNet.Avatar;
|
||||
using RadicadeServer.RecNet.Enums.Store;
|
||||
using RadicadeServer.RecNet.Progression;
|
||||
using RadicadeServer.RecNet.Rooms;
|
||||
using RadicadeServer.RecNet.Storefront;
|
||||
using RadicadeServer.Utils;
|
||||
using Xunit;
|
||||
|
||||
namespace RadicadeServer.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// What happens to a quest's reward box when the player walks away from it.
|
||||
///
|
||||
/// A quest's reward is not a choice and is not openable anywhere else - the server picked one unowned
|
||||
/// item out of the run's rank pool when the reward was generated, and the box is only the delivery of
|
||||
/// that item. Leaving the quest with the box still shut therefore has to deliver it, not strand it,
|
||||
/// not re-roll it, and not pay tokens for it. These tests cover the delivery, and the three things
|
||||
/// the delivery must not touch: a box for the quest the player is standing in, a box that is no
|
||||
/// quest's, and the item's identity.
|
||||
/// </summary>
|
||||
public class QuestRewardDeliveryTests
|
||||
{
|
||||
private const long PlayerId = 4411;
|
||||
|
||||
private static RecDBContext NewDb() =>
|
||||
new(TestDbOptions.Create()
|
||||
.UseInMemoryDatabase(Guid.NewGuid().ToString())
|
||||
.Options);
|
||||
|
||||
private static async Task<RoomData> SeedRoomAsync(RecDBContext db, string name)
|
||||
{
|
||||
var room = new RoomData { Name = name };
|
||||
db.Rooms.Add(room);
|
||||
await db.SaveChangesAsync();
|
||||
return room;
|
||||
}
|
||||
|
||||
private static Gift QuestBox(GiftContext context = GiftContext.StuntRunner_TheMainEvent_C) => new()
|
||||
{
|
||||
GiftDropId = 8801,
|
||||
FriendlyName = "Runner Harness (Green)",
|
||||
Tooltip = "Stunt Runner: The Main Event",
|
||||
AvatarItemDesc = "d2d3264b-fbf6-40b5-9f10-c85ec737d112,1ba65dd5-9df9-4ff3-be96-f83a7abf67b3",
|
||||
CurrencyType = CurrencyType.Invalid,
|
||||
Currency = 0,
|
||||
Rarity = Rarity.Uncommon,
|
||||
Context = context
|
||||
};
|
||||
|
||||
private static async Task SeedRewardAsync(RecDBContext db, Gift box, bool consumed = false)
|
||||
{
|
||||
var reward = new GameReward
|
||||
{
|
||||
RewardSelectionId = 5150,
|
||||
Message = "Stunt Runner: The Main Event",
|
||||
GiftContext = box.Context,
|
||||
RewardType = RewardType.PostQuestActivity,
|
||||
GiftDrop1 = box,
|
||||
GiftDrop2 = box,
|
||||
GiftDrop3 = box,
|
||||
CreatedAt = DateTime.UtcNow.AddMinutes(-2),
|
||||
Consumed = consumed,
|
||||
ConsumedGiftDropId = consumed ? box.GiftDropId : 0
|
||||
};
|
||||
var json = new ProgressionJson { PendingGameRewards = new List<GameReward> { reward } };
|
||||
db.Progression.Add(new ProgressionData { PlayerId = PlayerId, Progress = json.ToJson() });
|
||||
await db.SaveChangesAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The player leaves the quest without opening the box: they get the item that was already inside
|
||||
/// it, the box is taken back, and the reward is recorded as collected against that same box.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task LeavingTheQuestWithTheBoxUnopenedDeliversTheItemItAlreadyHeld()
|
||||
{
|
||||
await using var db = NewDb();
|
||||
var recCenter = await SeedRoomAsync(db, "RecCenter");
|
||||
var box = QuestBox();
|
||||
await SeedRewardAsync(db, box);
|
||||
await StorefrontShared.PersistGiftBoxAsync(db, PlayerId, box, notify: false);
|
||||
|
||||
var delivered = await QuestRewardDelivery.DeliverOnArrivalAsync(db, PlayerId, recCenter.RoomId);
|
||||
|
||||
Assert.Equal(1, delivered);
|
||||
Assert.Empty(await StorefrontShared.GetPendingGiftsAsync(db, PlayerId));
|
||||
|
||||
var unlocks = await db.Unlocks.AsNoTracking().FirstOrDefaultAsync(x => x.AccountId == PlayerId);
|
||||
var item = Assert.Single(unlocks!.GetAvatarItems(), x => x.AvatarItemDesc == box.AvatarItemDesc);
|
||||
Assert.Equal("Runner Harness (Green)", item.FriendlyName);
|
||||
|
||||
var progression = await db.Progression.AsNoTracking().FirstAsync(x => x.PlayerId == PlayerId);
|
||||
var saved = Assert.Single(progression.GetProgressionJson()!.PendingGameRewards);
|
||||
Assert.True(saved.Consumed);
|
||||
Assert.Equal(box.GiftDropId, saved.ConsumedGiftDropId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Arriving back in the quest itself - a different instance of it, or a different rank of it -
|
||||
/// leaves the box alone, because it is still openable there.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task ArrivingInTheQuest_KeepsTheBoxOpenable()
|
||||
{
|
||||
await using var db = NewDb();
|
||||
var stuntRunner = await SeedRoomAsync(db, "StuntRunner");
|
||||
var box = QuestBox();
|
||||
await SeedRewardAsync(db, box);
|
||||
await StorefrontShared.PersistGiftBoxAsync(db, PlayerId, box, notify: false);
|
||||
|
||||
var delivered = await QuestRewardDelivery.DeliverOnArrivalAsync(db, PlayerId, stuntRunner.RoomId);
|
||||
|
||||
Assert.Equal(0, delivered);
|
||||
Assert.Single(await StorefrontShared.GetPendingGiftsAsync(db, PlayerId));
|
||||
Assert.Null(await db.Unlocks.AsNoTracking().FirstOrDefaultAsync(x => x.AccountId == PlayerId));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A box that is no quest's - a storefront purchase, a level-up box, a daily-challenge box - is
|
||||
/// not the quest's special box and is left where it is: it can be opened anywhere.
|
||||
/// </summary>
|
||||
[Theory]
|
||||
[InlineData(GiftContext.LevelUp)]
|
||||
[InlineData(GiftContext.All_Daily_Challenges_Complete)]
|
||||
[InlineData(GiftContext.Purchased_Gift_A)]
|
||||
[InlineData(GiftContext.Dodgeball)]
|
||||
public async Task ABoxThatIsNoQuestsIsLeftAlone(GiftContext context)
|
||||
{
|
||||
await using var db = NewDb();
|
||||
var recCenter = await SeedRoomAsync(db, "RecCenter");
|
||||
var box = QuestBox(context);
|
||||
await StorefrontShared.PersistGiftBoxAsync(db, PlayerId, box, notify: false);
|
||||
|
||||
var delivered = await QuestRewardDelivery.DeliverOnArrivalAsync(db, PlayerId, recCenter.RoomId);
|
||||
|
||||
Assert.Equal(0, delivered);
|
||||
Assert.Single(await StorefrontShared.GetPendingGiftsAsync(db, PlayerId));
|
||||
}
|
||||
|
||||
/// <summary>Which contexts count as a quest's own, and which do not.</summary>
|
||||
[Theory]
|
||||
[InlineData(GiftContext.StuntRunner_TheMainEvent_C, true)]
|
||||
[InlineData(GiftContext.StuntRunner_TheMainEvent_SS, true)]
|
||||
[InlineData(GiftContext.Quest_Goblin_S, true)]
|
||||
[InlineData(GiftContext.Quest_Pirate1_C, true)]
|
||||
[InlineData(GiftContext.Dodgeball, false)]
|
||||
[InlineData(GiftContext.Paintball_ClearCut, false)]
|
||||
[InlineData(GiftContext.Lasertag, false)]
|
||||
[InlineData(GiftContext.Reacquisition, false)]
|
||||
[InlineData(GiftContext.LevelUp, false)]
|
||||
[InlineData(GiftContext.GameRewards_Tokens, false)]
|
||||
public void OnlyARankedQuestsContextIsAQuestContext(GiftContext context, bool expected)
|
||||
{
|
||||
Assert.Equal(expected, RroRewardPools.IsQuestContext(context));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user