Adding unit tests
This commit is contained in:
@@ -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>
|
||||
@@ -0,0 +1,2 @@
|
||||
global using Xunit;
|
||||
global using Moq;
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user