This commit is contained in:
2025-08-22 11:55:35 +01:00
commit b21d2a685e
312 changed files with 31174 additions and 0 deletions

View File

@@ -0,0 +1,53 @@
using FluentAssertions;
using MareSynchronosServer.Discord;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Primitives;
using Moq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace MareSynchronosServerTest.Discord {
public class DiscordBotTest {
[Test]
[TestCase("", null)]
[TestCase("abcd", null)]
[TestCase("www.google.de", null)]
[TestCase("https://www.google.de", null)]
[TestCase("de.finalfantasyxiv.com/lodestone/character/1234", null)]
[TestCase("https://cn.finalfantasyxiv.com/lodestone/character/1234", null)]
[TestCase("http://jp.finalfantasyxiv.com/lodestone/character/1234", null)]
[TestCase("https://jp.finalfantasyxiv.com/character/1234", null)]
[TestCase("https://jp.finalfantasyxiv.com/lodestone/1234", null)]
[TestCase("https://www.finalfantasyxiv.com/lodestone/character/1234", null)]
[TestCase("https://jp.finalfantasyxiv.com/lodestone/character/1234", 1234)]
[TestCase("https://fr.finalfantasyxiv.com/lodestone/character/1234", 1234)]
[TestCase("https://eu.finalfantasyxiv.com/lodestone/character/1234/", 1234)]
[TestCase("https://eu.finalfantasyxiv.com/lodestone/character/1234?myurlparameter=500", 1234)]
[TestCase("https://de.finalfantasyxiv.com/lodestone/character/1234/whatever/3456", 1234)]
[TestCase("https://na.finalfantasyxiv.com/lodestone/character/1234abcd4321/whatever/3456", 1234)]
public void ParseCharacterIdFromLodestoneUrl_CheckThatIdIsParsedCorrectly(string url, int? expectedId) {
var inMemorySettings = new Dictionary<string, string> {
{"DiscordBotToken", "1234"}
};
IConfiguration configuration = new ConfigurationBuilder()
.AddInMemoryCollection(inMemorySettings)
.Build();
var spMock = new Mock<IServiceProvider>();
var loggerMock = new Mock<ILogger<DiscordBot>>();
var sut = new DiscordBot(spMock.Object, configuration, loggerMock.Object);
MethodInfo methodInfo = sut.GetType().GetMethod("ParseCharacterIdFromLodestoneUrl", BindingFlags.NonPublic | BindingFlags.Instance);
var actualId = methodInfo.Invoke(sut, new object[] { url });
actualId.Should().Be(expectedId);
}
}
}

View File

@@ -0,0 +1,82 @@
using MareSynchronosServer.Hubs;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Moq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using MareSynchronosShared.Data;
using MareSynchronosShared.Models;
namespace MareSynchronosServerTest.Hubs {
public class MareHubTest {
[Test]
public async Task Disconnect_QueryReturnsCorrectResult_Test() {
var options = new DbContextOptionsBuilder<MareDbContext>()
.UseInMemoryDatabase(databaseName: "mare").Options;
using var context = new MareDbContext(options);
context.Users.Add(new User() { UID = "User1", IsModerator = false, IsAdmin = false, CharacterIdentification = "Ident1" });
context.Users.Add(new User() { UID = "User2", IsModerator = false, IsAdmin = false, CharacterIdentification = "Ident2" });
context.Users.Add(new User() { UID = "User3", IsModerator = false, IsAdmin = false, CharacterIdentification = "Ident3" });
context.Users.Add(new User() { UID = "User4", IsModerator = false, IsAdmin = false, CharacterIdentification = "Ident4" });
context.Users.Add(new User() { UID = "User5", IsModerator = false, IsAdmin = false, CharacterIdentification = "Ident5" });
context.Users.Add(new User() { UID = "User6", IsModerator = false, IsAdmin = false, CharacterIdentification = "Ident6" });
// Valid pairs
context.ClientPairs.Add(new ClientPair() { UserUID = "User1", OtherUserUID = "User2", IsPaused = false });
context.ClientPairs.Add(new ClientPair() { UserUID = "User2", OtherUserUID = "User1", IsPaused = false });
context.ClientPairs.Add(new ClientPair() { UserUID = "User1", OtherUserUID = "User3", IsPaused = false });
context.ClientPairs.Add(new ClientPair() { UserUID = "User3", OtherUserUID = "User1", IsPaused = false });
// Other user paired but user not paired with current user
context.ClientPairs.Add(new ClientPair() { UserUID = "User4", OtherUserUID = "User1", IsPaused = false });
// Valid pair but user paused
context.ClientPairs.Add(new ClientPair() { UserUID = "User1", OtherUserUID = "User5", IsPaused = true });
context.ClientPairs.Add(new ClientPair() { UserUID = "User5", OtherUserUID = "User1", IsPaused = false });
// Valid pair but other user paused
context.ClientPairs.Add(new ClientPair() { UserUID = "User1", OtherUserUID = "User6", IsPaused = false });
context.ClientPairs.Add(new ClientPair() { UserUID = "User6", OtherUserUID = "User1", IsPaused = true });
// Non existant user
context.ClientPairs.Add(new ClientPair() { UserUID = "User99", OtherUserUID = "User1", IsPaused = false });
// Non-related data
context.ClientPairs.Add(new ClientPair() { UserUID = "User6", OtherUserUID = "User4", IsPaused = true });
context.ClientPairs.Add(new ClientPair() { UserUID = "User4", OtherUserUID = "User3", IsPaused = false });
context.ClientPairs.Add(new ClientPair() { UserUID = "User3", OtherUserUID = "User2", IsPaused = false });
context.SaveChanges();
var clientContextMock = new Mock<HubCallerContext>();
var claimMock = new Mock<ClaimsPrincipal>();
var claim = new Claim(ClaimTypes.NameIdentifier, "User1");
claimMock.SetupGet(x => x.Claims).Returns(new List<Claim>() { claim });
clientContextMock.SetupGet(x => x.User).Returns(claimMock.Object);
var clientsMock = new Mock<IHubCallerClients>();
var clientProxyMock = new Mock<IClientProxy>();
clientsMock.Setup(x => x.Users(It.IsAny<IReadOnlyList<string>>())).Returns(clientProxyMock.Object);
var hub = new MareHub(context, new Mock<ILogger<MareHub>>().Object, null, new Mock<IConfiguration>().Object, new Mock<IHttpContextAccessor>().Object);
hub.Clients = clientsMock.Object;
hub.Context = clientContextMock.Object;
await hub.OnDisconnectedAsync(new Exception("Test Exception")).ConfigureAwait(false);
clientsMock.Verify(x => x.Users(It.Is<IReadOnlyList<string>>(x => x.Count() == 2 && x[0] == "User2" && x[1] == "User3")), Times.Once);
clientProxyMock.Verify(x => x.SendCoreAsync(It.IsAny<string>(), It.Is<object[]>(o => (string)o[0] == "Ident1"), It.IsAny<CancellationToken>()), Times.Once);
}
}
}

View File

@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.7.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="6.0.8" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="Moq" Version="4.18.2" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
<PackageReference Include="NUnit.Analyzers" Version="3.3.0" />
<PackageReference Include="coverlet.collector" Version="3.1.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MareSynchronosServer\MareSynchronosServer.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1 @@
global using NUnit.Framework;