mirror of
https://github.com/JogmansonReal/Radicade.git
synced 2026-10-26 07:29:00 -07:00
Radicade Public Code
This commit is contained in:
@@ -0,0 +1,181 @@
|
||||
using System.Text.Json.Nodes;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RadicadeServer.Admin;
|
||||
using RadicadeServer.DB;
|
||||
using RadicadeServer.RecNet;
|
||||
using RadicadeServer.RecNet.Enums;
|
||||
using RadicadeServer.RecNet.Enums.Rooms;
|
||||
using RadicadeServer.RecNet.Rooms;
|
||||
using Xunit;
|
||||
|
||||
namespace RadicadeServer.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Room creation through <c>POST admin/rooms/create/room</c>, which is how every import puts a
|
||||
/// room on this server (the Taco archives, tools/import_room_dump.mjs).
|
||||
///
|
||||
/// The route reads its body with a helper that only knew scalars. Enums and arrays are neither,
|
||||
/// so <c>Accessibility</c>, <c>WarningMask</c>, <c>MaxPlayerCalculationMode</c> and <c>Tags</c>
|
||||
/// silently took their defaults while the strings and bools around them bound: an imported room
|
||||
/// arrived Private (invisible to every list, unsearchable) and untagged, with nothing in the
|
||||
/// response to say a field had been dropped. These pin the whole payload, and the defaults the
|
||||
/// route still falls back to when a field is absent.
|
||||
/// </summary>
|
||||
public class AdminRoomCreateTests
|
||||
{
|
||||
private static RecDBContext NewDb() => new(
|
||||
TestDbOptions.Create()
|
||||
.UseInMemoryDatabase(Guid.NewGuid().ToString())
|
||||
.Options);
|
||||
|
||||
private const string Secret = "test-bot-secret";
|
||||
|
||||
private static async Task<RecDBContext> CreateAsync(string json)
|
||||
{
|
||||
var db = NewDb();
|
||||
var api = new AdminRoomAPI(db);
|
||||
var original = DBConfig.AdminApiKey;
|
||||
DBConfig.AdminApiKey = Secret;
|
||||
try
|
||||
{
|
||||
var result = await api.CreateRoom(Secret, 2, JsonNode.Parse(json)!);
|
||||
Assert.IsType<OkObjectResult>(result);
|
||||
}
|
||||
finally
|
||||
{
|
||||
DBConfig.AdminApiKey = original;
|
||||
}
|
||||
|
||||
return db;
|
||||
}
|
||||
|
||||
private const string RoomPayload = """
|
||||
{
|
||||
"Name": "MakeItToMidnight",
|
||||
"Description": "A night of horror ensues.",
|
||||
"Accessibility": 1,
|
||||
"State": 0,
|
||||
"IsRRO": true,
|
||||
"IsDorm": false,
|
||||
"ImageName": "default.png",
|
||||
"MaxPlayers": 5,
|
||||
"MaxPlayerCalculationMode": 1,
|
||||
"WarningMask": 1,
|
||||
"CloningAllowed": false,
|
||||
"SupportsScreens": 1,
|
||||
"SupportsWalkVR": true,
|
||||
"SupportsTeleportVR": "true",
|
||||
"SupportsJuniors": "1",
|
||||
"Tags": [ { "Tag": "import", "Type": 1 } ],
|
||||
"CreatedAt": "2023-07-26T23:23:35Z",
|
||||
"SubRooms": [
|
||||
{
|
||||
"Name": "Home",
|
||||
"Accessibility": 1,
|
||||
"IsSandbox": true,
|
||||
"MaxPlayers": 5,
|
||||
"UnitySceneId": "a75f7547-79eb-47c6-8986-6767abcb4f92",
|
||||
"DataBlob": "aq4a6u116zm6uathf9i9b7n0y.room"
|
||||
}
|
||||
]
|
||||
}
|
||||
""";
|
||||
|
||||
[Fact]
|
||||
public async Task AnImportedRoomKeepsItsAccessibilityWarningMaskAndPlayerCountMode()
|
||||
{
|
||||
var db = await CreateAsync(RoomPayload);
|
||||
var room = db.Rooms.Single();
|
||||
|
||||
Assert.Equal(Accessibility.Public, room.Accessibility);
|
||||
Assert.Equal(WarningMask.Scary, room.WarningMask);
|
||||
Assert.Equal(MaxPlayerMode.OnlyEntrySubrooms, room.MaxPlayerCalculationMode);
|
||||
Assert.Equal(5, room.MaxPlayers);
|
||||
Assert.True(room.IsRRO);
|
||||
Assert.False(room.IsDorm);
|
||||
Assert.Equal(2, room.CreatorAccountId);
|
||||
Assert.Equal(new DateTime(2023, 7, 26, 23, 23, 35), room.CreatedAt);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TheTagListIsKeptWithItsTagTypes()
|
||||
{
|
||||
var db = await CreateAsync(RoomPayload);
|
||||
|
||||
// One tag, of type Auto - the same "name,type|name,type" string the room's own tag
|
||||
// screen writes, which is what the tag doors and the list queries read back.
|
||||
Assert.Equal("import,1", db.Rooms.Single().Tags);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task EnumsArriveAsNumbersOrNamesAndBoolsAsTrueOnesOrStrings()
|
||||
{
|
||||
var db = await CreateAsync("""
|
||||
{
|
||||
"Name": "NamedEnums",
|
||||
"Accessibility": "Public",
|
||||
"WarningMask": "Scary",
|
||||
"MaxPlayerCalculationMode": "OnlyEntrySubrooms",
|
||||
"SupportsScreens": 1,
|
||||
"SupportsWalkVR": true,
|
||||
"SupportsQuest2": "true",
|
||||
"SupportsTeleportVR": "false",
|
||||
"IsRRO": 1
|
||||
}
|
||||
""");
|
||||
var room = db.Rooms.Single();
|
||||
|
||||
Assert.Equal(Accessibility.Public, room.Accessibility);
|
||||
Assert.Equal(WarningMask.Scary, room.WarningMask);
|
||||
Assert.Equal(MaxPlayerMode.OnlyEntrySubrooms, room.MaxPlayerCalculationMode);
|
||||
Assert.True(room.SupportsScreens);
|
||||
Assert.True(room.SupportsWalkVR);
|
||||
Assert.True(room.SupportsQuest2);
|
||||
Assert.False(room.SupportsTeleportVR);
|
||||
Assert.True(room.IsRRO);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AnAbsentFieldStillTakesTheRoutesDefault()
|
||||
{
|
||||
var db = await CreateAsync("""{ "Name": "BareRoom" }""");
|
||||
var room = db.Rooms.Single();
|
||||
|
||||
Assert.Equal(Accessibility.Private, room.Accessibility);
|
||||
Assert.Equal(WarningMask.None, room.WarningMask);
|
||||
Assert.Equal(MaxPlayerMode.AllSubrooms, room.MaxPlayerCalculationMode); Assert.Equal("", room.Tags);
|
||||
Assert.False(room.IsRRO);
|
||||
|
||||
// LoadScreens is the one field whose absence used to fail the insert outright: the
|
||||
// column is NOT NULL and the payload's missing array was written over the default.
|
||||
Assert.Equal("[]", room.loadScreen);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TheSubroomKeepsTheSceneAndTheSaveItWasImportedWith()
|
||||
{
|
||||
var db = await CreateAsync(RoomPayload);
|
||||
var subRoom = db.SubRooms.Single();
|
||||
|
||||
Assert.Equal("Home", subRoom.Name);
|
||||
Assert.Equal("a75f7547-79eb-47c6-8986-6767abcb4f92", subRoom.UnitySceneId);
|
||||
Assert.Equal("aq4a6u116zm6uathf9i9b7n0y.room", subRoom.DataBlob);
|
||||
Assert.Equal(2, subRoom.SavedByAccountId);
|
||||
Assert.True(subRoom.IsSandbox);
|
||||
Assert.Equal(Accessibility.Public, subRoom.Accessibility);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ASceneTheClientDoesNotKnowBecomesTheMakerRoom()
|
||||
{
|
||||
var db = await CreateAsync("""
|
||||
{
|
||||
"Name": "OddScene",
|
||||
"SubRooms": [ { "Name": "Home", "UnitySceneId": "not-a-scene", "DataBlob": "empty.room" } ]
|
||||
}
|
||||
""");
|
||||
|
||||
Assert.Equal(SceneLocations.MakerRoom, db.SubRooms.Single().UnitySceneId);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user