profileShare

rasmusjy / splitapp-backend-microservices

Read-only snapshot

No repository description.

main default branch 501 files Expires Sep 13, 2026, 9:06 AM
HostFeatureTests.cs 3,286 bytes
1 using System.Net;
2 using Microsoft.AspNetCore.Hosting;
3 using Microsoft.AspNetCore.Mvc.Testing;
4
5 namespace SplitApp.WebApp.IntegrationTests;
6
7 /// <summary>
8 /// End-to-end host checks that exercise the cross-cutting requirements:
9 /// Swagger generation, Admin area protection, JWT requirement on a second
10 /// module's controller, and request-localization wiring.
11 /// </summary>
12 public class HostFeatureTests : IClassFixture<WebApplicationFactory<Program>>
13 {
14 private readonly WebApplicationFactory<Program> _factory;
15
16 public HostFeatureTests(WebApplicationFactory<Program> factory)
17 {
18 _factory = factory.WithWebHostBuilder(b =>
19 {
20 b.UseEnvironment("Testing");
21 b.UseSetting("ConnectionStrings:DefaultConnection", "Host=ignored;Database=ignored");
22 b.UseSetting("JWT:Issuer", "splitapp-test");
23 b.UseSetting("JWT:Audience", "splitapp-test");
24 b.UseSetting("JWT:Key", "this-is-a-long-enough-test-signing-key-for-hs256");
25 });
26 }
27
28 [Fact]
29 public async Task Get_SwaggerV1Json_ReturnsOpenApiDocument()
30 {
31 var client = _factory.CreateClient();
32 var response = await client.GetAsync("/swagger/v1/swagger.json");
33 Assert.Equal(HttpStatusCode.OK, response.StatusCode);
34
35 var body = await response.Content.ReadAsStringAsync();
36 Assert.Contains("\"openapi\"", body);
37 Assert.Contains("/api/v1/Trips", body);
38 }
39
40 [Fact]
41 public async Task Get_SwaggerUi_ReturnsOk()
42 {
43 var client = _factory.CreateClient();
44 var response = await client.GetAsync("/swagger/index.html");
45 Assert.Equal(HttpStatusCode.OK, response.StatusCode);
46 }
47
48 [Fact]
49 public async Task Get_AdminArea_BlocksUnauthenticatedUser()
50 {
51 // Phase 4: JWT bearer is the only auth scheme. Unauthenticated requests get 401,
52 // not a redirect — the MVC AccountController at /Account/Login is opt-in (the SPA
53 // login flow uses an HttpOnly cookie, but unauthenticated MVC navigations are not
54 // automatically redirected to a login page anymore).
55 var client = _factory.CreateClient(new WebApplicationFactoryClientOptions
56 {
57 AllowAutoRedirect = false,
58 });
59 var response = await client.GetAsync("/Admin/Trips");
60
61 Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
62 }
63
64 [Fact]
65 public async Task Get_ExpensesApi_RequiresAuth()
66 {
67 var client = _factory.CreateClient(new WebApplicationFactoryClientOptions
68 {
69 AllowAutoRedirect = false,
70 });
71 var response = await client.GetAsync($"/api/v1/expenses/trip/{Guid.NewGuid()}");
72 Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
73 }
74
75 [Fact]
76 public async Task Get_Home_WithEtCultureQuery_ReturnsOk()
77 {
78 var client = _factory.CreateClient();
79 var response = await client.GetAsync("/?culture=et&ui-culture=et");
80 Assert.Equal(HttpStatusCode.OK, response.StatusCode);
81
82 // RequestLocalization should accept "et" as a supported culture
83 // without throwing or falling back to a 4xx/5xx.
84 var body = await response.Content.ReadAsStringAsync();
85 Assert.Contains("SplitApp", body);
86 }
87 }
88