Code Cleanup

This commit is contained in:
2026-04-05 01:32:52 +02:00
parent 305999e4b7
commit 46a63f9e06
109 changed files with 939 additions and 1125 deletions

View File

@@ -48,4 +48,4 @@ public sealed class AuthApiTests : ApiTestBase
var usernames = await GetAsync<IReadOnlyList<string>>(client, "/api/users/usernames");
Assert.Equal(["amy", "bob", "zoe"], usernames);
}
}
}

View File

@@ -138,7 +138,7 @@ public sealed class CampaignApiTests : ApiTestBase
var groupedSkill = await PostAsync<CreateSkillRequest, SkillSummary>(ownerClient, $"/api/characters/{character.Id}/skills", new("Strike", "2D+1", 1, true, renamedGroup.Id));
Assert.Equal(renamedGroup.Id, groupedSkill.SkillGroupId);
var ungroupedSkill = await PutAsync<UpdateSkillRequest, SkillSummary>(ownerClient, $"/api/skills/{groupedSkill.Id}", new("Strike", "2D+1", 1, true, null));
var ungroupedSkill = await PutAsync<UpdateSkillRequest, SkillSummary>(ownerClient, $"/api/skills/{groupedSkill.Id}", new("Strike", "2D+1", 1, true));
Assert.Null(ungroupedSkill.SkillGroupId);
var groupedAgainSkill = await PutAsync<UpdateSkillRequest, SkillSummary>(ownerClient, $"/api/skills/{groupedSkill.Id}", new("Strike", "2D+1", 1, true, renamedGroup.Id));
@@ -187,7 +187,7 @@ public sealed class CampaignApiTests : ApiTestBase
Assert.Contains(adminEntry.Roles, role => string.Equals(role, "admin", StringComparison.OrdinalIgnoreCase));
Assert.Empty(playerEntry.Roles);
var promotedPlayer = await PutAsync<UpdateUserRolesRequest, AdminUserSummary>(adminClient, $"/api/admin/users/{player.Id}/roles", new([ "admin" ]));
var promotedPlayer = await PutAsync<UpdateUserRolesRequest, AdminUserSummary>(adminClient, $"/api/admin/users/{player.Id}/roles", new(["admin"]));
Assert.Contains(promotedPlayer.Roles, role => string.Equals(role, "admin", StringComparison.OrdinalIgnoreCase));
var campaign = await PostAsync<CreateCampaignRequest, CampaignSummary>(gmClient, "/api/campaigns", new("Disposable Campaign", "d6"));
@@ -404,4 +404,4 @@ public sealed class CampaignApiTests : ApiTestBase
Assert.Equal(latestRoll.Breakdown, detail.Breakdown);
Assert.NotEmpty(detail.Dice);
}
}
}

View File

@@ -18,4 +18,4 @@ public sealed class FrontendHostTests : ApiTestBase
Assert.Contains("_framework/blazor.web.js", html);
Assert.Contains("Connecting...", html);
}
}
}

View File

@@ -24,4 +24,4 @@ public sealed class ResponseCompressionApiTests : ApiTestBase
response.EnsureSuccessStatusCode();
Assert.Contains("gzip", response.Content.Headers.ContentEncoding);
}
}
}

View File

@@ -61,36 +61,28 @@ public sealed class RolemasterApiTests : ApiTestBase
var logEntry = Assert.Single(logPage.Entries);
Assert.Equal("(05) -97 -100 -12 | open-ended low", logEntry.SummaryText);
var eventBadges = Assert.IsType<string[]>(logEntry.EventBadges);
Assert.Collection(
eventBadges,
badge => Assert.Equal("rf", badge),
badge => Assert.Equal("r100", badge));
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);
});
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);
});
}
}
}

View File

@@ -97,4 +97,4 @@ public sealed class RollVisibilityApiTests : ApiTestBase
var unauthorizedWithInvalidSession = await anonymousClient.SendAsync(invalidSessionRequest);
Assert.Equal(HttpStatusCode.Unauthorized, unauthorizedWithInvalidSession.StatusCode);
}
}
}

View File

@@ -26,4 +26,4 @@ public sealed class SystemApiTests : ApiTestBase
Assert.Equal(HttpStatusCode.OK, sseResponse.StatusCode);
Assert.Equal("text/event-stream", sseResponse.Content.Headers.ContentType?.MediaType);
}
}
}

View File

