From cea087d5f07bf38ff02f812d0ddf230ba13856b5 Mon Sep 17 00:00:00 2001 From: Oliver Scott Date: Tue, 9 Jan 2024 10:25:06 +0000 Subject: [PATCH] VIH-10375 Return empty list instead of 500 error when no hearings exist (#2107) * Return empty list instead of 500 error when no hearings exist * Sonar warnings * Refactor --- .../GetConferencesForHostTests.cs | 19 ++++++- .../GetConferencesForIndividualTests.cs | 21 +++++++- .../GetConferencesForStaffMemberTests.cs | 21 ++++++++ .../GetConferencesForVHOfficerTests.cs | 38 +++++++++++++ .../Controllers/ConferencesController.cs | 53 +++++++++++-------- 5 files changed, 127 insertions(+), 25 deletions(-) diff --git a/VideoWeb/VideoWeb.UnitTests/Controllers/ConferenceController/GetConferencesForHostTests.cs b/VideoWeb/VideoWeb.UnitTests/Controllers/ConferenceController/GetConferencesForHostTests.cs index 6c2b18b205..e904e0d800 100644 --- a/VideoWeb/VideoWeb.UnitTests/Controllers/ConferenceController/GetConferencesForHostTests.cs +++ b/VideoWeb/VideoWeb.UnitTests/Controllers/ConferenceController/GetConferencesForHostTests.cs @@ -171,7 +171,7 @@ public async Task Should_return_forbidden_request() } [Test] - public async Task Should_return_exception() + public async Task Should_forward_error_when_video_api_returns_error() { var apiException = new VideoApiException("Internal Server Error", (int) HttpStatusCode.InternalServerError, @@ -184,5 +184,22 @@ public async Task Should_return_exception() var typedResult = result.Value; typedResult.Should().BeNull(); } + + [Test] + public async Task Should_forward_error_when_bookings_api_returns_error() + { + var apiException = new BookingsApiException("Internal Server Error", + (int)HttpStatusCode.InternalServerError, + "Stacktrace goes here", null, default, null); + + _mocker.Mock() + .Setup(x => x.GetConfirmedHearingsByUsernameForTodayAsync(It.IsAny())) + .ThrowsAsync(apiException); + + var result = await _controller.GetConferencesForHostAsync(); + + var typedResult = (ObjectResult)result.Result; + typedResult.StatusCode.Should().Be((int)HttpStatusCode.InternalServerError); + } } } diff --git a/VideoWeb/VideoWeb.UnitTests/Controllers/ConferenceController/GetConferencesForIndividualTests.cs b/VideoWeb/VideoWeb.UnitTests/Controllers/ConferenceController/GetConferencesForIndividualTests.cs index c8ce310bfe..702972ddf9 100644 --- a/VideoWeb/VideoWeb.UnitTests/Controllers/ConferenceController/GetConferencesForIndividualTests.cs +++ b/VideoWeb/VideoWeb.UnitTests/Controllers/ConferenceController/GetConferencesForIndividualTests.cs @@ -62,7 +62,7 @@ public void Setup() _sut = _mocker.Create(); _sut.ControllerContext = context; } - + [Test] public async Task Should_return_ok_with_list_of_conferences_for_quickLink_user() { @@ -181,7 +181,7 @@ public async Task Should_return_forbidden_request() } [Test] - public async Task Should_return_exception() + public async Task Should_forward_error_when_video_api_returns_error() { var apiException = new VideoApiException("Internal Server Error", (int)HttpStatusCode.InternalServerError, "Stacktrace goes here", null, default, null); @@ -193,5 +193,22 @@ public async Task Should_return_exception() var typedResult = result.Value; typedResult.Should().BeNull(); } + + [Test] + public async Task Should_forward_error_when_bookings_api_returns_error() + { + var apiException = new BookingsApiException("Internal Server Error", + (int)HttpStatusCode.InternalServerError, + "Stacktrace goes here", null, default, null); + + _mocker.Mock() + .Setup(x => x.GetConfirmedHearingsByUsernameForTodayAsync(It.IsAny())) + .ThrowsAsync(apiException); + + var result = await _sut.GetConferencesForIndividual(); + + var typedResult = (ObjectResult)result.Result; + typedResult.StatusCode.Should().Be((int)HttpStatusCode.InternalServerError); + } } } diff --git a/VideoWeb/VideoWeb.UnitTests/Controllers/ConferenceController/GetConferencesForStaffMemberTests.cs b/VideoWeb/VideoWeb.UnitTests/Controllers/ConferenceController/GetConferencesForStaffMemberTests.cs index 13b3f17e08..0fa2de6f89 100644 --- a/VideoWeb/VideoWeb.UnitTests/Controllers/ConferenceController/GetConferencesForStaffMemberTests.cs +++ b/VideoWeb/VideoWeb.UnitTests/Controllers/ConferenceController/GetConferencesForStaffMemberTests.cs @@ -60,6 +60,23 @@ public async Task Should_forward_error_when_video_api_returns_error() var typedResult = (ObjectResult)result.Result; typedResult.StatusCode.Should().Be((int)HttpStatusCode.InternalServerError); } + + [Test] + public async Task Should_forward_error_when_bookings_api_returns_error() + { + var apiException = new BookingsApiException("Internal Server Error", + (int)HttpStatusCode.InternalServerError, + "Stacktrace goes here", null, default, null); + + _mocker.Mock() + .Setup(x => x.GetHearingsForTodayByVenueAsync(It.IsAny>())) + .ThrowsAsync(apiException); + + var result = await _controller.GetConferencesForStaffMemberAsync(new List()); + + var typedResult = (ObjectResult)result.Result; + typedResult.StatusCode.Should().Be((int)HttpStatusCode.InternalServerError); + } [Test] public async Task Should_return_ok_with_list_of_conferences() @@ -103,9 +120,13 @@ public async Task Should_return_ok_with_no_conferences() { var hearingVenueNamesQuery = new List(); var conferences = new List(); + var bookingException = new BookingsApiException("User does not have any hearings", (int)HttpStatusCode.NotFound, "Error", null, null); _mocker.Mock() .Setup(x => x.GetConferencesForHostByHearingRefIdAsync(It.IsAny())) .ReturnsAsync(conferences); + _mocker.Mock() + .Setup(x => x.GetHearingsForTodayByVenueAsync(It.IsAny>())) + .ThrowsAsync(bookingException); var result = await _controller.GetConferencesForStaffMemberAsync(hearingVenueNamesQuery); diff --git a/VideoWeb/VideoWeb.UnitTests/Controllers/ConferenceController/GetConferencesForVHOfficerTests.cs b/VideoWeb/VideoWeb.UnitTests/Controllers/ConferenceController/GetConferencesForVHOfficerTests.cs index bbdb1c885f..ffaf5b3873 100644 --- a/VideoWeb/VideoWeb.UnitTests/Controllers/ConferenceController/GetConferencesForVHOfficerTests.cs +++ b/VideoWeb/VideoWeb.UnitTests/Controllers/ConferenceController/GetConferencesForVHOfficerTests.cs @@ -61,6 +61,23 @@ public async Task Should_forward_error_when_video_api_returns_error() var typedResult = (ObjectResult) result.Result; typedResult.StatusCode.Should().Be((int) HttpStatusCode.InternalServerError); } + + [Test] + public async Task Should_forward_error_when_bookings_api_returns_error() + { + var apiException = new BookingsApiException("Internal Server Error", + (int)HttpStatusCode.InternalServerError, + "Stacktrace goes here", null, default, null); + + _mocker.Mock() + .Setup(x => x.GetHearingsForTodayByVenueAsync(It.IsAny>())) + .ThrowsAsync(apiException); + + var result = await _controller.GetConferencesForVhOfficerAsync(new VhoConferenceFilterQuery()); + + var typedResult = (ObjectResult)result.Result; + typedResult.StatusCode.Should().Be((int)HttpStatusCode.InternalServerError); + } [Test] @@ -351,6 +368,27 @@ public async Task Should_return_ok_with_list_of_conferences_when_querying_by_cso conferencesForUser.Count.Should().Be(1); conferencesForUser[0].HearingRefId.Should().Be(unallocatedHearing.HearingId); } + + [Test] + public async Task Should_return_ok_with_no_conferences() + { + var conferences = new List(); + var bookingException = new BookingsApiException("User does not have any hearings", (int)HttpStatusCode.NotFound, "Error", null, null); + _mocker.Mock() + .Setup(x => x.GetConferencesForAdminByHearingRefIdAsync(It.IsAny())) + .ReturnsAsync(conferences); + _mocker.Mock() + .Setup(x => x.GetHearingsForTodayByVenueAsync(It.IsAny>())) + .ThrowsAsync(bookingException); + + var result = await _controller.GetConferencesForVhOfficerAsync(new VhoConferenceFilterQuery()); + + var typedResult = (OkObjectResult)result.Result; + typedResult.Should().NotBeNull(); + + var conferencesForUser = (List)typedResult.Value; + conferencesForUser.Should().BeEmpty(); + } private ConferencesController SetupControllerWithClaims(ClaimsPrincipal claimsPrincipal) { diff --git a/VideoWeb/VideoWeb/Controllers/ConferencesController.cs b/VideoWeb/VideoWeb/Controllers/ConferencesController.cs index e198dc8e06..2257017809 100644 --- a/VideoWeb/VideoWeb/Controllers/ConferencesController.cs +++ b/VideoWeb/VideoWeb/Controllers/ConferencesController.cs @@ -80,18 +80,11 @@ public async Task>> GetConferencesF } catch (BookingsApiException e) { - if (e.StatusCode == (int)HttpStatusCode.NotFound) - { - _logger.LogWarning("No hearings found for user"); - return Ok(new List()); - } - - throw; + return HandleBookingsApiExceptionForGetHearings(e); } catch (VideoApiException e) { - _logger.LogError(e, "Unable to get conferences for user"); - return StatusCode(e.StatusCode, e.Response); + return HandleVideoApiExceptionForGetConferences(e); } } @@ -119,10 +112,13 @@ public async Task>> GetConferencesF .ToList(); return Ok(response); } + catch (BookingsApiException e) + { + return HandleBookingsApiExceptionForGetHearings(e); + } catch (VideoApiException e) { - _logger.LogError(e, "Unable to get conferences for staff member"); - return StatusCode(e.StatusCode, e.Response); + return HandleVideoApiExceptionForGetConferences(e); } } @@ -166,18 +162,11 @@ public async Task>> GetConfer } catch (BookingsApiException e) { - if (e.StatusCode == (int)HttpStatusCode.NotFound) - { - _logger.LogWarning("No hearings found for user"); - return Ok(new List()); - } - - throw; + return HandleBookingsApiExceptionForGetHearings(e); } catch (VideoApiException e) { - _logger.LogError(e, "Unable to get conferences for user"); - return StatusCode(e.StatusCode, e.Response); + return HandleVideoApiExceptionForGetConferences(e); } } @@ -222,10 +211,13 @@ public async Task>> GetConfere responses.Sort(new SortConferenceForVhoOfficerHelper()); return Ok(responses); } + catch (BookingsApiException e) + { + return HandleBookingsApiExceptionForGetHearings(e); + } catch (VideoApiException e) { - _logger.LogError(e, "Unable to get conferences for vh officer"); - return StatusCode(e.StatusCode, e.Response); + return HandleVideoApiExceptionForGetConferences(e); } } @@ -379,5 +371,22 @@ public async Task> GetConferenceByIdAsync(Guid return Ok(response); } + + private ActionResult HandleBookingsApiExceptionForGetHearings(BookingsApiException e) where T : class + { + if (e.StatusCode == (int)HttpStatusCode.NotFound) + { + _logger.LogWarning("No hearings found for user"); + return Ok(new List()); + } + + return StatusCode(e.StatusCode, e.Response); + } + + private ActionResult HandleVideoApiExceptionForGetConferences(VideoApiException e) + { + _logger.LogError(e, "Unable to get conferences for user"); + return StatusCode(e.StatusCode, e.Response); + } } }