|
- using System.Net;
- using Microsoft.AspNetCore.Mvc.Testing;
-
- namespace CartWise.Web.Tests;
-
- public class PurchaseAccessControlTests : IClassFixture<CartWiseWebApplicationFactory>
- {
- private readonly CartWiseWebApplicationFactory _factory;
-
- public PurchaseAccessControlTests(CartWiseWebApplicationFactory factory)
- {
- _factory = factory;
- }
-
- [Fact]
- public async Task AnonymousUser_IsRedirectedToLoginWhenRequestingPurchases()
- {
- var client = _factory.CreateClient(new WebApplicationFactoryClientOptions { AllowAutoRedirect = false });
-
- var response = await client.GetAsync("/purchases");
-
- Assert.Equal(HttpStatusCode.Redirect, response.StatusCode);
- Assert.Contains("/Account/Login", response.Headers.Location?.ToString());
- }
-
- [Fact]
- public async Task RecordPurchase_FullFlow_AddsItemAndCompletes()
- {
- var client = _factory.CreateClient();
- await WebTestHelpers.RegisterAsync(client, "purchaseflow1@example.com", "Purchase Flow User");
- await WebTestHelpers.CreateHouseholdAsync(client, "Purchase Flow Household");
-
- var indexHtml = await client.GetStringAsync("/purchases");
- var startToken = WebTestHelpers.ExtractAntiForgeryToken(indexHtml);
- var startResponse = await client.PostAsync("/purchases/start", new FormUrlEncodedContent(new Dictionary<string, string>
- {
- ["__RequestVerificationToken"] = startToken
- }));
- startResponse.EnsureSuccessStatusCode();
- var purchaseUrl = startResponse.RequestMessage!.RequestUri!.AbsolutePath;
-
- var detailHtml = await client.GetStringAsync(purchaseUrl);
- HtmlAssert.Contains("In progress", detailHtml);
- var itemToken = WebTestHelpers.ExtractAntiForgeryToken(detailHtml);
-
- var addItemResponse = await client.PostAsync($"{purchaseUrl}/items", new FormUrlEncodedContent(new Dictionary<string, string>
- {
- ["__RequestVerificationToken"] = itemToken,
- ["NewItem.Description"] = "Milk",
- ["NewItem.Quantity"] = "2",
- ["NewItem.Unit"] = "gal",
- ["NewItem.LinePrice"] = "7.98"
- }));
- addItemResponse.EnsureSuccessStatusCode();
-
- var afterAddHtml = await addItemResponse.Content.ReadAsStringAsync();
- HtmlAssert.Contains("Milk", afterAddHtml);
-
- var completeToken = WebTestHelpers.ExtractAntiForgeryToken(afterAddHtml);
- var completeResponse = await client.PostAsync($"{purchaseUrl}/complete", new FormUrlEncodedContent(new Dictionary<string, string>
- {
- ["__RequestVerificationToken"] = completeToken
- }));
- completeResponse.EnsureSuccessStatusCode();
-
- var finalHtml = await completeResponse.Content.ReadAsStringAsync();
- HtmlAssert.Contains("Completed", finalHtml);
- HtmlAssert.Contains("$7.98", finalHtml);
- }
-
- [Fact]
- public async Task EachHousehold_OnlySeesItsOwnPurchases()
- {
- var clientA = _factory.CreateClient();
- var clientB = _factory.CreateClient();
- await WebTestHelpers.RegisterAsync(clientA, "purchasealice@example.com", "Purchase Alice");
- await WebTestHelpers.RegisterAsync(clientB, "purchasebob@example.com", "Purchase Bob");
- await WebTestHelpers.CreateHouseholdAsync(clientA, "Purchase Household A");
- await WebTestHelpers.CreateHouseholdAsync(clientB, "Purchase Household B");
-
- var indexA = await clientA.GetStringAsync("/purchases");
- var tokenA = WebTestHelpers.ExtractAntiForgeryToken(indexA);
- var startResponseA = await clientA.PostAsync("/purchases/start", new FormUrlEncodedContent(new Dictionary<string, string>
- {
- ["__RequestVerificationToken"] = tokenA
- }));
- var purchaseUrlA = startResponseA.RequestMessage!.RequestUri!.AbsolutePath;
- var purchaseIdA = purchaseUrlA.Split('/').Last();
-
- var response = await clientB.GetAsync($"/purchases/{purchaseIdA}");
-
- Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
- }
- }
|