mirror of
https://github.com/JogmansonReal/Radicade.git
synced 2026-10-25 23:18:56 -07:00
452 lines
22 KiB
C#
452 lines
22 KiB
C#
using System.Security.Claims;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using RadicadeServer.API.Keepsakes;
|
|
using RadicadeServer.DB;
|
|
using RadicadeServer.RecNet.Keepsakes;
|
|
using Xunit;
|
|
|
|
namespace RadicadeServer.Tests;
|
|
|
|
/// <summary>
|
|
/// The keepsake store: a placed keepsake is the room save's GUID, seeing a room without one is
|
|
/// still NO CONTENT, and collecting is per player and idempotent.
|
|
/// </summary>
|
|
public class KeepsakesStoreTests : IDisposable
|
|
{
|
|
private const long Room = 25;
|
|
|
|
private readonly KeepsakeRoomConfig? _previousRooms;
|
|
private readonly bool? _previousFeature;
|
|
|
|
/// <summary>
|
|
/// These tests exercise the feature, so they configure it rather than inheriting whatever the
|
|
/// shipped config says: keepsakes are OFF unless a keepsake room is configured
|
|
/// (<see cref="KeepsakeFeature"/>), and the shipped file lists no room. Pinning "every room is a
|
|
/// keepsake room" here is also what makes a test's own override - the "no keepsake rooms" cases
|
|
/// below - a deliberate change rather than a fallback.
|
|
/// </summary>
|
|
public KeepsakesStoreTests()
|
|
{
|
|
_previousRooms = KeepsakeRoomConfig.Override;
|
|
_previousFeature = KeepsakeFeature.Override;
|
|
KeepsakeRoomConfig.Override = KeepsakeRoomConfig.Parse("""{ "AllRooms": true }""");
|
|
KeepsakeFeature.Override = null;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
KeepsakeRoomConfig.Override = _previousRooms;
|
|
KeepsakeFeature.Override = _previousFeature;
|
|
}
|
|
|
|
private static RecDBContext NewDb()
|
|
=> new RecDBContext(TestDbOptions.Create()
|
|
.UseInMemoryDatabase(Guid.NewGuid().ToString()).Options);
|
|
|
|
private static KeepsakesAPI CreateApi(RecDBContext db, long accountId = 2, string? body = null)
|
|
{
|
|
var identity = new ClaimsIdentity("TestAuth");
|
|
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, accountId.ToString()));
|
|
var context = new DefaultHttpContext { User = new ClaimsPrincipal(identity) };
|
|
if (body != null)
|
|
{
|
|
context.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));
|
|
context.Request.ContentType = "application/json";
|
|
}
|
|
return new KeepsakesAPI(db) { ControllerContext = new ControllerContext { HttpContext = context } };
|
|
}
|
|
|
|
private static Guid PlacedGuid(IActionResult result)
|
|
{
|
|
var ok = Assert.IsType<OkObjectResult>(result);
|
|
var json = JsonSerializer.SerializeToElement(ok.Value);
|
|
return json.GetProperty("KeepsakeInstanceId").GetGuid();
|
|
}
|
|
|
|
/// <summary>
|
|
/// The room's keepsake carries the id the ROOM SAVE already has. Minting a different one here
|
|
/// is how a room ends up with a keepsake the server knows under another name, so the id in the
|
|
/// placement body is the id that has to come back.
|
|
/// </summary>
|
|
[Fact]
|
|
public async Task PlacementKeepsTheRoomSavesInstanceId()
|
|
{
|
|
var savedId = Guid.Parse("a75f7547-79eb-47c6-8986-6767abcb4f92");
|
|
await using var db = NewDb();
|
|
var api = CreateApi(db, body: $$"""
|
|
{"RoomId":{{Room}},"SubRoomId":null,"KeepsakeCategoryConfigId":0,
|
|
"KeepsakeInstanceId":"{{savedId}}"}
|
|
""");
|
|
|
|
var placed = await api.Place(Room);
|
|
Assert.Equal(savedId, PlacedGuid(placed));
|
|
|
|
var stored = await db.KeepsakeInstances.SingleAsync();
|
|
Assert.Equal(Room, stored.RoomId);
|
|
Assert.Equal(0, stored.KeepsakeCategoryId);
|
|
Assert.Equal(2, stored.PlacedByAccountId);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task UnknownCategoryIsRejectedRatherThanStored()
|
|
{
|
|
await using var db = NewDb();
|
|
var api = CreateApi(db, body: """{"KeepsakeCategoryConfigId":99}""");
|
|
|
|
Assert.IsType<BadRequestObjectResult>(await api.Place(Room));
|
|
Assert.Empty(db.KeepsakeInstances);
|
|
}
|
|
|
|
/// <summary>
|
|
/// One placed keepsake, seen by the player who placed it: it is an instance to collect and
|
|
/// there is no collection record yet. This is the body the room-load phase reads - an id here
|
|
/// that has no row behind it is what faults the load, so the two lists move together.
|
|
/// </summary>
|
|
[Fact]
|
|
public async Task RoomServesTheInstancesAndTheCallersRecords()
|
|
{
|
|
await using var db = NewDb();
|
|
var id = Guid.NewGuid();
|
|
await CreateApi(db, body: $$"""{"KeepsakeCategoryConfigId":5,"KeepsakeInstanceId":"{{id}}"}""").Place(Room);
|
|
|
|
var result = Assert.IsType<OkObjectResult>(await CreateApi(db).Room(Room));
|
|
var json = JsonSerializer.SerializeToElement(result.Value);
|
|
|
|
var instance = Assert.Single(json.GetProperty("KeepsakeInstances").EnumerateArray());
|
|
Assert.Equal(id, instance.GetProperty("KeepsakeInstanceId").GetGuid());
|
|
Assert.Equal(5, instance.GetProperty("KeepsakeCategoryConfigId").GetInt32());
|
|
Assert.Equal(Room, instance.GetProperty("KeepsakeRoomId").GetInt64());
|
|
|
|
Assert.Empty(json.GetProperty("KeepsakeCollectionRecords").EnumerateArray());
|
|
|
|
// A permitted room names the keepsake event, which is what the client checks for before it
|
|
// offers a keepsake at all - the list of events is never empty for one of these rooms.
|
|
Assert.NotEmpty(json.GetProperty("KeepsakeProgressionEventIds").EnumerateArray());
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CollectingMovesTheInstanceIntoTheCallersRecords()
|
|
{
|
|
await using var db = NewDb();
|
|
var id = Guid.NewGuid();
|
|
await CreateApi(db, body: $$"""{"KeepsakeCategoryConfigId":6,"KeepsakeInstanceId":"{{id}}"}""").Place(Room);
|
|
|
|
var collected = Assert.IsType<OkObjectResult>(await CreateApi(db, body: $$"""{"KeepsakeInstanceIds":["{{id}}"]}""").Collect(Room));
|
|
var collectedJson = JsonSerializer.SerializeToElement(collected.Value);
|
|
Assert.Equal(Room, collectedJson.GetProperty("KeepsakeRoomId").GetInt64());
|
|
|
|
var result = Assert.IsType<OkObjectResult>(await CreateApi(db).Room(Room));
|
|
var json = JsonSerializer.SerializeToElement(result.Value);
|
|
|
|
var record = Assert.Single(json.GetProperty("KeepsakeCollectionRecords").EnumerateArray());
|
|
Assert.Equal(id, record.GetProperty("KeepsakeInstanceId").GetGuid());
|
|
Assert.Equal(6, record.GetProperty("KeepsakeCategoryConfigId").GetInt32());
|
|
|
|
// Collected keepsakes are no longer instances to hand out - a second body for the same
|
|
// keepsake would put the player back in front of something they already have.
|
|
Assert.Empty(json.GetProperty("KeepsakeInstances").EnumerateArray());
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CollectingTwiceKeepsTheFirstRecord()
|
|
{
|
|
await using var db = NewDb();
|
|
var id = Guid.NewGuid();
|
|
await CreateApi(db, body: $$"""{"KeepsakeCategoryConfigId":0,"KeepsakeInstanceId":"{{id}}"}""").Place(Room);
|
|
|
|
await CreateApi(db, body: $$"""{"KeepsakeInstanceIds":["{{id}}"]}""").Collect(Room);
|
|
var first = await db.KeepsakeCollectionRecords.SingleAsync();
|
|
|
|
await CreateApi(db, body: $$"""{"KeepsakeInstanceIds":["{{id}}"]}""").Collect(Room);
|
|
var records = db.KeepsakeCollectionRecords.ToList();
|
|
|
|
Assert.Single(records);
|
|
Assert.Equal(first.CollectedAt, records[0].CollectedAt);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Another player's collection is not mine: their records do not hide an instance from me.
|
|
/// </summary>
|
|
[Fact]
|
|
public async Task CollectionIsPerPlayer()
|
|
{
|
|
await using var db = NewDb();
|
|
var id = Guid.NewGuid();
|
|
await CreateApi(db, accountId: 2, body: $$"""{"KeepsakeCategoryConfigId":0,"KeepsakeInstanceId":"{{id}}"}""").Place(Room);
|
|
await CreateApi(db, accountId: 2, body: $$"""{"KeepsakeInstanceIds":["{{id}}"]}""").Collect(Room);
|
|
|
|
var result = Assert.IsType<OkObjectResult>(await CreateApi(db, accountId: 3).Room(Room));
|
|
var json = JsonSerializer.SerializeToElement(result.Value);
|
|
|
|
Assert.Single(json.GetProperty("KeepsakeInstances").EnumerateArray());
|
|
Assert.Empty(json.GetProperty("KeepsakeCollectionRecords").EnumerateArray());
|
|
}
|
|
|
|
/// <summary>
|
|
/// An unnamed keepsake call is named in the log and answered 404, never 204: a write that looks
|
|
/// successful while the room save holds an id nothing backs is the failure this all exists to
|
|
/// avoid, and the log line is how the spelling gets found.
|
|
/// </summary>
|
|
[Fact]
|
|
public async Task UnclaimedRoutesAreReportedAndRefused()
|
|
{
|
|
await using var db = NewDb();
|
|
var api = CreateApi(db, body: """{"KeepsakeInstanceIds":[]}""");
|
|
|
|
Assert.IsType<NotFoundResult>(await api.Unclaimed("rooms/25/whatever"));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deleted keepsakes stay in the table but stop being served. The override pins "no keepsake
|
|
/// rooms" so this reads the removed instance and not the shipped config, which gives every
|
|
/// room the permission and would otherwise answer this room with an empty list instead.
|
|
/// </summary>
|
|
[Fact]
|
|
public async Task RemovedInstancesAreNotServed()
|
|
{
|
|
await using var db = NewDb();
|
|
var id = Guid.NewGuid();
|
|
await CreateApi(db, body: $$"""{"KeepsakeCategoryConfigId":4,"KeepsakeInstanceId":"{{id}}"}""").Place(Room);
|
|
|
|
var instance = await db.KeepsakeInstances.SingleAsync();
|
|
instance.Removed = true;
|
|
await db.SaveChangesAsync();
|
|
|
|
var original = KeepsakeRoomConfig.Override;
|
|
try
|
|
{
|
|
KeepsakeRoomConfig.Override = KeepsakeRoomConfig.Parse(null);
|
|
Assert.IsType<NoContentResult>(await CreateApi(db).Room(Room));
|
|
}
|
|
finally
|
|
{
|
|
KeepsakeRoomConfig.Override = original;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The same removed instance in a room the server DOES advertise as a keepsake room: the room
|
|
/// fields come back - the permission the shipped config grants - and the deleted instance is
|
|
/// still absent from them.
|
|
/// </summary>
|
|
[Fact]
|
|
public async Task ARemovedInstanceIsNotServedEvenInAKeepsakeRoom()
|
|
{
|
|
await using var db = NewDb();
|
|
var id = Guid.NewGuid();
|
|
await CreateApi(db, body: $$"""{"KeepsakeCategoryConfigId":4,"KeepsakeInstanceId":"{{id}}"}""").Place(Room);
|
|
|
|
var instance = await db.KeepsakeInstances.SingleAsync();
|
|
instance.Removed = true;
|
|
await db.SaveChangesAsync();
|
|
|
|
var original = KeepsakeRoomConfig.Override;
|
|
try
|
|
{
|
|
KeepsakeRoomConfig.Override = KeepsakeRoomConfig.Parse("""{ "AllRooms": true }""");
|
|
var ok = Assert.IsType<OkObjectResult>(await CreateApi(db).Room(Room));
|
|
var json = JsonSerializer.SerializeToElement(ok.Value);
|
|
|
|
Assert.Empty(json.GetProperty("KeepsakeInstances").EnumerateArray());
|
|
Assert.Equal(Room, json.GetProperty("KeepsakeRoomId").GetInt64());
|
|
}
|
|
finally
|
|
{
|
|
KeepsakeRoomConfig.Override = original;
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void CatalogCarriesTheReferenceCategories()
|
|
{
|
|
var results = KeepsakeCatalog.Results();
|
|
Assert.Equal(5, results.Length);
|
|
Assert.Equal("explore", KeepsakeCatalog.Find(0)!.VisualId);
|
|
Assert.Equal(3, KeepsakeCatalog.Find(0)!.LimitPerRoom);
|
|
Assert.Equal(40, KeepsakeCatalog.Find(6)!.XpValue);
|
|
Assert.Null(KeepsakeCatalog.Find(99));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CollectionAcknowledgesOnlyExistingActiveInstancesInThisRoom()
|
|
{
|
|
await using var db = NewDb();
|
|
var id = PlacedGuid(await CreateApi(db, body: """{"CategoryId":0}""").Place(Room));
|
|
var other = PlacedGuid(await CreateApi(db, body: """{"CategoryId":0}""").Place(Room + 1));
|
|
var result = Assert.IsType<OkObjectResult>(await CreateApi(db, body:
|
|
$$"""{"InstanceIds":["{{id}}","{{id}}","{{other}}","{{Guid.NewGuid()}}"]}""").Collect(Room));
|
|
Assert.Equal(id, Assert.Single(JsonSerializer.SerializeToElement(result.Value)
|
|
.GetProperty("KeepsakeInstanceIds").EnumerateArray()).GetGuid());
|
|
Assert.Single(db.KeepsakeCollectionRecords);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task RemovalIsRepeatablePreservesHistoryAndPreventsFurtherCollection()
|
|
{
|
|
await using var db = NewDb();
|
|
var id = PlacedGuid(await CreateApi(db, body: """{"CategoryId":0}""").Place(Room));
|
|
var body = $$"""{"InstanceIds":["{{id}}"]}""";
|
|
await CreateApi(db, body: body).Collect(Room);
|
|
Assert.IsType<ForbidResult>(await CreateApi(db, accountId: 3).Remove(Room, id));
|
|
Assert.IsType<NotFoundResult>(await CreateApi(db).Remove(Room + 1, id));
|
|
Assert.IsType<NoContentResult>(await CreateApi(db).Remove(Room, id));
|
|
Assert.IsType<NoContentResult>(await CreateApi(db).Remove(Room, id));
|
|
await CreateApi(db, accountId: 3, body: body).Collect(Room);
|
|
Assert.Single(db.KeepsakeCollectionRecords);
|
|
Assert.True((await db.KeepsakeInstances.SingleAsync()).Removed);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task PlacementCannotTakeAnotherPlayersInstanceOrMoveItToAnotherRoom()
|
|
{
|
|
await using var db = NewDb();
|
|
var id = PlacedGuid(await CreateApi(db, body: """{"CategoryId":0}""").Place(Room));
|
|
var body = $$"""{"CategoryId":0,"KeepsakeInstanceId":"{{id}}"}""";
|
|
Assert.IsType<ConflictObjectResult>(await CreateApi(db, accountId: 3, body: body).Place(Room));
|
|
Assert.IsType<ConflictObjectResult>(await CreateApi(db, body: body).Place(Room + 1));
|
|
Assert.Equal(Room, (await db.KeepsakeInstances.SingleAsync()).RoomId);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task RoomAndCategoryLimitsAllowRetriesButRejectAdditionalPlacements()
|
|
{
|
|
await using var db = NewDb();
|
|
KeepsakeRoomConfig.Override = KeepsakeRoomConfig.Parse("""{"AllRooms":true,"RoomLimit":1}""");
|
|
var id = PlacedGuid(await CreateApi(db, body: """{"CategoryId":0}""").Place(Room));
|
|
Assert.IsType<BadRequestObjectResult>(await CreateApi(db, body: """{"CategoryId":4}""").Place(Room));
|
|
Assert.Equal(id, PlacedGuid(await CreateApi(db, body:
|
|
$$"""{"CategoryId":0,"KeepsakeInstanceId":"{{id}}"}""").Place(Room)));
|
|
KeepsakeRoomConfig.Override = KeepsakeRoomConfig.Parse("""{"AllRooms":true,"RoomLimit":10}""");
|
|
await CreateApi(db, body: """{"CategoryId":0}""").Place(Room);
|
|
await CreateApi(db, body: """{"CategoryId":0}""").Place(Room);
|
|
Assert.IsType<BadRequestObjectResult>(await CreateApi(db, body: """{"CategoryId":0}""").Place(Room));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ValidBodyLargerThanLogPreviewIsParsedInFull()
|
|
{
|
|
await using var db = NewDb();
|
|
var body = JsonSerializer.Serialize(new { Padding = new string('x', 2100), CategoryId = 0 });
|
|
PlacedGuid(await CreateApi(db, body: body).Place(Room));
|
|
Assert.Single(db.KeepsakeInstances);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task PlacementRequiresAnAccountAndAPermittedRoom()
|
|
{
|
|
await using var db = NewDb();
|
|
var api = CreateApi(db, body: """{"CategoryId":0}""");
|
|
api.HttpContext.User = new ClaimsPrincipal();
|
|
Assert.IsType<UnauthorizedResult>(await api.Place(Room));
|
|
KeepsakeRoomConfig.Override = KeepsakeRoomConfig.Parse("""{"RoomIds":[26]}""");
|
|
Assert.IsType<BadRequestObjectResult>(await CreateApi(db, body: """{"CategoryId":0}""").Place(Room));
|
|
Assert.Empty(db.KeepsakeInstances);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task SeptemberClientCanPlaceReadCollectAndDeleteUsingItsActualRoutes()
|
|
{
|
|
await using var db = NewDb();
|
|
var placed = Assert.IsType<OkObjectResult>(await CreateApi(db,
|
|
body: $$"""{"RoomId":{{Room}},"SubRoomId":null,"KeepsakeCategory":4}""").PlaceFromClient());
|
|
var id = Assert.IsType<Guid>(placed.Value);
|
|
var room = JsonSerializer.SerializeToElement(Assert.IsType<OkObjectResult>(await CreateApi(db).Room(Room)).Value);
|
|
Assert.Equal(id, Assert.Single(room.GetProperty("Instances").EnumerateArray()).GetProperty("KeepsakeInstanceId").GetGuid());
|
|
|
|
var eventId = KeepsakeRoomConfig.Current.EventId;
|
|
var before = JsonSerializer.SerializeToElement(Assert.IsType<OkObjectResult>(await CreateApi(db).EventInstances(eventId)).Value);
|
|
Assert.Equal(Room, Assert.Single(before.GetProperty("Instances").EnumerateArray()).GetProperty("RoomId").GetInt64());
|
|
Assert.Empty(before.GetProperty("CollectionRecords").EnumerateArray());
|
|
|
|
var reward = JsonSerializer.SerializeToElement(Assert.IsType<OkObjectResult>(await CreateApi(db).CollectFromClient(id)).Value);
|
|
Assert.Equal(20, reward.GetProperty("TotalXp").GetInt32());
|
|
reward = JsonSerializer.SerializeToElement(Assert.IsType<OkObjectResult>(await CreateApi(db).CollectFromClient(id)).Value);
|
|
Assert.Equal(0, reward.GetProperty("TotalXp").GetInt32());
|
|
Assert.Single(db.KeepsakeCollectionRecords);
|
|
room = JsonSerializer.SerializeToElement(Assert.IsType<OkObjectResult>(await CreateApi(db).Room(Room)).Value);
|
|
Assert.Single(room.GetProperty("Instances").EnumerateArray());
|
|
Assert.Equal(2, Assert.Single(room.GetProperty("CollectionRecords").EnumerateArray()).GetProperty("AccountId").GetInt64());
|
|
var after = JsonSerializer.SerializeToElement(Assert.IsType<OkObjectResult>(await CreateApi(db).EventInstances(eventId)).Value);
|
|
Assert.Equal(id, Assert.Single(Assert.Single(after.GetProperty("CollectionRecords").EnumerateArray())
|
|
.GetProperty("KeepsakeInstanceIds").EnumerateArray()).GetGuid());
|
|
var other = JsonSerializer.SerializeToElement(Assert.IsType<OkObjectResult>(await CreateApi(db, accountId: 3).EventInstances(eventId)).Value);
|
|
Assert.Empty(other.GetProperty("CollectionRecords").EnumerateArray());
|
|
Assert.IsType<NoContentResult>(await CreateApi(db).RemoveFromClient(id));
|
|
var removed = Assert.IsType<ObjectResult>(await CreateApi(db).CollectFromClient(id));
|
|
Assert.Equal(404, removed.StatusCode);
|
|
Assert.Equal("The keepsake instance has been removed.", Assert.IsType<ProblemDetails>(removed.Value).Detail);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ClientCollectionExplainsMissingAndDisabledInstancesWithoutWritingRecords()
|
|
{
|
|
await using var db = NewDb();
|
|
var id = Guid.NewGuid();
|
|
var missing = Assert.IsType<ObjectResult>(await CreateApi(db).CollectFromClient(id));
|
|
Assert.Equal(404, missing.StatusCode);
|
|
Assert.Equal("The keepsake instance is not registered on this server.", Assert.IsType<ProblemDetails>(missing.Value).Detail);
|
|
|
|
KeepsakeFeature.Override = false;
|
|
var disabled = Assert.IsType<ObjectResult>(await CreateApi(db).CollectFromClient(id));
|
|
Assert.Equal(404, disabled.StatusCode);
|
|
Assert.Equal("Keepsakes are disabled on this server.", Assert.IsType<ProblemDetails>(disabled.Value).Detail);
|
|
Assert.Empty(db.KeepsakeCollectionRecords);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task EmptyRoomAndEventHaveNonNullClientLists()
|
|
{
|
|
await using var db = NewDb();
|
|
foreach (var response in new[] { await CreateApi(db).Room(Room), await CreateApi(db).EventInstances(KeepsakeRoomConfig.Current.EventId) })
|
|
{
|
|
var json = JsonSerializer.SerializeToElement(Assert.IsType<OkObjectResult>(response).Value);
|
|
Assert.Empty(json.GetProperty("Instances").EnumerateArray());
|
|
Assert.Empty(json.GetProperty("CollectionRecords").EnumerateArray());
|
|
}
|
|
Assert.IsType<NotFoundResult>(await CreateApi(db).EventInstances(9999));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task EventCanBeDisabledWhileKeepsakesRemainEnabled()
|
|
{
|
|
KeepsakeRoomConfig.Override = KeepsakeRoomConfig.Parse("""{"AllRooms":true,"EventEnabled":false}""");
|
|
await using var db = NewDb();
|
|
Assert.True(KeepsakeFeature.Enabled);
|
|
var api = new RadicadeServer.API.Compatibility.CompatibilityAPI(db);
|
|
Assert.Equal("null", Assert.IsType<ContentResult>(api.ActiveProgressionEvents()).Content);
|
|
Assert.IsType<NotFoundResult>(api.ProgressionEventDefinition(1));
|
|
Assert.IsType<NotFoundResult>(await CreateApi(db).EventInstances(1));
|
|
PlacedGuid(await CreateApi(db, body: """{"CategoryId":0}""").Place(Room));
|
|
var room = JsonSerializer.SerializeToElement(Assert.IsType<OkObjectResult>(await CreateApi(db).Room(Room)).Value);
|
|
Assert.Empty(room.GetProperty("KeepsakeProgressionEventIds").EnumerateArray());
|
|
Assert.Single(room.GetProperty("Instances").EnumerateArray());
|
|
}
|
|
|
|
[Fact]
|
|
public async Task AllRoomsEventAdvertisesRealRoomObjectsAndPlayerRecordTracksCollectionXp()
|
|
{
|
|
await using var db = NewDb();
|
|
db.Rooms.Add(new RadicadeServer.RecNet.Rooms.RoomData { RoomId = Room, Name = "Keepsake test" });
|
|
await db.SaveChangesAsync();
|
|
var keepsakes = CreateApi(db, body: """{"KeepsakeCategory":6}""");
|
|
var id = PlacedGuid(await keepsakes.Place(Room));
|
|
await CreateApi(db).CollectFromClient(id);
|
|
var api = new RadicadeServer.API.Compatibility.CompatibilityAPI(db)
|
|
{ ControllerContext = CreateApi(db).ControllerContext };
|
|
var definition = JsonSerializer.SerializeToElement(Assert.IsType<OkObjectResult>(api.ProgressionEventDefinition(1)).Value);
|
|
var list = Assert.Single(definition.GetProperty("KeepsakeRoomLists").EnumerateArray());
|
|
var room = Assert.Single(list.GetProperty("KeepsakeRooms").EnumerateArray());
|
|
Assert.Equal(Room, room.GetProperty("RoomId").GetInt64());
|
|
Assert.Equal(1, room.GetProperty("KeepsakeRoomListId").GetInt64());
|
|
Assert.Equal(1, list.GetProperty("ProgressionEventId").GetInt64());
|
|
Assert.True(list.GetProperty("RoomUnlockIntervalTicks").GetInt64() > 0);
|
|
var record = JsonSerializer.SerializeToElement(Assert.IsType<OkObjectResult>(api.ProgressionEventRecord(1)).Value);
|
|
Assert.Equal(2, record.GetProperty("AccountId").GetInt64());
|
|
Assert.Equal(40, record.GetProperty("Xp").GetInt32());
|
|
}
|
|
}
|