@@ -1,5 +1,5 @@
using Microsoft.Data.Sqlite;
using Microsoft.AspNetCore.Builder;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
@@ -218,12 +218,8 @@ public sealed class HostingCoverageTests
using var db = new RpgRollerDbContext(options);
var migrator = db.GetService<IMigrator>();
var charactersScript = migrator.GenerateScript(
fromMigration: "20260226131003_AddSkillGroupPrototypes",
toMigration: "20260226160859_AddAuthorizationRolesAndCampaignDeletion");
var rolesScript = migrator.GenerateScript(
fromMigration: "20260226160859_AddAuthorizationRolesAndCampaignDeletion",
toMigration: "20260226170000_AddAuthorizationRoles");
var charactersScript = migrator.GenerateScript("20260226131003_AddSkillGroupPrototypes", "20260226160859_AddAuthorizationRolesAndCampaignDeletion");
var rolesScript = migrator.GenerateScript("20260226160859_AddAuthorizationRolesAndCampaignDeletion", "20260226170000_AddAuthorizationRoles");
Assert.Contains("""CREATE TABLE "ef_temp_Characters" (""", charactersScript);
Assert.DoesNotContain("""ALTER TABLE "Users" ADD "Roles" TEXT NOT NULL DEFAULT 'admin';""", charactersScript);
@@ -359,7 +355,7 @@ public sealed class HostingCoverageTests
{
var sourceDbPath = Path.Combine(AppContext.BaseDirectory, "..", "..", "..", "..", "RpgRoller", "App_Data", "rpgroller.development.db");
var copiedDbPath = Path.Combine(Path.GetTempPath(), $"rpgroller-dev-copy-{Guid.NewGuid():N}.db");
File.Copy(Path.GetFullPath(sourceDbPath), copiedDbPath, overwrite: true);
File.Copy(Path.GetFullPath(sourceDbPath), copiedDbPath, true);
Guid skillId;
Guid ownerUserId;
@@ -427,10 +423,7 @@ public sealed class HostingCoverageTests
builder.Logging.AddFilter("Microsoft.AspNetCore", LogLevel.Warning);
builder.Logging.AddFilter("Microsoft.EntityFrameworkCore", LogLevel.Warning);
builder.Logging.AddFilter("Microsoft.Hosting", LogLevel.Warning);
builder.Configuration.AddInMemoryCollection(new Dictionary<string, string?>
{
["ConnectionStrings:RpgRoller"] = $"Data Source={copiedDbPath}"
});
builder.Configuration.AddInMemoryCollection(new Dictionary<string, string?> { ["ConnectionStrings:RpgRoller"] = $"Data Source={copiedDbPath}" });
builder.Services.AddRpgRollerCore(builder.Configuration, builder.Environment);
using var app = builder.Build();
@@ -450,9 +443,9 @@ public sealed class HostingCoverageTests
using var countsAfterCommand = verifyConnection.CreateCommand();
countsAfterCommand.CommandText = """
SELECT (SELECT COUNT(*) FROM Campaigns),
(SELECT COUNT(*) FROM Skills);
""";
SELECT (SELECT COUNT(*) FROM Campaigns),
(SELECT COUNT(*) FROM Skills);
""";
using var countsAfterReader = countsAfterCommand.ExecuteReader();
Assert.True(countsAfterReader.Read());
Assert.Equal(campaignCountBefore, countsAfterReader.GetInt32(0));
@@ -481,4 +474,4 @@ public sealed class HostingCoverageTests
var authorizationRolesHistoryCount = Convert.ToInt32(authorizationRolesHistoryCommand.ExecuteScalar());
Assert.Equal(1, authorizationRolesHistoryCount);
}
}
}

View File

@@ -1,5 +1,4 @@
using System.Text.Json;
using RpgRoller.Contracts;
namespace RpgRoller.Tests;
@@ -133,7 +132,7 @@ public sealed class PayloadBudgetTests
[Fact]
public void RolemasterRollDetailPayload_StaysWithinBudget_AndRolemasterMetadataRemainsLazy()
{
using var harness = ServiceTestSupport.CreateHarness([96, 100, 100, 100, 100, 97, 12]);
using var harness = ServiceTestSupport.CreateHarness(96, 100, 100, 100, 100, 97, 12);
var service = harness.Service;
service.Register("gm-rm-detail-budget", "Password123", "GM");
@@ -192,4 +191,4 @@ public sealed class PayloadBudgetTests
}
private static readonly JsonSerializerOptions SerializerOptions = RpgRollerJson.CreateSerializerOptions();
}
}

View File

@@ -56,4 +56,4 @@ public sealed class DiceRulesTests
Assert.Equal("rolemaster", DiceRules.ToRulesetId(RulesetKind.Rolemaster));
Assert.Throws<ArgumentOutOfRangeException>(() => DiceRules.ToRulesetId((RulesetKind)99));
}
}
}

View File

@@ -1,5 +1,3 @@
using RpgRoller.Domain;
namespace RpgRoller.Tests;
public sealed class ServiceAdminAndCampaignDeletionTests
@@ -139,4 +137,4 @@ public sealed class ServiceAdminAndCampaignDeletionTests
Assert.DoesNotContain(db.Characters, character => character.Id == gmCharacterOutsideOwnedCampaign.Id);
}
}
}

View File

@@ -74,4 +74,4 @@ public sealed class ServiceAuthTests
var usernames = ServiceTestSupport.GetValue(service.GetUsernames(session));
Assert.Equal(["amy", "bob", "zoe"], usernames);
}
}
}

View File

@@ -163,4 +163,4 @@ public sealed class ServiceCampaignTests
Assert.Equal(updatedCharacterVersion, Assert.Single(afterRoll.CharacterVersions, version => version.CharacterId == character.Id).Version);
Assert.True(afterRoll.LogVersion > afterSkillCreate.LogVersion);
}
}
}

View File

@@ -64,4 +64,4 @@ public sealed class ServiceHelperExtractionTests
Assert.False(invalidRolemaster.Succeeded);
Assert.Equal("invalid_fumble_range", invalidRolemaster.Error!.Code);
}
}
}

View File

@@ -119,4 +119,4 @@ public sealed class ServicePersistenceTests
var reloadedSkill = Assert.Single(reloadedSheet.Skills, current => current.Id == skill.Id);
Assert.Equal(3, reloadedSkill.FumbleRange);
}
}
}

View File

@@ -20,22 +20,19 @@ public sealed class ServiceRolemasterRollTests
Assert.Equal(65, roll.Result);
Assert.Equal("7+10+48=65", roll.Breakdown);
Assert.Equal("7 + 10 | rolemaster", Assert.Single(logPage.Entries).SummaryText);
Assert.Collection(
roll.Dice,
die =>
{
Assert.Equal(7, die.Roll);
Assert.Equal(1, die.Sequence);
Assert.Equal(RollDieKinds.RolemasterStandard, die.Kind);
Assert.Equal(7, die.SignedContribution);
},
die =>
{
Assert.Equal(10, die.Roll);
Assert.Equal(2, die.Sequence);
Assert.Equal(RollDieKinds.RolemasterStandard, die.Kind);
Assert.Equal(10, die.SignedContribution);
});
Assert.Collection(roll.Dice, die =>
{
Assert.Equal(7, die.Roll);
Assert.Equal(1, die.Sequence);
Assert.Equal(RollDieKinds.RolemasterStandard, die.Kind);
Assert.Equal(7, die.SignedContribution);
}, die =>
{
Assert.Equal(10, die.Roll);
Assert.Equal(2, die.Sequence);
Assert.Equal(RollDieKinds.RolemasterStandard, die.Kind);
Assert.Equal(10, die.SignedContribution);
});
}
[Fact]
@@ -86,32 +83,28 @@ public sealed class ServiceRolemasterRollTests
Assert.Equal("97 + 96 + 45 | open-ended high", Assert.Single(logPage.Entries).SummaryText);
Assert.Null(Assert.Single(logPage.Entries).EventBadges);
Assert.Equal(roll.Breakdown, detail.Breakdown);
Assert.Collection(
detail.Dice,
die =>
{
Assert.Equal(97, die.Roll);
Assert.Equal(1, die.Sequence);
Assert.Equal(RollDieKinds.RolemasterOpenEndedInitial, die.Kind);
Assert.Equal(97, die.SignedContribution);
Assert.False(die.Added);
},
die =>
{
Assert.Equal(96, die.Roll);
Assert.Equal(2, die.Sequence);
Assert.Equal(RollDieKinds.RolemasterOpenEndedHigh, die.Kind);
Assert.Equal(96, die.SignedContribution);
Assert.True(die.Added);
},
die =>
{
Assert.Equal(45, die.Roll);
Assert.Equal(3, die.Sequence);
Assert.Equal(RollDieKinds.RolemasterOpenEndedHigh, die.Kind);
Assert.Equal(45, die.SignedContribution);
Assert.True(die.Added);
});
Assert.Collection(detail.Dice, die =>
{
Assert.Equal(97, die.Roll);
Assert.Equal(1, die.Sequence);
Assert.Equal(RollDieKinds.RolemasterOpenEndedInitial, die.Kind);
Assert.Equal(97, die.SignedContribution);
Assert.False(die.Added);
}, die =>
{
Assert.Equal(96, die.Roll);
Assert.Equal(2, die.Sequence);
Assert.Equal(RollDieKinds.RolemasterOpenEndedHigh, die.Kind);
Assert.Equal(96, die.SignedContribution);
Assert.True(die.Added);
}, die =>
{
Assert.Equal(45, die.Roll);
Assert.Equal(3, die.Sequence);
Assert.Equal(RollDieKinds.RolemasterOpenEndedHigh, die.Kind);
Assert.Equal(45, die.SignedContribution);
Assert.True(die.Added);
});
}
[Fact]
@@ -134,40 +127,32 @@ public sealed class ServiceRolemasterRollTests
var logEntry = Assert.Single(logPage.Entries);
Assert.Equal("(05) -97 -100 -12 | open-ended low", logEntry.SummaryText);
var lowEventBadges = Assert.IsType<string[]>(logEntry.EventBadges);
Assert.Collection(
lowEventBadges,
badge => Assert.Equal("rf", badge),
badge => Assert.Equal("r100", badge));
Assert.Collection(
roll.Dice,
die =>
{
Assert.Equal(5, die.Roll);
Assert.Equal(1, die.Sequence);
Assert.Equal(RollDieKinds.RolemasterOpenEndedInitial, die.Kind);
Assert.Null(die.SignedContribution);
},
die =>
{
Assert.Equal(97, die.Roll);
Assert.Equal(2, die.Sequence);
Assert.Equal(RollDieKinds.RolemasterOpenEndedLowSubtract, die.Kind);
Assert.Equal(-97, die.SignedContribution);
},
die =>
{
Assert.Equal(100, die.Roll);
Assert.Equal(3, die.Sequence);
Assert.Equal(RollDieKinds.RolemasterOpenEndedLowSubtract, die.Kind);
Assert.Equal(-100, die.SignedContribution);
},
die =>
{
Assert.Equal(12, die.Roll);
Assert.Equal(4, die.Sequence);
Assert.Equal(RollDieKinds.RolemasterOpenEndedLowSubtract, die.Kind);
Assert.Equal(-12, die.SignedContribution);
});
Assert.Collection(lowEventBadges, badge => Assert.Equal("rf", badge), badge => Assert.Equal("r100", badge));
Assert.Collection(roll.Dice, die =>
{
Assert.Equal(5, die.Roll);
Assert.Equal(1, die.Sequence);
Assert.Equal(RollDieKinds.RolemasterOpenEndedInitial, die.Kind);
Assert.Null(die.SignedContribution);
}, die =>
{
Assert.Equal(97, die.Roll);
Assert.Equal(2, die.Sequence);
Assert.Equal(RollDieKinds.RolemasterOpenEndedLowSubtract, die.Kind);
Assert.Equal(-97, die.SignedContribution);
}, die =>
{
Assert.Equal(100, die.Roll);
Assert.Equal(3, die.Sequence);
Assert.Equal(RollDieKinds.RolemasterOpenEndedLowSubtract, die.Kind);
Assert.Equal(-100, die.SignedContribution);
}, die =>
{
Assert.Equal(12, die.Roll);
Assert.Equal(4, die.Sequence);
Assert.Equal(RollDieKinds.RolemasterOpenEndedLowSubtract, die.Kind);
Assert.Equal(-12, die.SignedContribution);
});
}
[Fact]
@@ -189,4 +174,4 @@ public sealed class ServiceRolemasterRollTests
Assert.Equal("r66", badge);
Assert.Equal("66 | rolemaster", logEntry.SummaryText);
}
}
}

View File

@@ -1,67 +1,7 @@
using RpgRoller.Contracts;
using RpgRoller.Domain;
using RpgRoller.Services;
namespace RpgRoller.Tests;
public sealed class ServiceRollHelperTests
{
[Fact]
public void RollBreakdownFormatter_FormatsStandardAndRolemasterOpenEndedBreakdowns()
{
Assert.Equal("4+5+2=11", RollBreakdownFormatter.BuildBreakdown([4, 5], 2, 11));
Assert.Equal("0=0", RollBreakdownFormatter.BuildBreakdown([], 0, 0));
Assert.Equal("97+96+45+85=323", RollBreakdownFormatter.BuildRolemasterOpenEndedBreakdown(97, [96, 45], false, 85, 323));
Assert.Equal("(05) -97 -100 -12 +85 = -124", RollBreakdownFormatter.BuildRolemasterOpenEndedBreakdown(5, [97, 100, 12], true, 85, -124));
Assert.Equal("05", RollBreakdownFormatter.FormatRolemasterTriggerRoll(5));
}
[Fact]
public void CampaignLogSummaryBuilder_ExtractsExpressionsAndBuildsBadgesAndSummaries()
{
var d6Dice = new[]
{
new RollDieResult(6, true, false, true, false, false),
new RollDieResult(1, false, true, true, false, false)
};
var rolemasterDice = new[]
{
new RollDieResult(5, false, false, false, false, false, 1, RollDieKinds.RolemasterOpenEndedInitial, null),
new RollDieResult(97, false, false, false, false, false, 2, RollDieKinds.RolemasterOpenEndedLowSubtract, -97),
new RollDieResult(100, false, false, false, false, false, 3, RollDieKinds.RolemasterOpenEndedLowSubtract, -100)
};
Assert.Equal("1d20+5", CampaignLogSummaryBuilder.ExtractCustomRollExpression("1d20+5 => 20+5=25", " => "));
Assert.Null(CampaignLogSummaryBuilder.ExtractCustomRollExpression("20+5=25", " => "));
Assert.Equal("6, 1", CampaignLogSummaryBuilder.BuildCompactLogSummary(d6Dice));
Assert.Equal("(05) -97 -100 | open-ended low", CampaignLogSummaryBuilder.BuildCompactLogSummary(rolemasterDice));
Assert.Equal("No detail available.", CampaignLogSummaryBuilder.BuildCompactLogSummary([]));
Assert.Equal(["w6", "w1"], Assert.IsType<string[]>(CampaignLogSummaryBuilder.BuildCompactLogEventBadges(RulesetKind.D6, null, d6Dice)));
Assert.Equal(["n20"], Assert.IsType<string[]>(CampaignLogSummaryBuilder.BuildCompactLogEventBadges(RulesetKind.Dnd5e, "1d20+5", [new RollDieResult(20, false, false, false, false, false)])));
Assert.Equal(["rf", "r100"], Assert.IsType<string[]>(CampaignLogSummaryBuilder.BuildCompactLogEventBadges(RulesetKind.Rolemaster, "d100!+85", rolemasterDice)));
}
[Fact]
public void RollEngine_DelegatesToRulesetSpecificEngines()
{
var engine = new RollEngine(
new StandardRollEngine(new FixedDiceRoller([7, 10])),
new D6RollEngine(new FixedDiceRoller([6, 4, 2])),
new RolemasterRollEngine(new FixedDiceRoller([97, 96, 45])));
var d6Roll = engine.Roll(RulesetKind.D6, new DiceExpression(2, 6, 1, "2D+1"), 1, true, null);
Assert.Equal(13, d6Roll.Total);
Assert.Equal("6+4+2+1=13", d6Roll.Breakdown);
var standardRoll = engine.Roll(RulesetKind.Dnd5e, new DiceExpression(2, 10, 3, "2d10+3"), 0, false, null);
Assert.Equal(20, standardRoll.Total);
Assert.Equal("7+10+3=20", standardRoll.Breakdown);
var rolemasterRoll = engine.Roll(RulesetKind.Rolemaster, new DiceExpression(1, 100, 85, "d100!+85", DiceExpressionKind.RolemasterOpenEndedPercentile), 0, false, 5);
Assert.Equal(323, rolemasterRoll.Total);
Assert.Equal("97+96+45+85=323", rolemasterRoll.Breakdown);
}
private sealed class FixedDiceRoller : IDiceRoller
{
public FixedDiceRoller(IEnumerable<int> values)
@@ -77,4 +17,48 @@ public sealed class ServiceRollHelperTests
private readonly Queue<int> m_Values;
}
}
[Fact]
public void RollBreakdownFormatter_FormatsStandardAndRolemasterOpenEndedBreakdowns()
{
Assert.Equal("4+5+2=11", RollBreakdownFormatter.BuildBreakdown([4, 5], 2, 11));
Assert.Equal("0=0", RollBreakdownFormatter.BuildBreakdown([], 0, 0));
Assert.Equal("97+96+45+85=323", RollBreakdownFormatter.BuildRolemasterOpenEndedBreakdown(97, [96, 45], false, 85, 323));
Assert.Equal("(05) -97 -100 -12 +85 = -124", RollBreakdownFormatter.BuildRolemasterOpenEndedBreakdown(5, [97, 100, 12], true, 85, -124));
Assert.Equal("05", RollBreakdownFormatter.FormatRolemasterTriggerRoll(5));
}
[Fact]
public void CampaignLogSummaryBuilder_ExtractsExpressionsAndBuildsBadgesAndSummaries()
{
var d6Dice = new[] { new RollDieResult(6, true, false, true, false, false), new RollDieResult(1, false, true, true, false, false) };
var rolemasterDice = new[] { new RollDieResult(5, false, false, false, false, false, 1, RollDieKinds.RolemasterOpenEndedInitial), new RollDieResult(97, false, false, false, false, false, 2, RollDieKinds.RolemasterOpenEndedLowSubtract, -97), new RollDieResult(100, false, false, false, false, false, 3, RollDieKinds.RolemasterOpenEndedLowSubtract, -100) };
Assert.Equal("1d20+5", CampaignLogSummaryBuilder.ExtractCustomRollExpression("1d20+5 => 20+5=25", " => "));
Assert.Null(CampaignLogSummaryBuilder.ExtractCustomRollExpression("20+5=25", " => "));
Assert.Equal("6, 1", CampaignLogSummaryBuilder.BuildCompactLogSummary(d6Dice));
Assert.Equal("(05) -97 -100 | open-ended low", CampaignLogSummaryBuilder.BuildCompactLogSummary(rolemasterDice));
Assert.Equal("No detail available.", CampaignLogSummaryBuilder.BuildCompactLogSummary([]));
Assert.Equal(["w6", "w1"], Assert.IsType<string[]>(CampaignLogSummaryBuilder.BuildCompactLogEventBadges(RulesetKind.D6, null, d6Dice)));
Assert.Equal(["n20"], Assert.IsType<string[]>(CampaignLogSummaryBuilder.BuildCompactLogEventBadges(RulesetKind.Dnd5e, "1d20+5", [new(20, false, false, false, false, false)])));
Assert.Equal(["rf", "r100"], Assert.IsType<string[]>(CampaignLogSummaryBuilder.BuildCompactLogEventBadges(RulesetKind.Rolemaster, "d100!+85", rolemasterDice)));
}
[Fact]
public void RollEngine_DelegatesToRulesetSpecificEngines()
{
var engine = new RollEngine(new(new FixedDiceRoller([7, 10])), new(new FixedDiceRoller([6, 4, 2])), new(new FixedDiceRoller([97, 96, 45])));
var d6Roll = engine.Roll(RulesetKind.D6, new(2, 6, 1, "2D+1"), 1, true, null);
Assert.Equal(13, d6Roll.Total);
Assert.Equal("6+4+2+1=13", d6Roll.Breakdown);
var standardRoll = engine.Roll(RulesetKind.Dnd5e, new(2, 10, 3, "2d10+3"), 0, false, null);
Assert.Equal(20, standardRoll.Total);
Assert.Equal("7+10+3=20", standardRoll.Breakdown);
var rolemasterRoll = engine.Roll(RulesetKind.Rolemaster, new(1, 100, 85, "d100!+85", DiceExpressionKind.RolemasterOpenEndedPercentile), 0, false, 5);
Assert.Equal(323, rolemasterRoll.Total);
Assert.Equal("97+96+45+85=323", rolemasterRoll.Breakdown);
}
}

View File

@@ -1,7 +1,3 @@
using RpgRoller.Contracts;
using RpgRoller.Domain;
using RpgRoller.Services;
namespace RpgRoller.Tests;
public sealed class ServiceSharedHelperTests
@@ -13,7 +9,7 @@ public sealed class ServiceSharedHelperTests
var characterId = Guid.NewGuid();
var store = new GameStateStore();
store.CampaignsById[campaignId] = new Campaign
store.CampaignsById[campaignId] = new()
{
Id = campaignId,
GmUserId = Guid.NewGuid(),
@@ -21,7 +17,7 @@ public sealed class ServiceSharedHelperTests
Ruleset = RulesetKind.D6,
Version = 1
};
store.CharactersById[characterId] = new Character
store.CharactersById[characterId] = new()
{
Id = characterId,
OwnerUserId = Guid.NewGuid(),
@@ -65,7 +61,7 @@ public sealed class ServiceSharedHelperTests
var campaignId = Guid.NewGuid();
var store = new GameStateStore();
store.UsersById[adminId] = new UserAccount
store.UsersById[adminId] = new()
{
Id = adminId,
Username = "admin",
@@ -74,7 +70,7 @@ public sealed class ServiceSharedHelperTests
DisplayName = "Admin",
Roles = UserRoles.Admin
};
store.UsersById[gmId] = new UserAccount
store.UsersById[gmId] = new()
{
Id = gmId,
Username = "gm",
@@ -83,7 +79,7 @@ public sealed class ServiceSharedHelperTests
DisplayName = "GM",
Roles = string.Empty
};
store.UsersById[playerId] = new UserAccount
store.UsersById[playerId] = new()
{
Id = playerId,
Username = "player",
@@ -92,7 +88,7 @@ public sealed class ServiceSharedHelperTests
DisplayName = "Player",
Roles = string.Empty
};
store.UsersById[outsiderId] = new UserAccount
store.UsersById[outsiderId] = new()
{
Id = outsiderId,
Username = "outsider",
@@ -112,7 +108,7 @@ public sealed class ServiceSharedHelperTests
};
store.CampaignsById[campaignId] = campaign;
var playerCharacterId = Guid.NewGuid();
store.CharactersById[playerCharacterId] = new Character
store.CharactersById[playerCharacterId] = new()
{
Id = playerCharacterId,
OwnerUserId = playerId,
@@ -171,7 +167,7 @@ public sealed class ServiceSharedHelperTests
var campaignId = Guid.NewGuid();
var store = new GameStateStore();
store.UsersById[userId] = new UserAccount
store.UsersById[userId] = new()
{
Id = userId,
Username = "user",
@@ -180,7 +176,7 @@ public sealed class ServiceSharedHelperTests
DisplayName = "User",
Roles = string.Empty
};
store.UsersById[otherUserId] = new UserAccount
store.UsersById[otherUserId] = new()
{
Id = otherUserId,
Username = "other",
@@ -189,13 +185,13 @@ public sealed class ServiceSharedHelperTests
DisplayName = "Other",
Roles = string.Empty
};
store.SessionsByToken["valid"] = new UserSession
store.SessionsByToken["valid"] = new()
{
Token = "valid",
UserId = userId,
CreatedAtUtc = DateTimeOffset.UtcNow
};
store.CampaignsById[campaignId] = new Campaign
store.CampaignsById[campaignId] = new()
{
Id = campaignId,
GmUserId = otherUserId,
@@ -267,7 +263,7 @@ public sealed class ServiceSharedHelperTests
var rollId = Guid.NewGuid();
var store = new GameStateStore();
store.UsersById[gmId] = new UserAccount
store.UsersById[gmId] = new()
{
Id = gmId,
Username = "gm",
@@ -276,7 +272,7 @@ public sealed class ServiceSharedHelperTests
DisplayName = "GM",
Roles = UserRoles.Admin
};
store.UsersById[ownerId] = new UserAccount
store.UsersById[ownerId] = new()
{
Id = ownerId,
Username = "owner",
@@ -285,7 +281,7 @@ public sealed class ServiceSharedHelperTests
DisplayName = "Owner",
Roles = string.Empty
};
store.UsersById[blankOwnerId] = new UserAccount
store.UsersById[blankOwnerId] = new()
{
Id = blankOwnerId,
Username = "blank",
@@ -294,7 +290,7 @@ public sealed class ServiceSharedHelperTests
DisplayName = "",
Roles = string.Empty
};
store.CampaignsById[campaignId] = new Campaign
store.CampaignsById[campaignId] = new()
{
Id = campaignId,
GmUserId = gmId,
@@ -302,14 +298,14 @@ public sealed class ServiceSharedHelperTests
Ruleset = RulesetKind.Rolemaster,
Version = 1
};
store.CharactersById[characterId] = new Character
store.CharactersById[characterId] = new()
{
Id = characterId,
OwnerUserId = ownerId,
CampaignId = campaignId,
Name = "Scout"
};
store.SkillGroupsById[skillGroupId] = new SkillGroup
store.SkillGroupsById[skillGroupId] = new()
{
Id = skillGroupId,
CharacterId = characterId,
@@ -319,7 +315,7 @@ public sealed class ServiceSharedHelperTests
AllowFumble = false,
FumbleRange = 5
};
store.SkillsById[skillId] = new Skill
store.SkillsById[skillId] = new()
{
Id = skillId,
CharacterId = characterId,
@@ -384,4 +380,4 @@ public sealed class ServiceSharedHelperTests
Assert.Equal("fallback", GameDtoMapper.ResolveOwnerDisplayName(store, blankOwnerId, "fallback"));
Assert.Equal("fallback", GameDtoMapper.ResolveOwnerDisplayName(store, Guid.NewGuid(), "fallback"));
}
}
}

View File

@@ -36,7 +36,7 @@ public sealed class ServiceSkillGroupAndOwnershipTests
var otherGroup = ServiceTestSupport.GetValue(service.CreateSkillGroup(otherSession, otherCharacter.Id, "Other Group", "2D+1", 1, true));
Assert.False(service.UpdateSkill(ownerSession, skill.Id, "Strike", "2D+1", 1, true, otherGroup.Id).Succeeded);
var ungroupedSkill = ServiceTestSupport.GetValue(service.UpdateSkill(ownerSession, skill.Id, "Strike", "2D+1", 1, true, null));
var ungroupedSkill = ServiceTestSupport.GetValue(service.UpdateSkill(ownerSession, skill.Id, "Strike", "2D+1", 1, true));
Assert.Null(ungroupedSkill.SkillGroupId);
var regroupedSkill = ServiceTestSupport.GetValue(service.UpdateSkill(ownerSession, skill.Id, "Strike", "2D+1", 1, true, renamedGroup.Id));
@@ -133,7 +133,7 @@ public sealed class ServiceSkillGroupAndOwnershipTests
var adminTwo = service.GetUserBySession(adminTwoSession);
Assert.NotNull(adminTwo);
_ = ServiceTestSupport.GetValue(service.UpdateUserRoles(gmSession, adminTwo!.Id, [ "admin" ]));
_ = ServiceTestSupport.GetValue(service.UpdateUserRoles(gmSession, adminTwo!.Id, ["admin"]));
var adminUnlink = ServiceTestSupport.GetValue(service.UpdateCharacter(adminTwoSession, character.Id, "Admin Unlink", null));
Assert.Null(adminUnlink.CampaignId);
@@ -225,4 +225,4 @@ public sealed class ServiceSkillGroupAndOwnershipTests
Assert.False(openEndedSkill.AllowFumble);
Assert.Equal(5, openEndedSkill.FumbleRange);
}
}
}

View File

@@ -264,4 +264,4 @@ public sealed class ServiceSkillRollTests
var log = ServiceTestSupport.GetValue(service.GetCampaignLog(ownerSession, campaign.Id));
Assert.Equal("Custom roll", Assert.Single(log).SkillName);
}
}
}

View File

@@ -32,11 +32,48 @@ public sealed class ServiceStateInfrastructureTests
Roles = "admin",
ActiveCharacterId = Guid.NewGuid()
};
var session = new UserSession { Token = "token", UserId = user.Id, CreatedAtUtc = DateTimeOffset.UtcNow };
var campaign = new Campaign { Id = Guid.NewGuid(), GmUserId = user.Id, Name = "Main", Ruleset = RulesetKind.D6, Version = 3 };
var character = new Character { Id = Guid.NewGuid(), OwnerUserId = user.Id, CampaignId = campaign.Id, Name = "Hero" };
var skillGroup = new SkillGroup { Id = Guid.NewGuid(), CharacterId = character.Id, Name = "Group", DiceRollDefinition = "2D+1", WildDice = 1, AllowFumble = true, FumbleRange = null };
var skill = new Skill { Id = Guid.NewGuid(), CharacterId = character.Id, SkillGroupId = skillGroup.Id, Name = "Skill", DiceRollDefinition = "2D+2", WildDice = 1, AllowFumble = true, FumbleRange = null };
var session = new UserSession
{
Token = "token",
UserId = user.Id,
CreatedAtUtc = DateTimeOffset.UtcNow
};
var campaign = new Campaign
{
Id = Guid.NewGuid(),
GmUserId = user.Id,
Name = "Main",
Ruleset = RulesetKind.D6,
Version = 3
};
var character = new Character
{
Id = Guid.NewGuid(),
OwnerUserId = user.Id,
CampaignId = campaign.Id,
Name = "Hero"
};
var skillGroup = new SkillGroup
{
Id = Guid.NewGuid(),
CharacterId = character.Id,
Name = "Group",
DiceRollDefinition = "2D+1",
WildDice = 1,
AllowFumble = true,
FumbleRange = null
};
var skill = new Skill
{
Id = Guid.NewGuid(),
CharacterId = character.Id,
SkillGroupId = skillGroup.Id,
Name = "Skill",
DiceRollDefinition = "2D+2",
WildDice = 1,
AllowFumble = true,
FumbleRange = null
};
var logEntry = new RollLogEntry
{
Id = Guid.NewGuid(),
@@ -59,4 +96,4 @@ public sealed class ServiceStateInfrastructureTests
Assert.NotSame(skill, GameStateCloneFactory.CloneSkill(skill));
Assert.NotSame(logEntry, GameStateCloneFactory.CloneRollLogEntry(logEntry));
}
}
}

View File

@@ -1,12 +1,182 @@
using Microsoft.AspNetCore.Http;
using RpgRoller.Components;
using RpgRoller.Contracts;
using RpgRoller.Services;
namespace RpgRoller.Tests;
public sealed class WorkspaceQueryServiceTests
{
private sealed class StubGameService : IGameService
{
public IReadOnlyList<RulesetDefinition> GetRulesets()
{
throw new NotSupportedException();
}
public ServiceResult<UserSummary> Register(string username, string password, string displayName)
{
throw new NotSupportedException();
}
public ServiceResult<(UserSummary User, string SessionToken)> Login(string username, string password)
{
throw new NotSupportedException();
}
public void Logout(string sessionToken)
{
throw new NotSupportedException();
}
public UserSummary? GetUserBySession(string sessionToken)
{
throw new NotSupportedException();
}
public ServiceResult<MeResponse> GetMe(string sessionToken)
{
return GetMeHandler(sessionToken);
}
public ServiceResult<CampaignSummary> CreateCampaign(string sessionToken, string name, string rulesetId)
{
throw new NotSupportedException();
}
public ServiceResult<IReadOnlyList<CampaignSummary>> GetCampaigns(string sessionToken)
{
return GetCampaignsHandler(sessionToken);
}
public ServiceResult<IReadOnlyList<CampaignOption>> GetCharacterCampaignOptions(string sessionToken)
{
throw new NotSupportedException();
}
public ServiceResult<CampaignRoster> GetCampaign(string sessionToken, Guid campaignId)
{
throw new NotSupportedException();
}
public ServiceResult<bool> DeleteCampaign(string sessionToken, Guid campaignId)
{
throw new NotSupportedException();
}
public ServiceResult<IReadOnlyList<string>> GetUsernames(string sessionToken)
{
throw new NotSupportedException();
}
public ServiceResult<IReadOnlyList<AdminUserSummary>> GetUsers(string sessionToken)
{
throw new NotSupportedException();
}
public ServiceResult<AdminUserSummary> UpdateUserRoles(string sessionToken, Guid userId, IReadOnlyList<string> roles)
{
throw new NotSupportedException();
}
public ServiceResult<bool> DeleteUser(string sessionToken, Guid userId)
{
throw new NotSupportedException();
}
public ServiceResult<CharacterSummary> CreateCharacter(string sessionToken, string name, Guid campaignId)
{
throw new NotSupportedException();
}
public ServiceResult<CharacterSummary> UpdateCharacter(string sessionToken, Guid characterId, string name, Guid? campaignId, string? ownerUsername = null)
{
throw new NotSupportedException();
}
public ServiceResult<bool> DeleteCharacter(string sessionToken, Guid characterId)
{
throw new NotSupportedException();
}
public ServiceResult<bool> ActivateCharacter(string sessionToken, Guid characterId)
{
throw new NotSupportedException();
}
public ServiceResult<IReadOnlyList<CharacterSummary>> GetOwnCharacters(string sessionToken)
{
throw new NotSupportedException();
}
public ServiceResult<SkillGroupSummary> CreateSkillGroup(string sessionToken, Guid characterId, string name, string diceRollDefinition, int wildDice, bool allowFumble, int? fumbleRange = null)
{
throw new NotSupportedException();
}
public ServiceResult<SkillGroupSummary> UpdateSkillGroup(string sessionToken, Guid skillGroupId, string name, string diceRollDefinition, int wildDice, bool allowFumble, int? fumbleRange = null)
{
throw new NotSupportedException();
}
public ServiceResult<bool> DeleteSkillGroup(string sessionToken, Guid skillGroupId)
{
throw new NotSupportedException();
}
public ServiceResult<SkillSummary> CreateSkill(string sessionToken, Guid characterId, string name, string diceRollDefinition, int wildDice, bool allowFumble, Guid? skillGroupId = null, int? fumbleRange = null)
{
throw new NotSupportedException();
}
public ServiceResult<SkillSummary> UpdateSkill(string sessionToken, Guid skillId, string name, string diceRollDefinition, int wildDice, bool allowFumble, Guid? skillGroupId = null, int? fumbleRange = null)
{
throw new NotSupportedException();
}
public ServiceResult<bool> DeleteSkill(string sessionToken, Guid skillId)
{
throw new NotSupportedException();
}
public ServiceResult<CharacterSheet> GetCharacterSheet(string sessionToken, Guid characterId)
{
throw new NotSupportedException();
}
public ServiceResult<RollResult> RollSkill(string sessionToken, Guid skillId, string visibility)
{
throw new NotSupportedException();
}
public ServiceResult<RollResult> RollCustom(string sessionToken, Guid characterId, string expression, string visibility)
{
throw new NotSupportedException();
}
public ServiceResult<IReadOnlyList<CampaignLogEntry>> GetCampaignLog(string sessionToken, Guid campaignId)
{
throw new NotSupportedException();
}
public ServiceResult<CampaignLogPage> GetCampaignLogPage(string sessionToken, Guid campaignId, Guid? afterRollId = null, int? limit = null)
{
throw new NotSupportedException();
}
public ServiceResult<CampaignRollDetail> GetRollDetail(string sessionToken, Guid rollId)
{
throw new NotSupportedException();
}
public ServiceResult<CampaignStateSnapshot> GetCampaignStateSnapshot(string sessionToken, Guid campaignId)
{
throw new NotSupportedException();
}
public Func<string, ServiceResult<MeResponse>> GetMeHandler { get; init; } = _ => ServiceResult<MeResponse>.Failure("unexpected_call", "Unexpected GetMe call.");
public Func<string, ServiceResult<IReadOnlyList<CampaignSummary>>> GetCampaignsHandler { get; init; } = _ => ServiceResult<IReadOnlyList<CampaignSummary>>.Failure("unexpected_call", "Unexpected GetCampaigns call.");
}
[Fact]
public void SessionTokenAccessor_ReadsSessionCookieFromHttpContext()
{
@@ -27,7 +197,7 @@ public sealed class WorkspaceQueryServiceTests
GetCampaignsHandler = sessionToken =>
{
Assert.Equal("server-session", sessionToken);
return ServiceResult<IReadOnlyList<CampaignSummary>>.Success([new CampaignSummary(Guid.NewGuid(), "Alpha", "d6", new CampaignGmSummary(Guid.NewGuid(), "GM"), 1)]);
return ServiceResult<IReadOnlyList<CampaignSummary>>.Success([new(Guid.NewGuid(), "Alpha", "d6", new(Guid.NewGuid(), "GM"), 1)]);
}
};
@@ -40,10 +210,7 @@ public sealed class WorkspaceQueryServiceTests
[Fact]
public async Task GetMeAsync_MapsUnauthorizedServiceResultToApiRequestException()
{
var service = new StubGameService
{
GetMeHandler = _ => ServiceResult<MeResponse>.Failure("unauthorized", "You must be logged in.")
};
var service = new StubGameService { GetMeHandler = _ => ServiceResult<MeResponse>.Failure("unauthorized", "You must be logged in.") };
var queryService = new WorkspaceQueryService(service, CreateSessionTokenAccessor("expired-session"));
var exception = await Assert.ThrowsAsync<ApiRequestException>(queryService.GetMeAsync);
@@ -57,49 +224,6 @@ public sealed class WorkspaceQueryServiceTests
{
var httpContext = new DefaultHttpContext();
httpContext.Request.Headers.Cookie = $"rpgroller_session={sessionToken}";
return new WorkspaceSessionTokenAccessor(new HttpContextAccessor { HttpContext = httpContext });
return new(new HttpContextAccessor { HttpContext = httpContext });
}
private sealed class StubGameService : IGameService
{
public Func<string, ServiceResult<MeResponse>> GetMeHandler { get; init; } =
_ => ServiceResult<MeResponse>.Failure("unexpected_call", "Unexpected GetMe call.");
public Func<string, ServiceResult<IReadOnlyList<CampaignSummary>>> GetCampaignsHandler { get; init; } =
_ => ServiceResult<IReadOnlyList<CampaignSummary>>.Failure("unexpected_call", "Unexpected GetCampaigns call.");
public IReadOnlyList<RulesetDefinition> GetRulesets() => throw new NotSupportedException();
public ServiceResult<UserSummary> Register(string username, string password, string displayName) => throw new NotSupportedException();
public ServiceResult<(UserSummary User, string SessionToken)> Login(string username, string password) => throw new NotSupportedException();
public void Logout(string sessionToken) => throw new NotSupportedException();
public UserSummary? GetUserBySession(string sessionToken) => throw new NotSupportedException();
public ServiceResult<MeResponse> GetMe(string sessionToken) => GetMeHandler(sessionToken);
public ServiceResult<CampaignSummary> CreateCampaign(string sessionToken, string name, string rulesetId) => throw new NotSupportedException();
public ServiceResult<IReadOnlyList<CampaignSummary>> GetCampaigns(string sessionToken) => GetCampaignsHandler(sessionToken);
public ServiceResult<IReadOnlyList<CampaignOption>> GetCharacterCampaignOptions(string sessionToken) => throw new NotSupportedException();
public ServiceResult<CampaignRoster> GetCampaign(string sessionToken, Guid campaignId) => throw new NotSupportedException();
public ServiceResult<bool> DeleteCampaign(string sessionToken, Guid campaignId) => throw new NotSupportedException();
public ServiceResult<IReadOnlyList<string>> GetUsernames(string sessionToken) => throw new NotSupportedException();
public ServiceResult<IReadOnlyList<AdminUserSummary>> GetUsers(string sessionToken) => throw new NotSupportedException();
public ServiceResult<AdminUserSummary> UpdateUserRoles(string sessionToken, Guid userId, IReadOnlyList<string> roles) => throw new NotSupportedException();
public ServiceResult<bool> DeleteUser(string sessionToken, Guid userId) => throw new NotSupportedException();
public ServiceResult<CharacterSummary> CreateCharacter(string sessionToken, string name, Guid campaignId) => throw new NotSupportedException();
public ServiceResult<CharacterSummary> UpdateCharacter(string sessionToken, Guid characterId, string name, Guid? campaignId, string? ownerUsername = null) => throw new NotSupportedException();
public ServiceResult<bool> DeleteCharacter(string sessionToken, Guid characterId) => throw new NotSupportedException();
public ServiceResult<bool> ActivateCharacter(string sessionToken, Guid characterId) => throw new NotSupportedException();
public ServiceResult<IReadOnlyList<CharacterSummary>> GetOwnCharacters(string sessionToken) => throw new NotSupportedException();
public ServiceResult<SkillGroupSummary> CreateSkillGroup(string sessionToken, Guid characterId, string name, string diceRollDefinition, int wildDice, bool allowFumble, int? fumbleRange = null) => throw new NotSupportedException();
public ServiceResult<SkillGroupSummary> UpdateSkillGroup(string sessionToken, Guid skillGroupId, string name, string diceRollDefinition, int wildDice, bool allowFumble, int? fumbleRange = null) => throw new NotSupportedException();
public ServiceResult<bool> DeleteSkillGroup(string sessionToken, Guid skillGroupId) => throw new NotSupportedException();
public ServiceResult<SkillSummary> CreateSkill(string sessionToken, Guid characterId, string name, string diceRollDefinition, int wildDice, bool allowFumble, Guid? skillGroupId = null, int? fumbleRange = null) => throw new NotSupportedException();
public ServiceResult<SkillSummary> UpdateSkill(string sessionToken, Guid skillId, string name, string diceRollDefinition, int wildDice, bool allowFumble, Guid? skillGroupId = null, int? fumbleRange = null) => throw new NotSupportedException();
public ServiceResult<bool> DeleteSkill(string sessionToken, Guid skillId) => throw new NotSupportedException();
public ServiceResult<CharacterSheet> GetCharacterSheet(string sessionToken, Guid characterId) => throw new NotSupportedException();
public ServiceResult<RollResult> RollSkill(string sessionToken, Guid skillId, string visibility) => throw new NotSupportedException();
public ServiceResult<RollResult> RollCustom(string sessionToken, Guid characterId, string expression, string visibility) => throw new NotSupportedException();
public ServiceResult<IReadOnlyList<CampaignLogEntry>> GetCampaignLog(string sessionToken, Guid campaignId) => throw new NotSupportedException();
public ServiceResult<CampaignLogPage> GetCampaignLogPage(string sessionToken, Guid campaignId, Guid? afterRollId = null, int? limit = null) => throw new NotSupportedException();
public ServiceResult<CampaignRollDetail> GetRollDetail(string sessionToken, Guid rollId) => throw new NotSupportedException();
public ServiceResult<CampaignStateSnapshot> GetCampaignStateSnapshot(string sessionToken, Guid campaignId) => throw new NotSupportedException();
}
}
}

View File

@@ -1,6 +1,4 @@
using RpgRoller.Components.Pages;
using RpgRoller.Contracts;
using RpgRoller.Domain;
namespace RpgRoller.Tests;
@@ -14,15 +12,10 @@ public sealed class WorkspaceStateTests
var otherOwnerId = Guid.NewGuid();
var state = new WorkspaceState
{
User = new UserSummary(userId, "user", "User", []),
SelectedCampaign = new CampaignRoster(
Guid.NewGuid(),
"Alpha",
"d6",
new CampaignGmSummary(gmId, "GM"),
[
new CharacterSummary(Guid.NewGuid(), "Scout", otherOwnerId, Guid.NewGuid(), "Other Owner")
])
User = new(userId, "user", "User", []),
SelectedCampaign = new(Guid.NewGuid(), "Alpha", "d6", new(gmId, "GM"), [
new(Guid.NewGuid(), "Scout", otherOwnerId, Guid.NewGuid(), "Other Owner")
])
};
Assert.Equal("You", state.OwnerLabel(userId));
@@ -35,17 +28,14 @@ public sealed class WorkspaceStateTests
public void SkillDefinitionLabel_FormatsD6RolemasterAndDefaultRulesets()
{
var skill = new CharacterSheetSkill(Guid.NewGuid(), null, "Awareness", "d100!+15", 1, true, 5);
var state = new WorkspaceState
{
SelectedCampaign = new CampaignRoster(Guid.NewGuid(), "Alpha", "d6", new CampaignGmSummary(Guid.NewGuid(), "GM"), [])
};
var state = new WorkspaceState { SelectedCampaign = new(Guid.NewGuid(), "Alpha", "d6", new(Guid.NewGuid(), "GM"), []) };
Assert.Equal("d100!+15, wild 1, fumble on", state.SkillDefinitionLabel(skill));
state.SelectedCampaign = new CampaignRoster(Guid.NewGuid(), "Alpha", "rolemaster", new CampaignGmSummary(Guid.NewGuid(), "GM"), []);
state.SelectedCampaign = new(Guid.NewGuid(), "Alpha", "rolemaster", new(Guid.NewGuid(), "GM"), []);
Assert.Equal("Open-ended percentile: d100!+15, fumble <= 5", state.SkillDefinitionLabel(skill));
state.SelectedCampaign = new CampaignRoster(Guid.NewGuid(), "Alpha", "dnd5e", new CampaignGmSummary(Guid.NewGuid(), "GM"), []);
state.SelectedCampaign = new(Guid.NewGuid(), "Alpha", "dnd5e", new(Guid.NewGuid(), "GM"), []);
Assert.Equal("d100!+15", state.SkillDefinitionLabel(skill));
}
@@ -58,17 +48,12 @@ public sealed class WorkspaceStateTests
var otherCharacter = new CharacterSummary(Guid.NewGuid(), "Other", Guid.NewGuid(), Guid.NewGuid(), "Other");
var state = new WorkspaceState
{
User = new UserSummary(userId, "user", "User", []),
SelectedCampaign = new CampaignRoster(
Guid.NewGuid(),
"Alpha",
"d6",
new CampaignGmSummary(Guid.NewGuid(), "GM"),
[ownedCharacter, secondOwnedCharacter, otherCharacter]),
User = new(userId, "user", "User", []),
SelectedCampaign = new(Guid.NewGuid(), "Alpha", "d6", new(Guid.NewGuid(), "GM"), [ownedCharacter, secondOwnedCharacter, otherCharacter]),
SelectedCharacterId = secondOwnedCharacter.Id,
ActiveCharacterId = ownedCharacter.Id,
SelectedCharacterSkills = [new CharacterSheetSkill(Guid.NewGuid(), null, "Stealth", "2D+1", 1, true, null)],
SelectedCharacterSkillGroups = [new CharacterSheetSkillGroup(Guid.NewGuid(), "Combat", "2D+1", 1, true, null)]
SelectedCharacterSkills = [new(Guid.NewGuid(), null, "Stealth", "2D+1", 1, true, null)],
SelectedCharacterSkillGroups = [new(Guid.NewGuid(), "Combat", "2D+1", 1, true, null)]
};
Assert.Equal(2, state.PlaySelectedCampaign!.Characters.Length);
@@ -89,8 +74,8 @@ public sealed class WorkspaceStateTests
var adminId = Guid.NewGuid();
var state = new WorkspaceState
{
User = new UserSummary(adminId, "admin", "Admin", [UserRoles.Admin]),
SelectedCampaign = new CampaignRoster(Guid.NewGuid(), "Alpha", "d6", new CampaignGmSummary(adminId, "Admin"), []),
User = new(adminId, "admin", "Admin", [UserRoles.Admin]),
SelectedCampaign = new(Guid.NewGuid(), "Alpha", "d6", new(adminId, "Admin"), []),
CurrentScreen = "admin",
ConnectionState = "reconnecting"
};
@@ -113,4 +98,4 @@ public sealed class WorkspaceStateTests
Assert.Equal("ok", state.ConnectionStateCssClass);
Assert.Equal("rr-app app-play", state.AppCssClass);
}
}
}

View File

@@ -97,4 +97,4 @@ public abstract class ApiTestBase : IClassFixture<WebApplicationFactory<Program>
}
private readonly WebApplicationFactory<Program> m_BaseFactory;
}
}