Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VIH-10376 new users are being booked on hearings but do not have a hearing today #629

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions VideoApi/Testing.Common/Helper/ApiUriFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public static class ConferenceEndpoints
public static string GetExpiredOpenConferences => $"{ApiRoot}/expired";
public static string GetConferenceDetailsById(Guid conferenceId) => $"{ApiRoot}/{conferenceId}";
public static string GetConferencesForHostByHearingRefId() => $"{ApiRoot}/hearings/host";
public static string GetConferencesForIndividualByHearingRefId() => $"{ApiRoot}/hearings/individual";
public static string GetConferencesForAdminByHearingRefId() => $"{ApiRoot}/hearings/staff-member";
public static string GetConferenceByHearingRefId(Guid hearingRefId) => $"{ApiRoot}/hearings/{hearingRefId}";
public static string RemoveConference(Guid conferenceId) => $"{ApiRoot}/{conferenceId}";
Expand Down
140 changes: 140 additions & 0 deletions VideoApi/VideoApi.Client/VideoApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ public partial interface IVideoApiClient
/// <param name="username">person username</param>
/// <returns>List of non-closed conferences for judge</returns>
/// <exception cref="VideoApiException">A server side error occurred.</exception>
[System.Obsolete]
System.Threading.Tasks.Task<System.Collections.Generic.ICollection<ConferenceForIndividualResponse>> GetConferencesTodayForIndividualByUsernameAsync(string username);

/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
Expand All @@ -324,6 +325,7 @@ public partial interface IVideoApiClient
/// <param name="username">person username</param>
/// <returns>List of non-closed conferences for judge</returns>
/// <exception cref="VideoApiException">A server side error occurred.</exception>
[System.Obsolete]
System.Threading.Tasks.Task<System.Collections.Generic.ICollection<ConferenceForIndividualResponse>> GetConferencesTodayForIndividualByUsernameAsync(string username, System.Threading.CancellationToken cancellationToken);

/// <summary>
Expand Down Expand Up @@ -379,6 +381,23 @@ public partial interface IVideoApiClient
/// <exception cref="VideoApiException">A server side error occurred.</exception>
System.Threading.Tasks.Task<System.Collections.Generic.ICollection<ConferenceForHostResponse>> GetConferencesForHostByHearingRefIdAsync(GetConferencesByHearingIdsRequest request, System.Threading.CancellationToken cancellationToken);

/// <summary>
/// Get conferences by hearing ref id
/// </summary>
/// <param name="request">Hearing ref IDs</param>
/// <returns>Full details including participants and statuses of a conference</returns>
/// <exception cref="VideoApiException">A server side error occurred.</exception>
System.Threading.Tasks.Task<System.Collections.Generic.ICollection<ConferenceForIndividualResponse>> GetConferencesForIndividualByHearingRefIdAsync(GetConferencesByHearingIdsRequest request);

/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <summary>
/// Get conferences by hearing ref id
/// </summary>
/// <param name="request">Hearing ref IDs</param>
/// <returns>Full details including participants and statuses of a conference</returns>
/// <exception cref="VideoApiException">A server side error occurred.</exception>
System.Threading.Tasks.Task<System.Collections.Generic.ICollection<ConferenceForIndividualResponse>> GetConferencesForIndividualByHearingRefIdAsync(GetConferencesByHearingIdsRequest request, System.Threading.CancellationToken cancellationToken);

