Files
jdescopingtool/NEW/tests/JdeScoping.Api.IntegrationTests/AuthenticationTests.cs
T
Joseph Doherty 26ff8d9b4f Initial commit: JDE Scoping Tool migration project
Set up repository with legacy .NET Framework 4.8 source (OLD/),
new .NET 10 Blazor solution (NEW/), OpenSpec specifications,
documentation, and project configuration.
2026-01-02 07:43:29 -05:00

113 lines
4.4 KiB
C#

using System.Net;
using System.Net.Http.Json;
using JdeScoping.Api.Models;
using JdeScoping.Core.Models;
using Microsoft.AspNetCore.Mvc.Testing;
using Shouldly;
namespace JdeScoping.Api.IntegrationTests;
/// <summary>
/// Integration tests for authentication flow.
/// Note: These tests require a running test server with UseFakeAuth=true
/// </summary>
public class AuthenticationTests : IClassFixture<TestWebApplicationFactory>
{
private readonly TestWebApplicationFactory _factory;
private readonly HttpClient _client;
public AuthenticationTests(TestWebApplicationFactory factory)
{
_factory = factory;
_client = factory.CreateClient(new WebApplicationFactoryClientOptions
{
HandleCookies = true,
AllowAutoRedirect = false
});
}
[Fact]
public async Task FullLoginLogoutFlow_WithCookies()
{
// Step 1: Login
var loginRequest = new LoginRequest { Username = "testuser", Password = "testpass" };
var loginResponse = await _client.PostAsJsonAsync("/api/auth/login", loginRequest);
loginResponse.StatusCode.ShouldBe(HttpStatusCode.OK);
var user = await loginResponse.Content.ReadFromJsonAsync<UserInfo>();
user.ShouldNotBeNull();
user.Username.ShouldBe("testuser");
// Step 2: Verify we can access protected endpoint
var meResponse = await _client.GetAsync("/api/auth/me");
meResponse.StatusCode.ShouldBe(HttpStatusCode.OK);
var meUser = await meResponse.Content.ReadFromJsonAsync<UserInfo>();
meUser.ShouldNotBeNull();
meUser.Username.ShouldBe("testuser");
// Step 3: Logout
var logoutResponse = await _client.PostAsync("/api/auth/logout", null);
logoutResponse.StatusCode.ShouldBe(HttpStatusCode.OK);
// Step 4: Verify protected endpoint returns 401 after logout
var afterLogoutResponse = await _client.GetAsync("/api/auth/me");
afterLogoutResponse.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
}
[Fact]
public async Task ProtectedEndpoints_Return401_WithoutAuth()
{
// Use a fresh client without cookies (using factory to connect to test server)
var freshClient = _factory.CreateClient(new WebApplicationFactoryClientOptions
{
HandleCookies = false,
AllowAutoRedirect = false
});
// Search endpoints require auth
var searchResponse = await freshClient.GetAsync("/api/search");
searchResponse.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
// Auth me endpoint requires auth
var meResponse = await freshClient.GetAsync("/api/auth/me");
meResponse.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
}
[Fact]
public async Task ProtectedEndpoints_Work_WithAuthCookie()
{
// Login first
var loginRequest = new LoginRequest { Username = "testuser", Password = "testpass" };
var loginResponse = await _client.PostAsJsonAsync("/api/auth/login", loginRequest);
loginResponse.StatusCode.ShouldBe(HttpStatusCode.OK);
// Now search endpoint should work
var searchResponse = await _client.GetAsync("/api/search");
searchResponse.StatusCode.ShouldBe(HttpStatusCode.OK);
}
[Fact]
public async Task LookupEndpoints_DoNotRequireAuth()
{
// Use a fresh client without cookies (using factory to connect to test server)
var freshClient = _factory.CreateClient(new WebApplicationFactoryClientOptions
{
HandleCookies = false,
AllowAutoRedirect = false
});
// Lookup endpoints should work without auth
var itemsResponse = await freshClient.GetAsync("/api/lookup/items?q=test");
itemsResponse.StatusCode.ShouldBe(HttpStatusCode.OK);
var profitCentersResponse = await freshClient.GetAsync("/api/lookup/profit-centers?q=test");
profitCentersResponse.StatusCode.ShouldBe(HttpStatusCode.OK);
var workCentersResponse = await freshClient.GetAsync("/api/lookup/work-centers?q=test");
workCentersResponse.StatusCode.ShouldBe(HttpStatusCode.OK);
var operatorsResponse = await freshClient.GetAsync("/api/lookup/operators?q=test");
operatorsResponse.StatusCode.ShouldBe(HttpStatusCode.OK);
}
}