Files
RpgRoller/RpgRoller.Tests/Services/ServiceSkillRollTests.cs

191 lines
10 KiB
C#

namespace RpgRoller.Tests;
public sealed class ServiceSkillRollTests
{
[Fact]
public void CharacterSkillAndRollOperations_CheckAuthorizationAndValidationBranches()
{
using var harness = ServiceTestSupport.CreateHarness(3, 4, 5, 6);
var service = harness.Service;
service.Register("gm", "Password123", "GM");
service.Register("owner", "Password123", "Owner");
service.Register("other", "Password123", "Other");
var gmSession = ServiceTestSupport.GetValue(service.Login("gm", "Password123")).SessionToken;
var ownerSession = ServiceTestSupport.GetValue(service.Login("owner", "Password123")).SessionToken;
var otherSession = ServiceTestSupport.GetValue(service.Login("other", "Password123")).SessionToken;
var campaign = ServiceTestSupport.GetValue(service.CreateCampaign(gmSession, "Main", "dnd5e"));
var character = ServiceTestSupport.GetValue(service.CreateCharacter(ownerSession, "Owner Char", campaign.Id));
var noPermissionUpdate = service.UpdateCharacter(otherSession, character.Id, "Renamed", campaign.Id);
Assert.False(noPermissionUpdate.Succeeded);
var invalidCharacterName = service.UpdateCharacter(ownerSession, character.Id, "", campaign.Id);
Assert.False(invalidCharacterName.Succeeded);
var missingTargetCampaign = service.UpdateCharacter(ownerSession, character.Id, "Renamed", Guid.NewGuid());
Assert.False(missingTargetCampaign.Succeeded);
var noSkillName = service.CreateSkill(ownerSession, character.Id, "", "1d20", 0, false);
Assert.False(noSkillName.Succeeded);
var invalidExpression = service.CreateSkill(ownerSession, character.Id, "Skill", "5D+4", 0, false);
Assert.False(invalidExpression.Succeeded);
var skill = ServiceTestSupport.GetValue(service.CreateSkill(ownerSession, character.Id, "Skill", "1d20+2", 0, false));
var missingSkillUpdate = service.UpdateSkill(ownerSession, Guid.NewGuid(), "X", "1d20", 0, false);
Assert.False(missingSkillUpdate.Succeeded);
var forbiddenSkillUpdate = service.UpdateSkill(otherSession, skill.Id, "X", "1d20", 0, false);
Assert.False(forbiddenSkillUpdate.Succeeded);
var gmSkillUpdate = service.UpdateSkill(gmSession, skill.Id, "GM Edit", "2d6+1", 0, false);
Assert.True(gmSkillUpdate.Succeeded);
var missingRoll = service.RollSkill(ownerSession, Guid.NewGuid(), "public");
Assert.False(missingRoll.Succeeded);
var invalidVisibility = service.RollSkill(ownerSession, skill.Id, "hidden");
Assert.False(invalidVisibility.Succeeded);
var forbiddenRoll = service.RollSkill(otherSession, skill.Id, "public");
Assert.False(forbiddenRoll.Succeeded);
var privateRoll = service.RollSkill(ownerSession, skill.Id, "private");
var publicRoll = service.RollSkill(ownerSession, skill.Id, "public");
Assert.True(privateRoll.Succeeded);
Assert.True(publicRoll.Succeeded);
var ownerLog = service.GetCampaignLog(ownerSession, campaign.Id);
var gmLog = service.GetCampaignLog(gmSession, campaign.Id);
var outsiderLog = service.GetCampaignLog(otherSession, campaign.Id);
Assert.Equal(2, ServiceTestSupport.GetValue(ownerLog).Count);
Assert.Equal(2, ServiceTestSupport.GetValue(gmLog).Count);
Assert.False(outsiderLog.Succeeded);
Assert.All(ServiceTestSupport.GetValue(ownerLog), entry => Assert.NotEmpty(entry.Dice));
Assert.All(ServiceTestSupport.GetValue(gmLog), entry => Assert.NotEmpty(entry.Dice));
var state = service.GetCampaignStateSnapshot(ownerSession, campaign.Id);
var missingState = service.GetCampaignStateSnapshot(ownerSession, Guid.NewGuid());
Assert.True(state.Succeeded);
Assert.False(missingState.Succeeded);
Assert.True(ServiceTestSupport.GetValue(state).LogVersion > 1);
}
[Fact]
public void CampaignLogPage_ReturnsInitialWindowAndIncrementalAppend()
{
using var harness = ServiceTestSupport.CreateHarness(6, 5, 4, 3, 2, 6, 5, 4, 3, 2, 6, 5);
var service = harness.Service;
service.Register("gm-page", "Password123", "GM");
service.Register("owner-page", "Password123", "Owner");
var gmSession = ServiceTestSupport.GetValue(service.Login("gm-page", "Password123")).SessionToken;
var ownerSession = ServiceTestSupport.GetValue(service.Login("owner-page", "Password123")).SessionToken;
var campaign = ServiceTestSupport.GetValue(service.CreateCampaign(gmSession, "Paged", "d6"));
var character = ServiceTestSupport.GetValue(service.CreateCharacter(ownerSession, "Hero", campaign.Id));
var skill = ServiceTestSupport.GetValue(service.CreateSkill(ownerSession, character.Id, "Stealth", "2D+1", 1, true));
var rollIds = new List<Guid>();
for (var i = 0; i < 5; i++)
rollIds.Add(ServiceTestSupport.GetValue(service.RollSkill(ownerSession, skill.Id, "public")).RollId);
var initialPage = ServiceTestSupport.GetValue(service.GetCampaignLogPage(gmSession, campaign.Id, limit: 3));
Assert.Equal(3, initialPage.Entries.Length);
Assert.Equal(rollIds[2], initialPage.Entries[0].RollId);
Assert.Equal(rollIds[^1], initialPage.Entries[^1].RollId);
Assert.Equal(rollIds[^1], initialPage.Cursor);
Assert.True(initialPage.HasMore);
Assert.False(initialPage.ResetRequired);
Assert.All(initialPage.Entries, entry =>
{
Assert.False(string.IsNullOrWhiteSpace(entry.SummaryText));
Assert.False(string.IsNullOrWhiteSpace(entry.RollerLabel));
});
var latestRoll = ServiceTestSupport.GetValue(service.RollSkill(ownerSession, skill.Id, "public"));
var incrementalPage = ServiceTestSupport.GetValue(service.GetCampaignLogPage(gmSession, campaign.Id, initialPage.Cursor, 3));
Assert.Single(incrementalPage.Entries);
Assert.Equal(latestRoll.RollId, incrementalPage.Entries[0].RollId);
Assert.Equal(latestRoll.RollId, incrementalPage.Cursor);
Assert.False(incrementalPage.HasMore);
Assert.False(incrementalPage.ResetRequired);
}
[Fact]
public void CampaignLogPage_RequestsResetWhenIncrementalGapExceedsLimit()
{
using var harness = ServiceTestSupport.CreateHarness(6, 5, 4, 3, 2, 6, 5, 4, 3, 2, 6, 5);
var service = harness.Service;
service.Register("gm-gap", "Password123", "GM");
service.Register("owner-gap", "Password123", "Owner");
var gmSession = ServiceTestSupport.GetValue(service.Login("gm-gap", "Password123")).SessionToken;
var ownerSession = ServiceTestSupport.GetValue(service.Login("owner-gap", "Password123")).SessionToken;
var campaign = ServiceTestSupport.GetValue(service.CreateCampaign(gmSession, "Gap", "d6"));
var character = ServiceTestSupport.GetValue(service.CreateCharacter(ownerSession, "Hero", campaign.Id));
var skill = ServiceTestSupport.GetValue(service.CreateSkill(ownerSession, character.Id, "Stealth", "2D+1", 1, true));
var rollIds = new List<Guid>();
for (var i = 0; i < 6; i++)
rollIds.Add(ServiceTestSupport.GetValue(service.RollSkill(ownerSession, skill.Id, "public")).RollId);
var gapPage = ServiceTestSupport.GetValue(service.GetCampaignLogPage(gmSession, campaign.Id, rollIds[0], 3));
Assert.True(gapPage.ResetRequired);
Assert.True(gapPage.HasMore);
Assert.Equal(3, gapPage.Entries.Length);
Assert.Equal(rollIds[3], gapPage.Entries[0].RollId);
Assert.Equal(rollIds[^1], gapPage.Entries[^1].RollId);
Assert.Equal(rollIds[^1], gapPage.Cursor);
}
[Fact]
public void RollDetail_ReturnsVisibleDetailAndHidesPrivateRoll()
{
using var harness = ServiceTestSupport.CreateHarness(6, 5, 4, 3, 2, 6);
var service = harness.Service;
service.Register("gm-detail", "Password123", "GM");
service.Register("owner-detail", "Password123", "Owner");
service.Register("observer-detail", "Password123", "Observer");
service.Register("outsider-detail", "Password123", "Outsider");
var gmSession = ServiceTestSupport.GetValue(service.Login("gm-detail", "Password123")).SessionToken;
var ownerSession = ServiceTestSupport.GetValue(service.Login("owner-detail", "Password123")).SessionToken;
var observerSession = ServiceTestSupport.GetValue(service.Login("observer-detail", "Password123")).SessionToken;
var outsiderSession = ServiceTestSupport.GetValue(service.Login("outsider-detail", "Password123")).SessionToken;
var campaign = ServiceTestSupport.GetValue(service.CreateCampaign(gmSession, "Detail", "d6"));
var ownerCharacter = ServiceTestSupport.GetValue(service.CreateCharacter(ownerSession, "Hero", campaign.Id));
_ = ServiceTestSupport.GetValue(service.CreateCharacter(observerSession, "Watcher", campaign.Id));
var skill = ServiceTestSupport.GetValue(service.CreateSkill(ownerSession, ownerCharacter.Id, "Stealth", "2D+1", 1, true));
var privateRoll = ServiceTestSupport.GetValue(service.RollSkill(ownerSession, skill.Id, "private"));
var publicRoll = ServiceTestSupport.GetValue(service.RollSkill(ownerSession, skill.Id, "public"));
var gmDetail = ServiceTestSupport.GetValue(service.GetRollDetail(gmSession, privateRoll.RollId));
var ownerDetail = ServiceTestSupport.GetValue(service.GetRollDetail(ownerSession, privateRoll.RollId));
var observerPublicDetail = ServiceTestSupport.GetValue(service.GetRollDetail(observerSession, publicRoll.RollId));
var observerPrivateDetail = service.GetRollDetail(observerSession, privateRoll.RollId);
var outsiderPublicDetail = service.GetRollDetail(outsiderSession, publicRoll.RollId);
Assert.NotEmpty(gmDetail.Dice);
Assert.Equal(privateRoll.RollId, gmDetail.RollId);
Assert.Equal(privateRoll.Breakdown, ownerDetail.Breakdown);
Assert.Equal(publicRoll.RollId, observerPublicDetail.RollId);
Assert.False(observerPrivateDetail.Succeeded);
Assert.Equal("roll_not_found", observerPrivateDetail.Error!.Code);
Assert.False(outsiderPublicDetail.Succeeded);
Assert.Equal("roll_not_found", outsiderPublicDetail.Error!.Code);
}
}