Fix campaign owner labels to always use display names
This commit is contained in:
@@ -53,6 +53,7 @@ Gameplay capabilities now include:
|
||||
- Character owner selection in edit modal backed by existing-username dropdown data
|
||||
- Role-aware authorization with admin role support (including admin user/role management)
|
||||
- Campaign deletion by campaign owner or admin (unlinks characters from the campaign and clears campaign log entries)
|
||||
- Campaign management owner labels use account display names (no GUID fallback rendering)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ public sealed class CampaignApiTests : ApiTestBase
|
||||
var campaign = await PostAsync<CreateCampaignRequest, CampaignDetails>(gmClient, "/api/campaigns", new("Alpha Campaign", "dnd5e"));
|
||||
|
||||
var gmCharacter = await PostAsync<CreateCharacterRequest, CharacterSummary>(gmClient, "/api/characters", new("Arin", campaign.Id));
|
||||
Assert.Equal("Game Master", gmCharacter.OwnerDisplayName);
|
||||
|
||||
var activateResponse = await gmClient.PostAsync($"/api/characters/{gmCharacter.Id}/activate", null);
|
||||
Assert.Equal(HttpStatusCode.OK, activateResponse.StatusCode);
|
||||
@@ -39,10 +40,12 @@ public sealed class CampaignApiTests : ApiTestBase
|
||||
var details = await GetAsync<CampaignDetails>(gmClient, $"/api/campaigns/{campaign.Id}");
|
||||
Assert.Equal(campaign.Id, details.Id);
|
||||
Assert.Single(details.Characters);
|
||||
Assert.Equal("Game Master", details.Characters[0].OwnerDisplayName);
|
||||
|
||||
var currentCampaignCharacters = await GetAsync<IReadOnlyList<CharacterSummary>>(gmClient, "/api/characters");
|
||||
Assert.Single(currentCampaignCharacters);
|
||||
Assert.Equal(gmCharacter.Id, currentCampaignCharacters[0].Id);
|
||||
Assert.Equal("Game Master", currentCampaignCharacters[0].OwnerDisplayName);
|
||||
|
||||
var otherCampaign = await PostAsync<CreateCampaignRequest, CampaignDetails>(gmClient, "/api/campaigns", new("Beta Campaign", "d6"));
|
||||
|
||||
@@ -96,6 +99,11 @@ public sealed class CampaignApiTests : ApiTestBase
|
||||
|
||||
var transferResult = await PutAsync<UpdateCharacterRequest, CharacterSummary>(gmClient, $"/api/characters/{character.Id}", new("Grouped Hero", campaign.Id, "receiver2"));
|
||||
Assert.Equal("Grouped Hero", transferResult.Name);
|
||||
Assert.Equal("Receiver", transferResult.OwnerDisplayName);
|
||||
|
||||
var gmCampaignView = await GetAsync<CampaignDetails>(gmClient, $"/api/campaigns/{campaign.Id}");
|
||||
var gmViewedCharacter = Assert.Single(gmCampaignView.Characters, c => c.Id == character.Id);
|
||||
Assert.Equal("Receiver", gmViewedCharacter.OwnerDisplayName);
|
||||
|
||||
var ownerActivate = await ownerClient.PostAsync($"/api/characters/{character.Id}/activate", null);
|
||||
Assert.Equal(HttpStatusCode.BadRequest, ownerActivate.StatusCode);
|
||||
|
||||
@@ -590,10 +590,18 @@ public partial class Workspace : IAsyncDisposable
|
||||
if (User is not null && ownerUserId == User.Id)
|
||||
return "You";
|
||||
|
||||
if (SelectedCampaign is not null && ownerUserId == SelectedCampaign.Gm.Id)
|
||||
if (SelectedCampaign is null)
|
||||
return "Unknown owner";
|
||||
|
||||
if (ownerUserId == SelectedCampaign.Gm.Id)
|
||||
return $"{SelectedCampaign.Gm.DisplayName} (GM)";
|
||||
|
||||
return ownerUserId.ToString("N")[..8];
|
||||
var ownerDisplayName = SelectedCampaign.Characters
|
||||
.Where(character => character.OwnerUserId == ownerUserId)
|
||||
.Select(character => character.OwnerDisplayName)
|
||||
.FirstOrDefault(displayName => !string.IsNullOrWhiteSpace(displayName));
|
||||
|
||||
return string.IsNullOrWhiteSpace(ownerDisplayName) ? "Unknown owner" : ownerDisplayName;
|
||||
}
|
||||
|
||||
private string CharacterLabel(Guid characterId)
|
||||
|
||||
@@ -26,7 +26,7 @@ public sealed record CreateCharacterRequest(string Name, Guid CampaignId);
|
||||
|
||||
public sealed record UpdateCharacterRequest(string Name, Guid CampaignId, string? OwnerUsername = null);
|
||||
|
||||
public sealed record CharacterSummary(Guid Id, string Name, Guid OwnerUserId, Guid? CampaignId);
|
||||
public sealed record CharacterSummary(Guid Id, string Name, Guid OwnerUserId, Guid? CampaignId, string OwnerDisplayName);
|
||||
|
||||
public sealed record CreateSkillRequest(string Name, string DiceRollDefinition, int WildDice, bool AllowFumble, Guid? SkillGroupId = null);
|
||||
|
||||
|
||||
@@ -948,9 +948,10 @@ public sealed class GameService : IGameService
|
||||
}
|
||||
}
|
||||
|
||||
private static CharacterSummary ToCharacterSummary(Character character)
|
||||
private CharacterSummary ToCharacterSummary(Character character)
|
||||
{
|
||||
return new(character.Id, character.Name, character.OwnerUserId, character.CampaignId);
|
||||
var ownerDisplayName = ResolveOwnerDisplayName(character.OwnerUserId);
|
||||
return new(character.Id, character.Name, character.OwnerUserId, character.CampaignId, ownerDisplayName);
|
||||
}
|
||||
|
||||
private static SkillGroupSummary ToSkillGroupSummary(SkillGroup skillGroup)
|
||||
@@ -980,6 +981,13 @@ public sealed class GameService : IGameService
|
||||
return JsonSerializer.Serialize(dice, DiceJsonOptions);
|
||||
}
|
||||
|
||||
private string ResolveOwnerDisplayName(Guid ownerUserId)
|
||||
{
|
||||
return m_UsersById.TryGetValue(ownerUserId, out var owner) && !string.IsNullOrWhiteSpace(owner.DisplayName)
|
||||
? owner.DisplayName
|
||||
: "Unknown owner";
|
||||
}
|
||||
|
||||
private static IReadOnlyList<RollDieResult> DeserializeDice(string serializedDice)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(serializedDice))
|
||||
|
||||
Reference in New Issue
Block a user