mirror of
https://github.com/DorkSquadRR/DorkNet.git
synced 2026-10-25 23:18:44 -07:00
feat: Enhance room image handling by introducing default image and updating display logic; add unit tests for image resolution
This commit is contained in:
@@ -88,3 +88,4 @@ Recovered(*)/
|
|||||||
local-releases/**
|
local-releases/**
|
||||||
DorkNet.Models/bin-verify/**
|
DorkNet.Models/bin-verify/**
|
||||||
DorkNet.Models/bin-verify2/**
|
DorkNet.Models/bin-verify2/**
|
||||||
|
identityserver-signing.pfx
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
using System.Text.Json;
|
||||||
|
using DorkNet.Server.Data.Entities;
|
||||||
|
using DorkNet.Server.Services;
|
||||||
|
|
||||||
|
namespace DorkNet.Server.Tests;
|
||||||
|
|
||||||
|
public sealed class RoomServiceTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void ToWireRoom_never_emits_empty_image_name()
|
||||||
|
{
|
||||||
|
var room = new RoomEntity
|
||||||
|
{
|
||||||
|
Id = 1001,
|
||||||
|
Name = "CustomRoomWithoutImage",
|
||||||
|
Description = "Custom room",
|
||||||
|
ImageName = "",
|
||||||
|
Accessibility = 1,
|
||||||
|
State = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
var json = JsonSerializer.Serialize(RoomService.ToWireRoom(room));
|
||||||
|
using var document = JsonDocument.Parse(json);
|
||||||
|
|
||||||
|
Assert.Equal(RoomService.DefaultRoomImageName, document.RootElement.GetProperty("ImageName").GetString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ResolveDisplayImageName_preserves_existing_image_name()
|
||||||
|
{
|
||||||
|
var room = new RoomEntity
|
||||||
|
{
|
||||||
|
Name = "Paintball",
|
||||||
|
ImageName = "custom-thumbnail.png",
|
||||||
|
};
|
||||||
|
|
||||||
|
Assert.Equal("custom-thumbnail.png", RoomService.ResolveDisplayImageName(room));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -65,7 +65,6 @@ public class CommunityBoardController(
|
|||||||
? new()
|
? new()
|
||||||
: await db.Rooms
|
: await db.Rooms
|
||||||
.Where(r => ids.Contains(r.Id))
|
.Where(r => ids.Contains(r.Id))
|
||||||
.Select(r => new { r.Id, r.Name, r.ImageName })
|
|
||||||
.ToDictionaryAsync(r => r.Id);
|
.ToDictionaryAsync(r => r.Id);
|
||||||
// 2020.12 FeaturedRoomGroup deserializer (NMPFCIJPODA.PPGFHEDFBEA)
|
// 2020.12 FeaturedRoomGroup deserializer (NMPFCIJPODA.PPGFHEDFBEA)
|
||||||
// reads required keys: FeaturedRoomGroupId, Name, Rooms (NOT
|
// reads required keys: FeaturedRoomGroupId, Name, Rooms (NOT
|
||||||
@@ -76,13 +75,13 @@ public class CommunityBoardController(
|
|||||||
FeaturedRoomGroupId = 0L,
|
FeaturedRoomGroupId = 0L,
|
||||||
Name = group.Name ?? string.Empty,
|
Name = group.Name ?? string.Empty,
|
||||||
Rooms = ids.Select(id => rooms.TryGetValue(id, out var r)
|
Rooms = ids.Select(id => rooms.TryGetValue(id, out var r)
|
||||||
? new { RoomName = r.Name, RoomId = r.Id, ImageName = r.ImageName ?? string.Empty }
|
? new { RoomName = r.Name, RoomId = r.Id, ImageName = RoomService.ResolveDisplayImageName(r) }
|
||||||
: new { RoomName = string.Empty, RoomId = id, ImageName = string.Empty })
|
: new { RoomName = string.Empty, RoomId = id, ImageName = RoomService.DefaultRoomImageName })
|
||||||
.ToArray(),
|
.ToArray(),
|
||||||
// Keep the old key around for any 2020.03 clients hitting prod.
|
// Keep the old key around for any 2020.03 clients hitting prod.
|
||||||
FeaturedRooms = ids.Select(id => rooms.TryGetValue(id, out var r)
|
FeaturedRooms = ids.Select(id => rooms.TryGetValue(id, out var r)
|
||||||
? new { RoomName = r.Name, RoomId = r.Id, ImageName = r.ImageName ?? string.Empty }
|
? new { RoomName = r.Name, RoomId = r.Id, ImageName = RoomService.ResolveDisplayImageName(r) }
|
||||||
: new { RoomName = string.Empty, RoomId = id, ImageName = string.Empty })
|
: new { RoomName = string.Empty, RoomId = id, ImageName = RoomService.DefaultRoomImageName })
|
||||||
.ToArray(),
|
.ToArray(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ namespace DorkNet.Server.Services;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class RoomService(DorkNetDbContext db)
|
public class RoomService(DorkNetDbContext db)
|
||||||
{
|
{
|
||||||
|
public const string DefaultRoomImageName = "image_RecCenter.png";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Idempotent seed of the well-known Rec Room Original rooms — pulled
|
/// Idempotent seed of the well-known Rec Room Original rooms — pulled
|
||||||
/// from the AGRoomRuntimeConfig.Locations array we walked in
|
/// from the AGRoomRuntimeConfig.Locations array we walked in
|
||||||
@@ -232,7 +234,6 @@ public class RoomService(DorkNetDbContext db)
|
|||||||
// image/<blob-name> keys, so do NOT require the mapped blob
|
// image/<blob-name> keys, so do NOT require the mapped blob
|
||||||
// filename to exist on local disk before using it. Local disk
|
// filename to exist on local disk before using it. Local disk
|
||||||
// is only a fallback for rooms with no blob-name mapping.
|
// is only a fallback for rooms with no blob-name mapping.
|
||||||
const string ultimateFallback = "image_RecCenter.png";
|
|
||||||
var imagesDir = Path.Combine(AppContext.BaseDirectory, "data", "images");
|
var imagesDir = Path.Combine(AppContext.BaseDirectory, "data", "images");
|
||||||
bool OnDisk(string name) =>
|
bool OnDisk(string name) =>
|
||||||
!string.IsNullOrEmpty(name) && File.Exists(Path.Combine(imagesDir, name));
|
!string.IsNullOrEmpty(name) && File.Exists(Path.Combine(imagesDir, name));
|
||||||
@@ -248,7 +249,7 @@ public class RoomService(DorkNetDbContext db)
|
|||||||
else if (OnDisk(r.ImageName))
|
else if (OnDisk(r.ImageName))
|
||||||
preferred = r.ImageName;
|
preferred = r.ImageName;
|
||||||
else
|
else
|
||||||
preferred = ultimateFallback;
|
preferred = DefaultRoomImageName;
|
||||||
|
|
||||||
if (r.ImageName != preferred)
|
if (r.ImageName != preferred)
|
||||||
{
|
{
|
||||||
@@ -1085,7 +1086,7 @@ public class RoomService(DorkNetDbContext db)
|
|||||||
Description = r.Description,
|
Description = r.Description,
|
||||||
CreatorPlayerId = r.CreatorPlayerId,
|
CreatorPlayerId = r.CreatorPlayerId,
|
||||||
CreatorAccountId = r.CreatorPlayerId,
|
CreatorAccountId = r.CreatorPlayerId,
|
||||||
ImageName = r.ImageName,
|
ImageName = ResolveDisplayImageName(r),
|
||||||
State = r.State,
|
State = r.State,
|
||||||
Accessibility = r.Accessibility,
|
Accessibility = r.Accessibility,
|
||||||
SupportsLevelVoting = r.SupportsLevelVoting,
|
SupportsLevelVoting = r.SupportsLevelVoting,
|
||||||
@@ -1129,6 +1130,16 @@ public class RoomService(DorkNetDbContext db)
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static string ResolveDisplayImageName(RoomEntity r)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(r.ImageName))
|
||||||
|
return r.ImageName;
|
||||||
|
|
||||||
|
return RoomImagesByName.TryGetValue(r.Name, out var imageName) && !string.IsNullOrWhiteSpace(imageName)
|
||||||
|
? imageName
|
||||||
|
: DefaultRoomImageName;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Idempotent admin overrides applied AFTER SeedAsync. Keeps the seed
|
/// Idempotent admin overrides applied AFTER SeedAsync. Keeps the seed
|
||||||
/// table itself untouched (so a clean DB build still seeds the
|
/// table itself untouched (so a clean DB build still seeds the
|
||||||
|
|||||||
Reference in New Issue
Block a user