VanguardReMaster/server/tests/Vanguard.Server.Tests/MetaProfileServiceTests.cs

121 lines
3.8 KiB
C#

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging.Abstractions;
using Vanguard.Server.Configuration;
using Vanguard.Server.Matches;
using Vanguard.Server.Meta;
using Vanguard.Server.Storage;
namespace Vanguard.Server.Tests;
public class MetaProfileServiceTests
{
private static readonly DateTimeOffset Start = new(2026, 10, 21, 12, 0, 0, TimeSpan.Zero);
[Fact]
public async Task Forfeit_Records_History_Without_Gold_Or_Xp()
{
var factory = new TestFactory();
await CreateUsersAsync(factory);
var service = NewService(factory);
await service.RecordAsync(new MatchResult(
"m-forfeit", GameMode.ClassicRanked, "p1", "p2", 0,
MatchFinishReason.Concede));
await using var db = factory.CreateDbContext();
var rows = await db.MatchHistory.OrderBy(row => row.UserId).ToListAsync();
Assert.Equal(2, rows.Count);
Assert.All(rows, row =>
{
Assert.Equal(0, row.Gold);
Assert.Equal(0, row.Xp);
Assert.Equal("concede", row.FinishReason);
});
}
[Fact]
public async Task Normal_Finish_Gives_Gold_Xp_And_Is_Idempotent()
{
var factory = new TestFactory();
await CreateUsersAsync(factory);
var service = NewService(factory);
var result = new MatchResult(
"m-normal", GameMode.ClassicRanked, "p1", "p2", 0,
MatchFinishReason.Normal);
await service.RecordAsync(result);
await service.RecordAsync(result);
await using var db = factory.CreateDbContext();
var rows = await db.MatchHistory.OrderBy(row => row.Result).ToListAsync();
Assert.Equal(2, rows.Count);
var win = Assert.Single(rows, row => row.Result == "win");
var loss = Assert.Single(rows, row => row.Result == "loss");
Assert.Equal(30, win.Gold);
Assert.Equal(150, win.Xp);
Assert.Equal(15, loss.Gold);
Assert.Equal(75, loss.Xp);
var winner = await db.Users.SingleAsync(user => user.NormalizedUserName == "P1");
var loser = await db.Users.SingleAsync(user => user.NormalizedUserName == "P2");
Assert.Equal(150, winner.Xp);
Assert.Equal(75, loser.Xp);
Assert.True(winner.RankedMmr > 1000);
Assert.True(loser.RankedMmr < 1000);
}
private static MetaProfileService NewService(TestFactory factory) => new(
factory,
new MetaOptions(),
new FakeTimeProvider(Start),
NullLogger<MetaProfileService>.Instance);
private static async Task CreateUsersAsync(TestFactory factory)
{
await using var db = factory.CreateDbContext();
db.Users.AddRange(
new UserEntity
{
Id = Guid.NewGuid(),
UserName = "p1",
NormalizedUserName = "P1",
PasswordHash = "x",
CreatedAt = Start,
RankedMmr = 1000,
CasualMmr = 1000,
},
new UserEntity
{
Id = Guid.NewGuid(),
UserName = "p2",
NormalizedUserName = "P2",
PasswordHash = "x",
CreatedAt = Start,
RankedMmr = 1000,
CasualMmr = 1000,
});
await db.SaveChangesAsync();
}
private sealed class TestFactory : IDbContextFactory<MatchDbContext>
{
private readonly DbContextOptions<MatchDbContext> _options;
public TestFactory()
{
_options = new DbContextOptionsBuilder<MatchDbContext>()
.UseInMemoryDatabase("meta-profile-" + Guid.NewGuid().ToString("N"))
.Options;
}
public MatchDbContext CreateDbContext() => new(_options);
}
}