108 lines
3.9 KiB
C#
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))!;
|
|
}
|
|
}
|