namespace RpgRoller.Tests; public sealed class ServiceCampaignTests { [Fact] public void CampaignAndCharacterOperations_CheckUnauthorizedAndNotFoundCases() { using var harness = ServiceTestSupport.CreateHarness(); var service = harness.Service; var unauthorizedCampaign = service.CreateCampaign("missing", "Name", "d6"); Assert.False(unauthorizedCampaign.Succeeded); service.Register("gm", "Password123", "GM"); var gmSession = ServiceTestSupport.GetValue(service.Login("gm", "Password123")).SessionToken; var campaign = ServiceTestSupport.GetValue(service.CreateCampaign(gmSession, "Name", "d6")); var invalidRuleset = service.CreateCampaign(gmSession, "Name 2", "unknown"); Assert.False(invalidRuleset.Succeeded); var noCampaignCharacter = service.CreateCharacter(gmSession, "Hero", Guid.NewGuid()); Assert.False(noCampaignCharacter.Succeeded); var character = ServiceTestSupport.GetValue(service.CreateCharacter(gmSession, "Hero", campaign.Id)); var missingCharacterActivate = service.ActivateCharacter(gmSession, Guid.NewGuid()); Assert.False(missingCharacterActivate.Succeeded); var activateSuccess = service.ActivateCharacter(gmSession, character.Id); Assert.True(activateSuccess.Succeeded); var currentCharacters = service.GetOwnCharacters(gmSession); Assert.True(currentCharacters.Succeeded); Assert.Single(ServiceTestSupport.GetValue(currentCharacters)); var missingCampaignGet = service.GetCampaign(gmSession, Guid.NewGuid()); Assert.False(missingCampaignGet.Succeeded); } [Fact] public void CurrentCampaignCharacters_ReturnsNoActiveCharacterWhenUnset() { using var harness = ServiceTestSupport.CreateHarness(); var service = harness.Service; service.Register("user", "Password123", "User"); var sessionToken = ServiceTestSupport.GetValue(service.Login("user", "Password123")).SessionToken; var result = service.GetOwnCharacters(sessionToken); Assert.True(result.Succeeded); Assert.Empty(ServiceTestSupport.GetValue(result)); } [Fact] public void GetCampaigns_ReturnsOwnedAndParticipatingCampaigns() { using var harness = ServiceTestSupport.CreateHarness(); var service = harness.Service; service.Register("gm", "Password123", "GM"); service.Register("player", "Password123", "Player"); var gmSession = ServiceTestSupport.GetValue(service.Login("gm", "Password123")).SessionToken; var playerSession = ServiceTestSupport.GetValue(service.Login("player", "Password123")).SessionToken; var gmCampaign = ServiceTestSupport.GetValue(service.CreateCampaign(gmSession, "Owned", "d6")); _ = ServiceTestSupport.GetValue(service.CreateCampaign(gmSession, "Owned 2", "d6")); _ = service.CreateCharacter(playerSession, "Joiner", gmCampaign.Id); var playerCampaigns = service.GetCampaigns(playerSession); Assert.True(playerCampaigns.Succeeded); var campaigns = ServiceTestSupport.GetValue(playerCampaigns); Assert.Single(campaigns); Assert.Equal(gmCampaign.Id, campaigns[0].Id); } [Fact] public void GetCharacterCampaignOptions_ReturnsAllCampaignsForCharacterAssignment() { using var harness = ServiceTestSupport.CreateHarness(); var service = harness.Service; service.Register("gm1", "Password123", "GM One"); service.Register("gm2", "Password123", "GM Two"); service.Register("player", "Password123", "Player"); var gmSession = ServiceTestSupport.GetValue(service.Login("gm1", "Password123")).SessionToken; var gmTwoSession = ServiceTestSupport.GetValue(service.Login("gm2", "Password123")).SessionToken; var playerSession = ServiceTestSupport.GetValue(service.Login("player", "Password123")).SessionToken; var firstCampaign = ServiceTestSupport.GetValue(service.CreateCampaign(gmSession, "Alpha", "d6")); var secondCampaign = ServiceTestSupport.GetValue(service.CreateCampaign(gmTwoSession, "Beta", "d6")); var visibleCampaigns = ServiceTestSupport.GetValue(service.GetCampaigns(playerSession)); Assert.Empty(visibleCampaigns); var options = ServiceTestSupport.GetValue(service.GetCharacterCampaignOptions(playerSession)); Assert.Equal(2, options.Count); Assert.Contains(options, option => option.Id == firstCampaign.Id); Assert.Contains(options, option => option.Id == secondCampaign.Id); } [Fact] public void GetCampaignAndCharacterSheet_ForNonGmParticipant_ReturnCampaignRosterAndSheet() { using var harness = ServiceTestSupport.CreateHarness(); 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", "d6")); var ownerCharacter = ServiceTestSupport.GetValue(service.CreateCharacter(ownerSession, "Owner Character", campaign.Id)); var otherCharacter = ServiceTestSupport.GetValue(service.CreateCharacter(otherSession, "Other Character", campaign.Id)); var ownerSkill = ServiceTestSupport.GetValue(service.CreateSkill(ownerSession, ownerCharacter.Id, "Stealth", "2D+1", 1, true)); _ = ServiceTestSupport.GetValue(service.CreateSkill(otherSession, otherCharacter.Id, "Perception", "1D+2", 1, true)); var ownerView = ServiceTestSupport.GetValue(service.GetCampaign(ownerSession, campaign.Id)); Assert.Equal(2, ownerView.Characters.Length); Assert.Contains(ownerView.Characters, character => character.Id == ownerCharacter.Id); Assert.Contains(ownerView.Characters, character => character.Id == otherCharacter.Id); var ownerSheet = ServiceTestSupport.GetValue(service.GetCharacterSheet(ownerSession, ownerCharacter.Id)); var otherSheet = ServiceTestSupport.GetValue(service.GetCharacterSheet(ownerSession, otherCharacter.Id)); Assert.Single(ownerSheet.Skills); Assert.Contains(ownerSheet.Skills, skill => skill.Id == ownerSkill.Id); Assert.Single(otherSheet.Skills); } [Fact] public void CampaignStateSnapshot_TracksRosterCharacterAndLogSlicesIndependently() { using var harness = ServiceTestSupport.CreateHarness(4, 5, 6, 3); var service = harness.Service; service.Register("gm-state", "Password123", "GM"); service.Register("owner-state", "Password123", "Owner"); var gmSession = ServiceTestSupport.GetValue(service.Login("gm-state", "Password123")).SessionToken; var ownerSession = ServiceTestSupport.GetValue(service.Login("owner-state", "Password123")).SessionToken; var campaign = ServiceTestSupport.GetValue(service.CreateCampaign(gmSession, "State Campaign", "d6")); var character = ServiceTestSupport.GetValue(service.CreateCharacter(ownerSession, "State Hero", campaign.Id)); var afterCharacterCreate = ServiceTestSupport.GetValue(service.GetCampaignStateSnapshot(ownerSession, campaign.Id)); var initialCharacterVersion = Assert.Single(afterCharacterCreate.CharacterVersions, version => version.CharacterId == character.Id).Version; Assert.True(afterCharacterCreate.RosterVersion > 1); var skill = ServiceTestSupport.GetValue(service.CreateSkill(ownerSession, character.Id, "Stealth", "2D+1", 1, true)); var afterSkillCreate = ServiceTestSupport.GetValue(service.GetCampaignStateSnapshot(ownerSession, campaign.Id)); var updatedCharacterVersion = Assert.Single(afterSkillCreate.CharacterVersions, version => version.CharacterId == character.Id).Version; Assert.Equal(afterCharacterCreate.RosterVersion, afterSkillCreate.RosterVersion); Assert.True(updatedCharacterVersion > initialCharacterVersion); _ = ServiceTestSupport.GetValue(service.RollSkill(ownerSession, skill.Id, "public")); var afterRoll = ServiceTestSupport.GetValue(service.GetCampaignStateSnapshot(ownerSession, campaign.Id)); Assert.Equal(afterSkillCreate.RosterVersion, afterRoll.RosterVersion); Assert.Equal(updatedCharacterVersion, Assert.Single(afterRoll.CharacterVersions, version => version.CharacterId == character.Id).Version); Assert.True(afterRoll.LogVersion > afterSkillCreate.LogVersion); } }