public static ProblemDetails ShouldNotBeNull(this ProblemDetails problemDetails, HttpStatusCode statusCode) { problemDetails.Should().NotBeNull(); problemDetails.Status.Should().Be((int)statusCode); problemDetails.Title.Should().NotBeNull(); problemDetails.Detail.Should().NotBeNull(); problemDetails.Type.Should().NotBeNull(); return(problemDetails); }
public static ProblemDetails ShouldNotBeNull(this ProblemDetails problemDetails, HttpStatusCode statusCode) { _ = problemDetails ?? throw new ArgumentNullException(nameof(problemDetails)); problemDetails.Should().NotBeNull(); problemDetails.Status.Should().Be((int)statusCode); problemDetails.Title.Should().NotBeNull(); problemDetails.Detail.Should().NotBeNull(); problemDetails.Type.Should().NotBeNull(); return(problemDetails); }
public async Task HandleException_WhenApiThrowsException_MustConvertExceptionToInstanceOfProblemDetailsClass() { // Arrange var generateJwtModel = new GenerateJwtModel { UserName = $"test-user--{Guid.NewGuid():N}", Password = $"test-password--{Guid.NewGuid():N}", }; using var testWebApplicationFactory = new TestWebApplicationFactory(MethodBase.GetCurrentMethod()?.DeclaringType?.Name) .WithMockServices(containerBuilder => { // Ensure a mock implementation will be injected whenever a service requires an instance of the // IGenerateJwtFlow interface. containerBuilder .RegisterType <GenerateJwtFlowWhichThrowsException>() .As <IGenerateJwtFlow>() .InstancePerLifetimeScope(); }) .WithWebHostBuilder(webHostBuilder => { webHostBuilder.ConfigureAppConfiguration(configurationBuilder => { configurationBuilder.AddInMemoryCollection(new[] { // Ensure database is not migrated, since having an up-to-date RDBMS will just complicate // this test method. new KeyValuePair <string, string>("MigrateDatabase", bool.FalseString) }); }); }); using HttpClient httpClient = testWebApplicationFactory.CreateClient(); // Act HttpResponseMessage httpResponseMessage = await httpClient.PostAsJsonAsync("api/jwt", generateJwtModel); // Assert using (new AssertionScope()) { const HttpStatusCode expectedStatusCode = HttpStatusCode.InternalServerError; httpResponseMessage.IsSuccessStatusCode .Should().BeFalse("the endpoint was supposed to throw a hard-coded exception"); httpResponseMessage.StatusCode.Should().Be(expectedStatusCode, $"the hard-coded exception was mapped to HTTP status {expectedStatusCode}"); byte[] problemDetailsAsBytes = await httpResponseMessage.Content.ReadAsByteArrayAsync(); await using var memoryStream = new MemoryStream(problemDetailsAsBytes); // Must use System.Text.Json.JsonSerializer instead of Newtonsoft.Json.JsonSerializer to ensure // ProblemDetails.Extensions property is correctly deserialized and does not end up as an empty // dictionary. ProblemDetails problemDetails = await JsonSerializer.DeserializeAsync <ProblemDetails>(memoryStream); problemDetails.Should().NotBeNull("application must handle any exception"); // ReSharper disable once PossibleNullReferenceException problemDetails.Extensions.Should().NotBeNull("problem details must contain extra info"); problemDetails.Extensions.Should().NotContainKey("errorData", "error data must not be present"); problemDetails.Extensions.Should().ContainKey("errorKey", "error key must be present"); problemDetails.Extensions.Should().ContainKey("errorId", "error id must be present"); Guid.TryParse(problemDetails.Extensions["errorId"].ToString(), out Guid _) .Should().BeTrue("error id is a GUID"); } }