mirror of
https://github.com/JogmansonReal/Radicade.git
synced 2026-10-25 23:18:56 -07:00
Radicade Public Code
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
using System.Text.Json;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RadicadeServer.API.Notifications;
|
||||
using RadicadeServer.DB;
|
||||
using RadicadeServer.RecNet.Enums.Messages;
|
||||
using RadicadeServer.RecNet.Messages;
|
||||
using Xunit;
|
||||
|
||||
namespace RadicadeServer.Tests;
|
||||
|
||||
public sealed class SqlServerInviteFactAttribute : FactAttribute
|
||||
{
|
||||
public SqlServerInviteFactAttribute()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("RADICADE_SQL_TEST_CONNECTION")))
|
||||
Skip = "Set RADICADE_SQL_TEST_CONNECTION to a SQL Server with permission to create a scratch database.";
|
||||
}
|
||||
}
|
||||
|
||||
[Collection(DbFactoryCollection.Name)]
|
||||
public class SqlServerInvitePersistenceTests
|
||||
{
|
||||
private sealed class Factory(string connection) : IDbContextFactory<RecDBContext>
|
||||
{
|
||||
public RecDBContext CreateDbContext() => new(TestDbOptions.Create()
|
||||
.UseSqlServer(connection, sql => sql.EnableRetryOnFailure(3)).Options);
|
||||
}
|
||||
|
||||
[SqlServerInviteFact]
|
||||
public async Task InvitePayloadCommitsWithSqlServerRetriesEnabled()
|
||||
{
|
||||
// Never write test invitations into the user's database or notify real players.
|
||||
var database = "RadicadeInviteTest_" + Guid.NewGuid().ToString("N");
|
||||
var connection = new SqlConnectionStringBuilder(
|
||||
Environment.GetEnvironmentVariable("RADICADE_SQL_TEST_CONNECTION"));
|
||||
connection.InitialCatalog = "master";
|
||||
await using var admin = new SqlConnection(connection.ConnectionString);
|
||||
await admin.OpenAsync();
|
||||
await using (var create = new SqlCommand($"CREATE DATABASE [{database}]", admin))
|
||||
await create.ExecuteNonQueryAsync();
|
||||
var previous = Notify.DbFactory;
|
||||
try
|
||||
{
|
||||
connection.InitialCatalog = database;
|
||||
var factory = new Factory(connection.ConnectionString);
|
||||
await using var db = factory.CreateDbContext();
|
||||
await db.Database.ExecuteSqlRawAsync("""
|
||||
CREATE TABLE [Messages] (
|
||||
[Id] bigint IDENTITY PRIMARY KEY,
|
||||
[FromPlayerId] bigint NOT NULL, [ToPlayerId] bigint NOT NULL,
|
||||
[SentTime] datetime2 NOT NULL, [Type] int NOT NULL,
|
||||
[Data] nvarchar(max) NOT NULL, [Details] nvarchar(max) NOT NULL,
|
||||
[RoomId] bigint NULL, [PlayerEventId] bigint NULL,
|
||||
[IsDismissed] bit NOT NULL);
|
||||
""");
|
||||
Notify.DbFactory = factory;
|
||||
var message = new Message
|
||||
{
|
||||
FromPlayerId = long.MaxValue - 1, RoomId = 45, Type = MessageType.GameInviteV2
|
||||
};
|
||||
await Notify.SendMessage(long.MaxValue, message, prepareWithId: stored =>
|
||||
stored.Data = JsonSerializer.Serialize(new RoomInviteDetails
|
||||
{
|
||||
InviteId = stored.Id, Name = "SQL invite test", RoomInstanceId = 123
|
||||
}));
|
||||
var saved = await db.Messages.AsNoTracking().SingleAsync();
|
||||
Assert.True(saved.Id > 0);
|
||||
Assert.Equal(saved.Id, JsonSerializer.Deserialize<RoomInviteDetails>(saved.Data)!.InviteId);
|
||||
Assert.Equal(123L, RoomInviteDetails.GetInstanceId(saved));
|
||||
Assert.Equal(long.MaxValue, saved.ToPlayerId);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Notify.DbFactory = previous;
|
||||
SqlConnection.ClearAllPools();
|
||||
await using var drop = new SqlCommand(
|
||||
$"ALTER DATABASE [{database}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; DROP DATABASE [{database}]", admin);
|
||||
await drop.ExecuteNonQueryAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user