mirror of
https://github.com/RedWizardsLab/EchoHub.git
synced 2026-09-04 08:36:11 +02:00
feat: Add initial implementation of CI/CD workflows, documentation, and testing framework
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<IsPackable>false</IsPackable>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.*" />
|
||||
<PackageReference Include="xunit" Version="2.*" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.*">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\EchoHub.Core\EchoHub.Core.csproj" />
|
||||
<ProjectReference Include="..\EchoHub.Server\EchoHub.Server.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,56 @@
|
||||
using EchoHub.Server.Services;
|
||||
using Xunit;
|
||||
|
||||
namespace EchoHub.Tests;
|
||||
|
||||
public class FileValidationHelperTests
|
||||
{
|
||||
[Fact]
|
||||
public void IsValidImage_JpegMagicBytes_ReturnsTrue()
|
||||
{
|
||||
byte[] jpeg = [0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10];
|
||||
using var stream = new MemoryStream(jpeg);
|
||||
Assert.True(FileValidationHelper.IsValidImage(stream));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsValidImage_PngMagicBytes_ReturnsTrue()
|
||||
{
|
||||
byte[] png = [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A];
|
||||
using var stream = new MemoryStream(png);
|
||||
Assert.True(FileValidationHelper.IsValidImage(stream));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsValidImage_GifMagicBytes_ReturnsTrue()
|
||||
{
|
||||
byte[] gif = [0x47, 0x49, 0x46, 0x38, 0x39, 0x61];
|
||||
using var stream = new MemoryStream(gif);
|
||||
Assert.True(FileValidationHelper.IsValidImage(stream));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsValidImage_WebpMagicBytes_ReturnsTrue()
|
||||
{
|
||||
byte[] webp = [0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x45, 0x42, 0x50];
|
||||
using var stream = new MemoryStream(webp);
|
||||
Assert.True(FileValidationHelper.IsValidImage(stream));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsValidImage_RandomBytes_ReturnsFalse()
|
||||
{
|
||||
byte[] random = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05];
|
||||
using var stream = new MemoryStream(random);
|
||||
Assert.False(FileValidationHelper.IsValidImage(stream));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsValidImage_ResetsStreamPosition()
|
||||
{
|
||||
byte[] jpeg = [0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10];
|
||||
using var stream = new MemoryStream(jpeg);
|
||||
FileValidationHelper.IsValidImage(stream);
|
||||
Assert.Equal(0, stream.Position);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
using EchoHub.Server.Services;
|
||||
using Xunit;
|
||||
|
||||
namespace EchoHub.Tests;
|
||||
|
||||
public class PresenceTrackerTests
|
||||
{
|
||||
[Fact]
|
||||
public void UserConnected_IsOnline_ReturnsTrue()
|
||||
{
|
||||
var tracker = new PresenceTracker();
|
||||
tracker.UserConnected("conn1", Guid.NewGuid(), "alice");
|
||||
Assert.True(tracker.IsOnline("alice"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UserDisconnected_LastConnection_IsOnlineReturnsFalse()
|
||||
{
|
||||
var tracker = new PresenceTracker();
|
||||
tracker.UserConnected("conn1", Guid.NewGuid(), "alice");
|
||||
tracker.UserDisconnected("conn1");
|
||||
Assert.False(tracker.IsOnline("alice"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MultipleConnections_DisconnectOne_StillOnline()
|
||||
{
|
||||
var tracker = new PresenceTracker();
|
||||
var userId = Guid.NewGuid();
|
||||
tracker.UserConnected("conn1", userId, "alice");
|
||||
tracker.UserConnected("conn2", userId, "alice");
|
||||
tracker.UserDisconnected("conn1");
|
||||
Assert.True(tracker.IsOnline("alice"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JoinChannel_GetOnlineUsersInChannel_ReturnsUser()
|
||||
{
|
||||
var tracker = new PresenceTracker();
|
||||
tracker.UserConnected("conn1", Guid.NewGuid(), "alice");
|
||||
tracker.JoinChannel("alice", "general");
|
||||
var users = tracker.GetOnlineUsersInChannel("general");
|
||||
Assert.Contains("alice", users);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LeaveChannel_UserNoLongerInChannel()
|
||||
{
|
||||
var tracker = new PresenceTracker();
|
||||
tracker.UserConnected("conn1", Guid.NewGuid(), "alice");
|
||||
tracker.JoinChannel("alice", "general");
|
||||
tracker.LeaveChannel("alice", "general");
|
||||
var users = tracker.GetOnlineUsersInChannel("general");
|
||||
Assert.DoesNotContain("alice", users);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetChannelsForUser_ReturnsJoinedChannels()
|
||||
{
|
||||
var tracker = new PresenceTracker();
|
||||
tracker.UserConnected("conn1", Guid.NewGuid(), "alice");
|
||||
tracker.JoinChannel("alice", "general");
|
||||
tracker.JoinChannel("alice", "random");
|
||||
var channels = tracker.GetChannelsForUser("alice");
|
||||
Assert.Contains("general", channels);
|
||||
Assert.Contains("random", channels);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using EchoHub.Core.Constants;
|
||||
using Xunit;
|
||||
|
||||
namespace EchoHub.Tests;
|
||||
|
||||
public class ValidationConstantsTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("alice", true)]
|
||||
[InlineData("Bob_123", true)]
|
||||
[InlineData("user-name", true)]
|
||||
[InlineData("abc", true)]
|
||||
[InlineData("ab", false)]
|
||||
[InlineData("", false)]
|
||||
[InlineData("has space", false)]
|
||||
[InlineData("has@symbol", false)]
|
||||
public void UsernameRegex_ValidatesCorrectly(string input, bool expected)
|
||||
{
|
||||
var result = ValidationConstants.UsernameRegex().IsMatch(input);
|
||||
Assert.Equal(expected, result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("general", true)]
|
||||
[InlineData("my-channel_01", true)]
|
||||
[InlineData("ab", true)]
|
||||
[InlineData("a", false)]
|
||||
[InlineData("has space", false)]
|
||||
public void ChannelNameRegex_ValidatesCorrectly(string input, bool expected)
|
||||
{
|
||||
var result = ValidationConstants.ChannelNameRegex().IsMatch(input);
|
||||
Assert.Equal(expected, result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("#FF0000", true)]
|
||||
[InlineData("#aabbcc", true)]
|
||||
[InlineData("FF0000", false)]
|
||||
[InlineData("#FFF", false)]
|
||||
[InlineData("#GGGGGG", false)]
|
||||
public void HexColorRegex_ValidatesCorrectly(string input, bool expected)
|
||||
{
|
||||
var result = ValidationConstants.HexColorRegex().IsMatch(input);
|
||||
Assert.Equal(expected, result);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user