/// <summary>
/// Get list of expired conferences
/// </summary>
Expand Down Expand Up @@ -2990,6 +3009,7 @@ public virtual async System.Threading.Tasks.Task RemoveConferenceAsync(System.Gu
/// <param name="username">person username</param>
/// <returns>List of non-closed conferences for judge</returns>
/// <exception cref="VideoApiException">A server side error occurred.</exception>
[System.Obsolete]
public virtual System.Threading.Tasks.Task<System.Collections.Generic.ICollection<ConferenceForIndividualResponse>> GetConferencesTodayForIndividualByUsernameAsync(string username)
{
return GetConferencesTodayForIndividualByUsernameAsync(username, System.Threading.CancellationToken.None);
Expand All @@ -3002,6 +3022,7 @@ public virtual async System.Threading.Tasks.Task RemoveConferenceAsync(System.Gu
/// <param name="username">person username</param>
/// <returns>List of non-closed conferences for judge</returns>
/// <exception cref="VideoApiException">A server side error occurred.</exception>
[System.Obsolete]
public virtual async System.Threading.Tasks.Task<System.Collections.Generic.ICollection<ConferenceForIndividualResponse>> GetConferencesTodayForIndividualByUsernameAsync(string username, System.Threading.CancellationToken cancellationToken)
{
var urlBuilder_ = new System.Text.StringBuilder();
Expand Down Expand Up @@ -3452,6 +3473,125 @@ public virtual async System.Threading.Tasks.Task<ConferenceDetailsResponse> GetC
}
}

/// <summary>
/// Get conferences by hearing ref id
/// </summary>
/// <param name="request">Hearing ref IDs</param>
/// <returns>Full details including participants and statuses of a conference</returns>
/// <exception cref="VideoApiException">A server side error occurred.</exception>
public virtual System.Threading.Tasks.Task<System.Collections.Generic.ICollection<ConferenceForIndividualResponse>> GetConferencesForIndividualByHearingRefIdAsync(GetConferencesByHearingIdsRequest request)
{
return GetConferencesForIndividualByHearingRefIdAsync(request, System.Threading.CancellationToken.None);
}

/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <summary>
/// Get conferences by hearing ref id
/// </summary>
/// <param name="request">Hearing ref IDs</param>
/// <returns>Full details including participants and statuses of a conference</returns>
/// <exception cref="VideoApiException">A server side error occurred.</exception>
public virtual async System.Threading.Tasks.Task<System.Collections.Generic.ICollection<ConferenceForIndividualResponse>> GetConferencesForIndividualByHearingRefIdAsync(GetConferencesByHearingIdsRequest request, System.Threading.CancellationToken cancellationToken)
{
if (request == null)
throw new System.ArgumentNullException("request");

var urlBuilder_ = new System.Text.StringBuilder();
urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/conferences/hearings/individual");

var client_ = _httpClient;
var disposeClient_ = false;
try
{
using (var request_ = new System.Net.Http.HttpRequestMessage())
{
var json_ = Newtonsoft.Json.JsonConvert.SerializeObject(request, _settings.Value);
var content_ = new System.Net.Http.StringContent(json_);
content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
request_.Content = content_;
request_.Method = new System.Net.Http.HttpMethod("POST");
request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));

PrepareRequest(client_, request_, urlBuilder_);

var url_ = urlBuilder_.ToString();
request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);

PrepareRequest(client_, request_, url_);

var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
var disposeResponse_ = true;
try
{
var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.Content.Headers != null)
{
foreach (var item_ in response_.Content.Headers)
headers_[item_.Key] = item_.Value;
}

ProcessResponse(client_, response_);

var status_ = (int)response_.StatusCode;
if (status_ == 500)
{
var objectResponse_ = await ReadObjectResponseAsync<string>(response_, headers_, cancellationToken).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new VideoApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
}
throw new VideoApiException<string>("A server side error occurred.", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
}
else
if (status_ == 200)
{
var objectResponse_ = await ReadObjectResponseAsync<System.Collections.Generic.ICollection<ConferenceForIndividualResponse>>(response_, headers_, cancellationToken).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new VideoApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
}
return objectResponse_.Object;
}
else
if (status_ == 404)
{
var objectResponse_ = await ReadObjectResponseAsync<ProblemDetails>(response_, headers_, cancellationToken).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new VideoApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
}
throw new VideoApiException<ProblemDetails>("A server side error occurred.", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
}
else
if (status_ == 400)
{
var objectResponse_ = await ReadObjectResponseAsync<ValidationProblemDetails>(response_, headers_, cancellationToken).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new VideoApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
}
throw new VideoApiException<ValidationProblemDetails>("A server side error occurred.", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
}
else
{
var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new VideoApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (disposeResponse_)
response_.Dispose();
}
}
}
finally
{
if (disposeClient_)
client_.Dispose();
}
}

/// <summary>
/// Get list of expired conferences
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using AcceptanceTests.Common.Api.Helpers;
using FluentAssertions;
using NUnit.Framework;
using Testing.Common.Helper;
using VideoApi.Contract.Requests;
using VideoApi.Contract.Responses;
using VideoApi.IntegrationTests.Api.Setup;
using VideoApi.IntegrationTests.Helper;
using Task = System.Threading.Tasks.Task;

namespace VideoApi.IntegrationTests.Api.Conferences;

