namespace RpgRoller.Tests; public sealed class RolemasterApiTests(WebApplicationFactory factory) : ApiTestBase(factory) { [Fact] public async Task RolemasterRollEndpoints_ExecuteGenericRolemasterExpressions() { using var factory = CreateFactory(8, 6, 74); using var client = factory.CreateClient(new() { AllowAutoRedirect = false }); await RegisterAsync(client, "rolemaster-api", "Password123", "Rolemaster Api"); await LoginAsync(client, "rolemaster-api", "Password123"); var campaign = await PostAsync(client, "/api/campaigns", new("Rolemaster", "rolemaster")); var character = await PostAsync(client, "/api/characters", new("Hero", campaign.Id)); var initiative = await PostAsync(client, $"/api/characters/{character.Id}/skills", new("Healing", "2d10+48", 0, false)); var perception = await PostAsync(client, $"/api/characters/{character.Id}/skills", new("Perception", "d100-15", 0, false)); var initiativeRoll = await PostAsync(client, $"/api/skills/{initiative.Id}/roll", new("public")); var percentileRoll = await PostAsync(client, $"/api/skills/{perception.Id}/roll", new("public")); var logPage = await GetAsync(client, $"/api/campaigns/{campaign.Id}/log/page?limit=10"); Assert.Equal(62, initiativeRoll.Result); Assert.Equal("8+6+48=62", initiativeRoll.Breakdown); Assert.All(initiativeRoll.Dice, die => Assert.Equal(RollDieKinds.RolemasterStandard, die.Kind)); Assert.Equal(59, percentileRoll.Result); Assert.Equal("74-15=59", percentileRoll.Breakdown); Assert.Equal(RollDieKinds.RolemasterStandard, Assert.Single(percentileRoll.Dice).Kind); Assert.Equal(2, logPage.Entries.Length); Assert.Equal("8 + 6 | rolemaster", logPage.Entries[0].SummaryText); Assert.Null(logPage.Entries[0].EventBadges); Assert.Equal("74 | rolemaster", logPage.Entries[1].SummaryText); Assert.Null(logPage.Entries[1].EventBadges); } [Fact] public async Task RolemasterOpenEndedRolls_AppearInLogPageAndDetail() { using var factory = CreateFactory(5, 97, 100, 12); using var client = factory.CreateClient(new() { AllowAutoRedirect = false }); await RegisterAsync(client, "rolemaster-open-api", "Password123", "Rolemaster Open Api"); await LoginAsync(client, "rolemaster-open-api", "Password123"); var campaign = await PostAsync(client, "/api/campaigns", new("Rolemaster Open", "rolemaster")); var character = await PostAsync(client, "/api/characters", new("Hero", campaign.Id)); var skill = await PostAsync(client, $"/api/characters/{character.Id}/skills", new("Awareness", "d100!+85", 0, false, null, 5)); var roll = await PostAsync(client, $"/api/skills/{skill.Id}/roll", new("public")); var logPage = await GetAsync(client, $"/api/campaigns/{campaign.Id}/log/page?limit=5"); var detail = await GetAsync(client, $"/api/rolls/{roll.RollId}"); Assert.Equal(-124, roll.Result); Assert.Equal("(05) -97 -100 -12 +85 = -124", roll.Breakdown); var logEntry = Assert.Single(logPage.Entries); Assert.Equal("(05) -97 -100 -12 | open-ended low", logEntry.SummaryText); var eventBadges = Assert.IsType(logEntry.EventBadges); Assert.Collection(eventBadges, badge => Assert.Equal("rf", badge), badge => Assert.Equal("r100", badge)); Assert.Equal(roll.Breakdown, detail.Breakdown); Assert.Collection(detail.Dice, die => { Assert.Equal(RollDieKinds.RolemasterOpenEndedInitial, die.Kind); Assert.Equal(1, die.Sequence); Assert.Null(die.SignedContribution); }, die => { Assert.Equal(RollDieKinds.RolemasterOpenEndedLowSubtract, die.Kind); Assert.Equal(2, die.Sequence); Assert.Equal(-97, die.SignedContribution); }, die => { Assert.Equal(RollDieKinds.RolemasterOpenEndedLowSubtract, die.Kind); Assert.Equal(3, die.Sequence); Assert.Equal(-100, die.SignedContribution); }, die => { Assert.Equal(RollDieKinds.RolemasterOpenEndedLowSubtract, die.Kind); Assert.Equal(4, die.Sequence); Assert.Equal(-12, die.SignedContribution); }); } [Fact] public async Task RolemasterAutoRetryRolls_AppearInLogPageAndDetail() { using var factory = CreateFactory(68, 42, 90, 32, 68); using var client = factory.CreateClient(new() { AllowAutoRedirect = false }); await RegisterAsync(client, "rolemaster-retry-api", "Password123", "Rolemaster Retry Api"); await LoginAsync(client, "rolemaster-retry-api", "Password123"); var campaign = await PostAsync(client, "/api/campaigns", new("Rolemaster Retry", "rolemaster")); var character = await PostAsync(client, "/api/characters", new("Hero", campaign.Id)); var retryFiveSkill = await PostAsync(client, $"/api/characters/{character.Id}/skills", new("Awareness +5", "d100!+10", 0, false, null, 5, true)); var retryTenSkill = await PostAsync(client, $"/api/characters/{character.Id}/skills", new("Awareness +10", "d100!+1", 0, false, null, 5, true)); var disabledSkill = await PostAsync(client, $"/api/characters/{character.Id}/skills", new("Awareness Off", "d100!+10", 0, false, null, 5)); var retryFiveRoll = await PostAsync(client, $"/api/skills/{retryFiveSkill.Id}/roll", new("public")); var retryTenRoll = await PostAsync(client, $"/api/skills/{retryTenSkill.Id}/roll", new("public")); var disabledRoll = await PostAsync(client, $"/api/skills/{disabledSkill.Id}/roll", new("public")); var logPage = await GetAsync(client, $"/api/campaigns/{campaign.Id}/log/page?limit=10"); var detail = await GetAsync(client, $"/api/rolls/{retryFiveRoll.RollId}"); Assert.Equal(57, retryFiveRoll.Result); Assert.Equal("68+10=78; retry(+5): 42+10=52; final=57", retryFiveRoll.Breakdown); Assert.Collection(retryFiveRoll.Dice, die => { Assert.Equal(1, die.Attempt); Assert.Equal(1, die.Sequence); }, die => { Assert.Equal(2, die.Attempt); Assert.Equal(1, die.Sequence); }); Assert.Equal(43, retryTenRoll.Result); Assert.Equal("90+1=91; retry(+10): 32+1=33; final=43", retryTenRoll.Breakdown); Assert.Equal(78, disabledRoll.Result); Assert.Equal("68+10=78", disabledRoll.Breakdown); Assert.All(disabledRoll.Dice, die => Assert.Null(die.Attempt)); Assert.Equal(3, logPage.Entries.Length); Assert.Equal("68 | open-ended | retry +5", logPage.Entries[0].SummaryText); Assert.Equal(["rs5"], Assert.IsType(logPage.Entries[0].EventBadges)); Assert.Equal("90 | open-ended | retry +10", logPage.Entries[1].SummaryText); Assert.Equal(["rs10"], Assert.IsType(logPage.Entries[1].EventBadges)); Assert.Equal("68 | open-ended", logPage.Entries[2].SummaryText); Assert.Null(logPage.Entries[2].EventBadges); Assert.Equal(retryFiveRoll.Breakdown, detail.Breakdown); Assert.Collection(detail.Dice, die => { Assert.Equal(1, die.Attempt); Assert.Equal(RollDieKinds.RolemasterOpenEndedInitial, die.Kind); }, die => { Assert.Equal(2, die.Attempt); Assert.Equal(RollDieKinds.RolemasterOpenEndedInitial, die.Kind); }); } }