Adding unit tests

This commit is contained in:
hz
2025-06-04 21:33:44 -05:00
parent 638d73561d
commit ec38498957
17 changed files with 468 additions and 33 deletions
+112
View File
@@ -0,0 +1,112 @@
using GameAuthApi.Controllers;
using GameAuthApi.Models;
using GameAuthApi.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Text;
public class AuthControllerTests
{
private static IConfiguration GetConfig()
{
var inMemory = new Dictionary<string, string>
{
{"Jwt:Key", "testkeytestkeytestkey"},
{"Jwt:Issuer", "issuer"},
{"MongoDB:ConnectionString", "mongodb://localhost"},
{"MongoDB:DatabaseName", "test"}
};
return new ConfigurationBuilder().AddInMemoryCollection(inMemory!).Build();
}
[Fact]
public async Task Register_UserExists_ReturnsBadRequest()
{
var mockUser = new Mock<UserService>(GetConfig());
mockUser.Setup(u => u.GetByUsernameAsync("exists")).ReturnsAsync(new User());
var mockBlacklist = new Mock<BlacklistService>(GetConfig());
var controller = new AuthController(mockUser.Object, GetConfig(), mockBlacklist.Object);
var result = await controller.Register(new RegisterRequest { Username = "exists", Password = "p" });
Assert.IsType<BadRequestObjectResult>(result);
}
[Fact]
public async Task Login_InvalidPassword_ReturnsUnauthorized()
{
var user = new User { Username = "user", PasswordHash = BCrypt.Net.BCrypt.HashPassword("other") };
var mockUser = new Mock<UserService>(GetConfig());
mockUser.Setup(u => u.GetByUsernameAsync("user")).ReturnsAsync(user);
var controller = new AuthController(mockUser.Object, GetConfig(), new Mock<BlacklistService>(GetConfig()).Object);
var result = await controller.Login(new LoginRequest { Username = "user", Password = "bad" });
Assert.IsType<UnauthorizedResult>(result);
}
[Fact]
public async Task Refresh_InvalidToken_ReturnsUnauthorized()
{
var user = new User { Username = "user", RefreshToken = "r", RefreshTokenExpiry = DateTime.UtcNow.AddMinutes(-1) };
var mockUser = new Mock<UserService>(GetConfig());
mockUser.Setup(u => u.GetByUsernameAsync("user")).ReturnsAsync(user);
var controller = new AuthController(mockUser.Object, GetConfig(), new Mock<BlacklistService>(GetConfig()).Object);
var result = await controller.Refresh(new AuthController.RefreshRequest { Username = "user", RefreshToken = "bad" });
Assert.IsType<UnauthorizedObjectResult>(result);
}
[Fact]
public async Task Logout_BlacklistsToken()
{
var mockUser = new Mock<UserService>(GetConfig());
var blacklist = new Mock<BlacklistService>(GetConfig());
blacklist.Setup(b => b.AddToBlacklistAsync(It.IsAny<string>(), It.IsAny<DateTime>())).Returns(Task.CompletedTask).Verifiable();
var controller = new AuthController(mockUser.Object, GetConfig(), blacklist.Object);
controller.ControllerContext = new ControllerContext
{
HttpContext = new DefaultHttpContext()
};
var tokenHandler = new JwtSecurityTokenHandler();
var keyString = "abcdefghijklmnopqrstuvwxyz123456";
var key = Encoding.UTF8.GetBytes(keyString);
var token = tokenHandler.WriteToken(new JwtSecurityToken(
"issuer", "issuer", null,
expires: DateTime.UtcNow.AddMinutes(1),
signingCredentials: new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256)));
controller.Request.Headers["Authorization"] = $"Bearer {token}";
var result = await controller.Logout();
Assert.IsType<OkObjectResult>(result);
blacklist.Verify();
}
[Fact]
public async Task ChangeUserRole_InvalidRole_ReturnsBadRequest()
{
var svc = new Mock<UserService>(GetConfig());
var controller = new AuthController(svc.Object, GetConfig(), new Mock<BlacklistService>(GetConfig()).Object);
var result = await controller.ChangeUserRole(new ChangeRoleRequest { Username="u", NewRole="BAD" });
Assert.IsType<BadRequestObjectResult>(result);
}
[Fact]
public async Task GetAllUsers_ReturnsOk()
{
var users = new List<User>();
var svc = new Mock<UserService>(GetConfig());
svc.Setup(s => s.GetAllAsync()).ReturnsAsync(users);
var controller = new AuthController(svc.Object, GetConfig(), new Mock<BlacklistService>(GetConfig()).Object);
var result = await controller.GetAllUsers();
var ok = Assert.IsType<OkObjectResult>(result);
Assert.Equal(users, ok.Value);
}
}
@@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0" />
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="6.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GameAuthApi.csproj" />
</ItemGroup>
</Project>
+2
View File
@@ -0,0 +1,2 @@
global using Xunit;
global using Moq;
+27
View File
@@ -0,0 +1,27 @@
using GameAuthApi.Controllers;
using GameAuthApi.Models;
using GameAuthApi.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
public class ItemControllerTests
{
private static IConfiguration config = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string,string>
{
{"MongoDB:ConnectionString","mongodb://localhost"},
{"MongoDB:DatabaseName","test"}
}).Build();
[Fact]
public async Task Create_InvalidLocation_ReturnsBadRequest()
{
var loc = new Mock<LocationService>(config);
loc.Setup(l => l.GetByIdAsync("bad")).ReturnsAsync((Location?)null);
var controller = new ItemController(new Mock<ItemService>(config).Object, loc.Object);
var result = await controller.Create(new CreateItemRequest { LocationId = "bad", Name = "n" });
Assert.IsType<BadRequestObjectResult>(result);
}
}
@@ -0,0 +1,40 @@
using GameAuthApi.Controllers;
using GameAuthApi.Models;
using GameAuthApi.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
public class LocationControllerTests
{
private static IConfiguration config = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string,string>
{
{"MongoDB:ConnectionString","mongodb://localhost"},
{"MongoDB:DatabaseName","test"}
}).Build();
[Fact]
public async Task Create_ReturnsOk()
{
var mockLoc = new Mock<LocationService>(config);
mockLoc.Setup(l => l.CreateAsync(It.IsAny<Location>())).Returns(Task.CompletedTask).Verifiable();
var controller = new LocationController(mockLoc.Object, new Mock<PlayerService>(config).Object);
var result = await controller.Create(new CreateLocationRequest { X = 1, Y = 2, Z = 3 });
Assert.IsType<OkObjectResult>(result);
mockLoc.Verify();
}
[Fact]
public async Task GetById_NotFound()
{
var mockLoc = new Mock<LocationService>(config);
mockLoc.Setup(l => l.GetByIdAsync("id")).ReturnsAsync((Location?)null);
var controller = new LocationController(mockLoc.Object, new Mock<PlayerService>(config).Object);
var result = await controller.GetById("id");
Assert.IsType<NotFoundObjectResult>(result);
}
}
@@ -0,0 +1,93 @@
using GameAuthApi.Controllers;
using GameAuthApi.Models;
using GameAuthApi.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using System.Security.Claims;
public class PlayerControllerTests
{
private static IConfiguration cfg = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string,string>
{
{"MongoDB:ConnectionString","mongodb://localhost"},
{"MongoDB:DatabaseName","test"}
}).Build();
private static ControllerContext ContextWithUser(string id, string role="USER")
{
var ctx = new DefaultHttpContext();
ctx.User = new ClaimsPrincipal(new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.NameIdentifier, id),
new Claim(ClaimTypes.Role, role)
}, "mock"));
return new ControllerContext { HttpContext = ctx };
}
[Fact]
public async Task Create_ReturnsOk()
{
var playerService = new Mock<PlayerService>(cfg);
playerService.Setup(p => p.GetByUserIdAsync("u")).ReturnsAsync((Player?)null);
playerService.Setup(p => p.CreateAsync(It.IsAny<Player>())).Returns(Task.CompletedTask).Verifiable();
var locSvc = new Mock<LocationService>(cfg);
locSvc.Setup(l => l.GetSpawnLocationAsync()).ReturnsAsync((Location?)null);
locSvc.Setup(l => l.CreateAsync(It.IsAny<Location>())).Returns(Task.CompletedTask);
var controller = new PlayerController(playerService.Object, locSvc.Object, new Mock<SpawnableService>(cfg).Object, new Mock<ItemService>(cfg).Object)
{
ControllerContext = ContextWithUser("u")
};
var result = await controller.Create(new CreatePlayerRequest { Name = "p" });
Assert.IsType<OkObjectResult>(result);
playerService.Verify();
}
[Fact]
public async Task Delete_NotFound()
{
var playerService = new Mock<PlayerService>(cfg);
playerService.Setup(p => p.GetByUserIdAsync("u")).ReturnsAsync((Player?)null);
var controller = new PlayerController(playerService.Object, new Mock<LocationService>(cfg).Object, new Mock<SpawnableService>(cfg).Object, new Mock<ItemService>(cfg).Object)
{
ControllerContext = ContextWithUser("u")
};
var result = await controller.Delete();
Assert.IsType<NotFoundObjectResult>(result);
}
[Fact]
public async Task AdminTeleport_PlayerNotFound()
{
var playerService = new Mock<PlayerService>(cfg);
playerService.Setup(p => p.GetByIdAsync("p")).ReturnsAsync((Player?)null);
var controller = new PlayerController(playerService.Object, new Mock<LocationService>(cfg).Object, new Mock<SpawnableService>(cfg).Object, new Mock<ItemService>(cfg).Object)
{
ControllerContext = ContextWithUser("admin", "SUPER")
};
var result = await controller.AdminTeleport(new TeleportRequest { PlayerId = "p", LocationId = "l" });
Assert.IsType<NotFoundObjectResult>(result);
}
[Fact]
public async Task Move_PlayerNotFound()
{
var playerService = new Mock<PlayerService>(cfg);
playerService.Setup(p => p.GetByUserIdAsync("u")).ReturnsAsync((Player?)null);
var controller = new PlayerController(playerService.Object, new Mock<LocationService>(cfg).Object, new Mock<SpawnableService>(cfg).Object, new Mock<ItemService>(cfg).Object)
{
ControllerContext = ContextWithUser("u")
};
var result = await controller.Move(new MoveRequest { Direction = "N" });
Assert.IsType<NotFoundObjectResult>(result);
}
}
@@ -0,0 +1,42 @@
using GameAuthApi.Controllers;
using GameAuthApi.Models;
using GameAuthApi.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
public class SpawnableControllerTests
{
private static IConfiguration config = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string,string>
{
{"MongoDB:ConnectionString","mongodb://localhost"},
{"MongoDB:DatabaseName","test"}
}).Build();
[Fact]
public async Task Create_ReturnsOk()
{
var svc = new Mock<SpawnableService>(config);
svc.Setup(s => s.CreateAsync(It.IsAny<Spawnable>())).Returns(Task.CompletedTask).Verifiable();
var controller = new SpawnableController(svc.Object);
var result = await controller.Create(new CreateSpawnableRequest { Name = "item", SpawnRate = 50 });
Assert.IsType<OkObjectResult>(result);
svc.Verify();
}
[Fact]
public async Task GetAll_ReturnsOk()
{
var svc = new Mock<SpawnableService>(config);
var list = new List<Spawnable>();
svc.Setup(s => s.GetAllAsync()).ReturnsAsync(list);
var controller = new SpawnableController(svc.Object);
var result = await controller.GetAll();
var ok = Assert.IsType<OkObjectResult>(result);
Assert.Equal(list, ok.Value);
}
}
+46
View File
@@ -0,0 +1,46 @@
using GameAuthApi.Controllers;
using GameAuthApi.Models;
using GameAuthApi.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
public class UserControllerTests
{
[Fact]
public async Task GetAllUsers_ReturnsOk()
{
var users = new List<User>{ new User{ Username="u" } };
var config = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string,string>
{
{"MongoDB:ConnectionString","mongodb://localhost"},
{"MongoDB:DatabaseName","test"}
}).Build();
var mockService = new Mock<UserService>(config);
mockService.Setup(s => s.GetAllAsync()).ReturnsAsync(users);
var controller = new UserController(mockService.Object);
var result = await controller.GetAllUsers();
var ok = Assert.IsType<OkObjectResult>(result);
Assert.Equal(users, ok.Value);
}
[Fact]
public async Task DeleteUser_NotFound()
{
var config = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string,string>
{
{"MongoDB:ConnectionString","mongodb://localhost"},
{"MongoDB:DatabaseName","test"}
}).Build();
var mockService = new Mock<UserService>(config);
mockService.Setup(s => s.DeleteAsync("no")).ReturnsAsync(false);
var controller = new UserController(mockService.Object);
var result = await controller.DeleteUser("no");
Assert.IsType<NotFoundObjectResult>(result);
}
}