public class GetConferencesForIndividualByHearingRefIdTests : ApiTest
{
[Test]
public async Task should_get_conferences_for_individual_by_HearingRefId()
{
//arrange
var conference = await TestDataManager.SeedConference();
using var client = Application.CreateClient();
var payload = RequestHelper.Serialise(new GetConferencesByHearingIdsRequest { HearingRefIds = new[] { conference.HearingRefId } });


//act
var result =
await client.PostAsync(ApiUriFactory.ConferenceEndpoints.GetConferencesForIndividualByHearingRefId(),
new StringContent(payload, Encoding.UTF8,"application/json"));


// assert
result.IsSuccessStatusCode.Should().BeTrue();
var conferenceResponse = await ApiClientResponse.GetResponses<List<ConferenceForIndividualResponse>>(result.Content);
var resultConference = conferenceResponse.FirstOrDefault();
resultConference.Should().NotBeNull();
resultConference!.Id.Should().Be(conference.Id);
resultConference!.HearingId.Should().Be(conference.HearingRefId);
}

[Test]
public async Task should_return_not_found()
{
//arrange
using var client = Application.CreateClient();
var payload = RequestHelper.Serialise(new GetConferencesByHearingIdsRequest { HearingRefIds = new[] { Guid.NewGuid() }});


//act
var result =
await client.PostAsync(ApiUriFactory.ConferenceEndpoints.GetConferencesForIndividualByHearingRefId(),
new StringContent(payload, Encoding.UTF8,"application/json"));


// assert
result.IsSuccessStatusCode.Should().BeFalse();
result.StatusCode.Should().Be(HttpStatusCode.NotFound);
}
}


25 changes: 23 additions & 2 deletions VideoApi/VideoApi/Controllers/ConferenceController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ public async Task<IActionResult> GetConferencesTodayForHostAsync([FromQuery] str
[OpenApiOperation("GetConferencesTodayForIndividualByUsername")]
[ProducesResponseType(typeof(List<ConferenceForIndividualResponse>), (int) HttpStatusCode.OK)]
[ProducesResponseType(typeof(ValidationProblemDetails),(int)HttpStatusCode.BadRequest)]
[Obsolete("Use bookingApi GetConfirmedHearingsByUsernameForTodayAsync then hearings/individual instead", false)]
public async Task<IActionResult> GetConferencesTodayForIndividualByUsernameAsync([FromQuery] string username)
{
_logger.LogDebug("GetConferencesTodayForIndividualByUsername {Username}", username);
Expand Down Expand Up @@ -428,6 +429,27 @@ public async Task<IActionResult> GetConferencesForHostByHearingRefIdAsync(GetCon
return Ok(conferences.Select(ConferenceForHostResponseMapper.MapConferenceSummaryToModel).ToList());
}

/// <summary>
/// Get conferences by hearing ref id
/// </summary>
/// <param name="request">Hearing ref IDs</param>
/// <returns>Full details including participants and statuses of a conference</returns>
[HttpPost("hearings/individual")]
[OpenApiOperation("GetConferencesForIndividualByHearingRefId")]
[ProducesResponseType(typeof(List<ConferenceForIndividualResponse>), (int) HttpStatusCode.OK)]
[ProducesResponseType((int) HttpStatusCode.NotFound)]
[ProducesResponseType(typeof(ValidationProblemDetails),(int)HttpStatusCode.BadRequest)]
public async Task<IActionResult> GetConferencesForIndividualByHearingRefIdAsync(GetConferencesByHearingIdsRequest request)
{
var query = new GetNonClosedConferenceByHearingRefIdQuery(request.HearingRefIds, true);
var conferences = await _queryHandler.Handle<GetNonClosedConferenceByHearingRefIdQuery, List<Conference>>(query);

if (!conferences.Any())
return NotFound();

return Ok(conferences.Select(ConferenceForIndividualResponseMapper.MapConferenceSummaryToModel).ToList());
}

/// <summary>
/// Get list of expired conferences
/// </summary>
Expand Down Expand Up @@ -605,8 +627,7 @@ public async Task<IActionResult> RemoveHeartbeatsForConferencesAsync()
[HttpPatch("anonymise-conference-with-hearing-ids")]
[OpenApiOperation("AnonymiseConferenceWithHearingIds")]
[ProducesResponseType((int) HttpStatusCode.OK)]
public async Task<IActionResult> AnonymiseConferenceWithHearingIds(
AnonymiseConferenceWithHearingIdsRequest request)
public async Task<IActionResult> AnonymiseConferenceWithHearingIds(AnonymiseConferenceWithHearingIdsRequest request)
{
await _commandHandler.Handle(new AnonymiseConferenceWithHearingIdsCommand
{ HearingIds = request.HearingIds });
Expand Down
Loading