mirror of
https://github.com/JogmansonReal/Radicade.git
synced 2026-10-26 15:39:01 -07:00
Radicade Public Code
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
using System.Reflection;
|
||||
using System.Security.Claims;
|
||||
using System.Text.Json;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Routing;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RadicadeServer.DB;
|
||||
using RadicadeServer.RecNet.Accounts;
|
||||
using RadicadeServer.RecNet.Enums;
|
||||
using RadicadeServer.RecNet.Enums.Rooms;
|
||||
using RadicadeServer.RecNet.Rooms;
|
||||
using RadicadeServer.RoomServer;
|
||||
using RadicadeServer.Utils;
|
||||
using Xunit;
|
||||
|
||||
namespace RadicadeServer.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// The Play menu's carousel rows read <c>rooms/carousel/{source}&skip=&take=</c>. The
|
||||
/// client's own template for that feed is paged, and every sibling paged rooms feed answers
|
||||
/// <c>{ Results, TotalResults }</c>; this one answered a bare array, which the client reported as
|
||||
///
|
||||
/// Malformed Response: '[ { "RoomId": 167, "IsDorm": false, ... } ]'
|
||||
///
|
||||
/// and then as <c>Error refreshing rooms from source CarouselEndpoint</c> - the row stayed empty.
|
||||
///
|
||||
/// The route assertion is here too: a controller-level test calls the handler by name, so it
|
||||
/// cannot see that the URL the client builds has no route at all (that is what the 404 was
|
||||
/// before this route existed).
|
||||
/// </summary>
|
||||
[Collection(DbFactoryCollection.Name)]
|
||||
public class CarouselFeedShapeTests
|
||||
{
|
||||
private const long RoomId = 167;
|
||||
private const long OtherRoomId = 211;
|
||||
|
||||
private sealed class TestDbContextFactory : IDbContextFactory<RecDBContext>
|
||||
{
|
||||
private readonly DbContextOptions<RecDBContext> options = TestDbOptions.Create()
|
||||
.UseInMemoryDatabase(Guid.NewGuid().ToString())
|
||||
.Options;
|
||||
|
||||
public RecDBContext CreateDbContext() => new(options);
|
||||
}
|
||||
|
||||
private static (TestDbContextFactory Factory, RecDBContext Db) CreateContext()
|
||||
{
|
||||
var factory = new TestDbContextFactory();
|
||||
RoomUtils.DbFactory = factory;
|
||||
return (factory, factory.CreateDbContext());
|
||||
}
|
||||
|
||||
private static void SetUser(Controller controller, long accountId)
|
||||
{
|
||||
var identity = new ClaimsIdentity("TestAuth");
|
||||
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, accountId.ToString()));
|
||||
controller.ControllerContext = new ControllerContext
|
||||
{
|
||||
HttpContext = new DefaultHttpContext { User = new ClaimsPrincipal(identity) }
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>Two public, live rooms - the shape a carousel row draws from.</summary>
|
||||
private static async Task SeedRoomsAsync(RecDBContext db)
|
||||
{
|
||||
db.Rooms.AddRange(
|
||||
new RoomData
|
||||
{
|
||||
RoomId = RoomId,
|
||||
Name = "Orientation",
|
||||
CreatorAccountId = 1,
|
||||
Accessibility = Accessibility.Public,
|
||||
State = RoomState.Active,
|
||||
MaxPlayers = 1,
|
||||
CreatedAt = DateTime.UtcNow,
|
||||
},
|
||||
new RoomData
|
||||
{
|
||||
RoomId = OtherRoomId,
|
||||
Name = "RecCenter",
|
||||
CreatorAccountId = 1,
|
||||
Accessibility = Accessibility.Public,
|
||||
State = RoomState.Active,
|
||||
MaxPlayers = 12,
|
||||
CreatedAt = DateTime.UtcNow,
|
||||
});
|
||||
await db.SaveChangesAsync();
|
||||
}
|
||||
|
||||
private static JsonElement ValueOf(IActionResult result)
|
||||
{
|
||||
var ok = Assert.IsType<OkObjectResult>(result);
|
||||
return JsonSerializer.SerializeToElement(ok.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SupportsThePagedCarouselRouteTheClientBuilds()
|
||||
{
|
||||
var method = typeof(RoomServerAPI).GetMethod(nameof(RoomServerAPI.GetCarouselRooms))!;
|
||||
|
||||
var attributes = method
|
||||
.GetCustomAttributes(typeof(HttpMethodAttribute), false)
|
||||
.Cast<HttpMethodAttribute>()
|
||||
.ToList();
|
||||
|
||||
Assert.Contains(attributes, x => x.Template == "rooms/carousel/{*source}");
|
||||
Assert.Contains(attributes, x => x is HttpGetAttribute);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TheCarouselRowAnswersThePagedEnvelopeWithRoomsInIt()
|
||||
{
|
||||
var (_, db) = CreateContext();
|
||||
await using var _db = db;
|
||||
await SeedRoomsAsync(db);
|
||||
|
||||
var api = new RoomServerAPI(db);
|
||||
SetUser(api, 1);
|
||||
|
||||
var value = ValueOf(await api.GetCarouselRooms("foryou", skip: -1, take: 20));
|
||||
|
||||
Assert.Equal(JsonValueKind.Object, value.ValueKind);
|
||||
Assert.Equal(2, value.GetProperty("TotalResults").GetInt32());
|
||||
var results = value.GetProperty("Results").EnumerateArray().ToArray();
|
||||
Assert.Equal(new long[] { RoomId, OtherRoomId },
|
||||
results.Select(room => room.GetProperty("RoomId").GetInt64()).ToArray());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ASourceThatMatchesNothingStillFillsTheRow()
|
||||
{
|
||||
var (_, db) = CreateContext();
|
||||
await using var _db = db;
|
||||
await SeedRoomsAsync(db);
|
||||
|
||||
var api = new RoomServerAPI(db);
|
||||
SetUser(api, 1);
|
||||
|
||||
// "rising" is one of the server's own ordering names, so it matches no room by name or
|
||||
// tag. An empty row is not the answer: the client marks the source failed.
|
||||
var value = ValueOf(await api.GetCarouselRooms("rising&skip=0&take=20", skip: -1, take: 20));
|
||||
|
||||
Assert.Equal(2, value.GetProperty("TotalResults").GetInt32());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user