using System.Net.Http.Json; using BigRegister.Api.Contracts; using Microsoft.AspNetCore.Mvc.Testing; namespace BigRegister.Tests; public class IdempotencyTests(TestWebApplicationFactory factory) : IClassFixture { private readonly HttpClient _client = factory.CreateClient(); private static HttpRequestMessage ChangeRequestWithKey(string key) { var req = new HttpRequestMessage(HttpMethod.Post, "/api/v1/change-requests") { Content = JsonContent.Create(new { straat = "Lange Voorhout 9", postcode = "2514 EA", woonplaats = "Den Haag" }), }; req.Headers.Add("Idempotency-Key", key); return req; } [Fact] public async Task Replaying_the_same_idempotency_key_returns_the_same_reference_not_a_new_one() { var key = Guid.NewGuid().ToString(); var first = await _client.SendAsync(ChangeRequestWithKey(key)); first.EnsureSuccessStatusCode(); var firstBody = await first.Content.ReadFromJsonAsync(); var replay = await _client.SendAsync(ChangeRequestWithKey(key)); replay.EnsureSuccessStatusCode(); var replayBody = await replay.Content.ReadFromJsonAsync(); Assert.Equal(firstBody!.Referentie, replayBody!.Referentie); } [Fact] public async Task Different_idempotency_keys_are_independent_submissions() { var first = await _client.SendAsync(ChangeRequestWithKey(Guid.NewGuid().ToString())); var second = await _client.SendAsync(ChangeRequestWithKey(Guid.NewGuid().ToString())); var firstBody = await first.Content.ReadFromJsonAsync(); var secondBody = await second.Content.ReadFromJsonAsync(); Assert.NotEqual(firstBody!.Referentie, secondBody!.Referentie); } [Fact] public async Task A_rejected_submission_replays_the_same_rejection_not_a_retry() { var key = Guid.NewGuid().ToString(); var badRequest = new HttpRequestMessage(HttpMethod.Post, "/api/v1/change-requests") { Content = JsonContent.Create(new { straat = "Straat 1", postcode = "nope", woonplaats = "Den Haag" }), }; badRequest.Headers.Add("Idempotency-Key", key); var first = await _client.SendAsync(badRequest); Assert.Equal(System.Net.HttpStatusCode.UnprocessableEntity, first.StatusCode); var replayRequest = new HttpRequestMessage(HttpMethod.Post, "/api/v1/change-requests") { Content = JsonContent.Create(new { straat = "Straat 1", postcode = "nope", woonplaats = "Den Haag" }), }; replayRequest.Headers.Add("Idempotency-Key", key); var replay = await _client.SendAsync(replayRequest); Assert.Equal(System.Net.HttpStatusCode.UnprocessableEntity, replay.StatusCode); } }