VanguardReMaster/server/tests/Vanguard.Server.Tests/AuthTests.cs

108 lines
3.9 KiB
C#

using System.Net;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
using Microsoft.AspNetCore.Mvc.Testing;
using Vanguard.Server.Auth;
using Xunit.Sdk;
namespace Vanguard.Server.Tests;
public class AuthTests
{
private static readonly JsonSerializerOptions Json = new(JsonSerializerDefaults.Web);
[Fact]
public async Task Register_Login_Refresh_Rotation_Logout()
{
using var factory = new WebApplicationFactory<Program>();
using var http = factory.CreateClient();
var userName = "user" + Guid.NewGuid().ToString("N")[..8];
var registered = await RegisterAsync(http, userName);
Assert.False(registered.OnboardingCompleted);
using var authed = factory.CreateClient();
authed.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", registered.AccessToken);
var me = await authed.GetFromJsonAsync<MeResponse>("/api/auth/me", Json);
Assert.NotNull(me);
Assert.Equal(userName, me!.UserName);
Assert.Equal(0, me.Gold);
Assert.Equal(0, me.Tokens);
var loginResponse = await http.PostAsJsonAsync(
"/api/auth/login",
new { userName, password = "password123" },
Json);
loginResponse.EnsureSuccessStatusCode();
var login = (await loginResponse.Content.ReadFromJsonAsync<AuthResponse>(Json))!;
var refreshResponse = await http.PostAsJsonAsync(
"/api/auth/refresh",
new { refreshToken = login.RefreshToken },
Json);
refreshResponse.EnsureSuccessStatusCode();
var refreshed = (await refreshResponse.Content.ReadFromJsonAsync<AuthResponse>(Json))!;
Assert.NotEqual(login.RefreshToken, refreshed.RefreshToken);
Assert.NotEqual(login.AccessToken, refreshed.AccessToken);
// старый refresh после ротации больше не действует
var reused = await http.PostAsJsonAsync(
"/api/auth/refresh",
new { refreshToken = login.RefreshToken },
Json);
Assert.Equal(HttpStatusCode.Unauthorized, reused.StatusCode);
var logout = await http.PostAsJsonAsync(
"/api/auth/logout",
new { refreshToken = refreshed.RefreshToken },
Json);
Assert.Equal(HttpStatusCode.NoContent, logout.StatusCode);
var afterLogout = await http.PostAsJsonAsync(
"/api/auth/refresh",
new { refreshToken = refreshed.RefreshToken },
Json);
Assert.Equal(HttpStatusCode.Unauthorized, afterLogout.StatusCode);
}
[Fact]
public async Task Weak_Password_And_Duplicate_User_Are_Rejected()
{
using var factory = new WebApplicationFactory<Program>();
using var http = factory.CreateClient();
var userName = "weak" + Guid.NewGuid().ToString("N")[..8];
var weak = await http.PostAsJsonAsync(
"/api/auth/register",
new { userName, password = "123" },
Json);
Assert.Equal(HttpStatusCode.BadRequest, weak.StatusCode);
var first = await RegisterAsync(http, userName);
Assert.NotNull(first.AccessToken);
var duplicate = await http.PostAsJsonAsync(
"/api/auth/register",
new { userName, password = "password123" },
Json);
Assert.Equal(HttpStatusCode.Conflict, duplicate.StatusCode);
}
private static async Task<AuthResponse> RegisterAsync(HttpClient http, string userName)
{
var response = await http.PostAsJsonAsync(
"/api/auth/register",
new { userName, password = "password123" },
Json);
if (!response.IsSuccessStatusCode)
throw new XunitException(await response.Content.ReadAsStringAsync());
return (await response.Content.ReadFromJsonAsync<AuthResponse>(Json))!;
}
}