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.
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user